From e8cdeaba6be5677e1a1468f821c7dd876ea0555f Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:36:38 +0200 Subject: [PATCH] ESP32 LVGL library from v9.1.0 to v9.2.0 (#22031) --- CHANGELOG.md | 1 + .../LVGL_assets/src/lv_theme_haspmota.c | 5 +- .../generate/LVGL_API_Reference.md | 40 +- .../generate/be_lv_c_mapping.h | 32 +- .../generate/be_lvgl_module.c | 41 + .../lv_binding_berry/mapping/lv_enum.h | 42 +- .../lv_binding_berry/mapping/lv_funcs.h | 502 +- .../src/be_lvgl_ctypes_definitions.c | 56 +- .../src/embedded/lvgl_ctypes.py | 131 +- .../lv_binding_berry/src/lv_berry.c | 12 +- .../lv_binding_berry/src/lv_berry.h | 7 - .../lv_binding_berry/tools/convert.py | 11 +- .../lv_binding_berry/tools/preprocessor.py | 24 +- .../lv_haspmota/src/embedded/lv_haspmota.be | 6 +- .../src/solidify/solidified_lv_haspmota.h | 6 +- lib/libesp32_lvgl/lvgl/README.md | 20 +- lib/libesp32_lvgl/lvgl/README_Tasmota.md | 28 - lib/libesp32_lvgl/lvgl/library.json | 2 +- lib/libesp32_lvgl/lvgl/library.properties | 2 +- lib/libesp32_lvgl/lvgl/lv_conf_template.h | 195 +- lib/libesp32_lvgl/lvgl/lv_version.h | 14 + lib/libesp32_lvgl/lvgl/lvgl.h | 14 +- lib/libesp32_lvgl/lvgl/src/core/lv_global.h | 70 +- lib/libesp32_lvgl/lvgl/src/core/lv_group.c | 90 +- lib/libesp32_lvgl/lvgl/src/core/lv_group.h | 56 +- .../lvgl/src/core/lv_group_private.h | 75 + lib/libesp32_lvgl/lvgl/src/core/lv_obj.c | 208 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj.h | 158 +- .../lvgl/src/core/lv_obj_class.c | 18 +- .../lvgl/src/core/lv_obj_class.h | 34 - .../lvgl/src/core/lv_obj_class_private.h | 78 + lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c | 24 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h | 27 +- .../lvgl/src/core/lv_obj_draw_private.h | 48 + .../lvgl/src/core/lv_obj_event.c | 21 +- .../lvgl/src/core/lv_obj_event.h | 25 +- .../lvgl/src/core/lv_obj_event_private.h | 62 + .../lvgl/src/core/lv_obj_id_builtin.c | 20 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c | 68 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h | 13 +- .../lvgl/src/core/lv_obj_private.h | 88 + .../lvgl/src/core/lv_obj_property.c | 183 +- .../lvgl/src/core/lv_obj_property.h | 139 +- .../lvgl/src/core/lv_obj_scroll.c | 40 +- .../lvgl/src/core/lv_obj_scroll.h | 32 +- .../lvgl/src/core/lv_obj_scroll_private.h | 50 + .../lvgl/src/core/lv_obj_style.c | 135 +- .../lvgl/src/core/lv_obj_style.h | 132 +- .../lvgl/src/core/lv_obj_style_gen.c | 2 +- .../lvgl/src/core/lv_obj_style_gen.h | 271 +- .../lvgl/src/core/lv_obj_style_private.h | 95 + lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c | 45 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h | 6 +- lib/libesp32_lvgl/lvgl/src/core/lv_refr.c | 303 +- lib/libesp32_lvgl/lvgl/src/core/lv_refr.h | 38 +- .../lvgl/src/core/lv_refr_private.h | 75 + .../lvgl/src/display/lv_display.c | 120 +- .../lvgl/src/display/lv_display.h | 49 +- .../lvgl/src/display/lv_display_private.h | 49 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c | 83 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h | 180 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c | 2 + lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c | 258 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h | 204 +- .../lvgl/src/draw/lv_draw_buf_private.h | 53 + .../lvgl/src/draw/lv_draw_image.c | 59 +- .../lvgl/src/draw/lv_draw_image.h | 70 +- .../lvgl/src/draw/lv_draw_image_private.h | 85 + .../lvgl/src/draw/lv_draw_label.c | 53 +- .../lvgl/src/draw/lv_draw_label.h | 29 +- .../lvgl/src/draw/lv_draw_label_private.h | 68 + .../lvgl/src/draw/lv_draw_line.c | 7 +- .../lvgl/src/draw/lv_draw_line.h | 2 +- .../lvgl/src/draw/lv_draw_mask.c | 5 +- .../lvgl/src/draw/lv_draw_mask.h | 19 +- .../lvgl/src/draw/lv_draw_mask_private.h | 51 + .../lvgl/src/draw/lv_draw_private.h | 196 + .../lvgl/src/draw/lv_draw_rect.c | 9 +- .../lvgl/src/draw/lv_draw_rect_private.h | 39 + .../lvgl/src/draw/lv_draw_triangle.c | 7 +- .../lvgl/src/draw/lv_draw_triangle.h | 4 +- .../lvgl/src/draw/lv_draw_triangle_private.h | 43 + .../lvgl/src/draw/lv_draw_vector.c | 243 +- .../lvgl/src/draw/lv_draw_vector.h | 236 +- .../lvgl/src/draw/lv_draw_vector_private.h | 109 + .../lvgl/src/draw/lv_image_decoder.c | 239 +- .../lvgl/src/draw/lv_image_decoder.h | 169 +- .../lvgl/src/draw/lv_image_decoder_private.h | 142 + .../lvgl/src/draw/lv_image_dsc.h | 40 +- .../lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c | 5 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp.c | 23 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c | 2 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c | 6 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c | 10 +- .../lvgl/src/draw/nxp/pxp/lv_pxp_osa.c | 71 +- .../src/draw/nxp/vglite/lv_draw_buf_vglite.c | 49 +- .../lvgl/src/draw/nxp/vglite/lv_draw_vglite.c | 147 +- .../lvgl/src/draw/nxp/vglite/lv_draw_vglite.h | 11 +- .../draw/nxp/vglite/lv_draw_vglite_border.c | 55 +- .../src/draw/nxp/vglite/lv_draw_vglite_fill.c | 2 +- .../src/draw/nxp/vglite/lv_draw_vglite_img.c | 16 +- .../draw/nxp/vglite/lv_draw_vglite_label.c | 32 +- .../draw/nxp/vglite/lv_draw_vglite_layer.c | 34 +- .../src/draw/nxp/vglite/lv_draw_vglite_line.c | 2 +- .../draw/nxp/vglite/lv_draw_vglite_triangle.c | 7 +- .../src/draw/nxp/vglite/lv_vglite_utils.c | 29 +- .../src/draw/nxp/vglite/lv_vglite_utils.h | 16 +- .../src/draw/renesas/dave2d/lv_draw_dave2d.c | 119 +- .../src/draw/renesas/dave2d/lv_draw_dave2d.h | 5 + .../draw/renesas/dave2d/lv_draw_dave2d_arc.c | 20 +- .../renesas/dave2d/lv_draw_dave2d_border.c | 46 +- .../draw/renesas/dave2d/lv_draw_dave2d_fill.c | 56 +- .../renesas/dave2d/lv_draw_dave2d_image.c | 14 +- .../renesas/dave2d/lv_draw_dave2d_label.c | 10 +- .../draw/renesas/dave2d/lv_draw_dave2d_line.c | 14 +- .../dave2d/lv_draw_dave2d_mask_rectangle.c | 10 +- .../renesas/dave2d/lv_draw_dave2d_triangle.c | 15 +- .../renesas/dave2d/lv_draw_dave2d_utils.c | 4 +- .../lvgl/src/draw/sdl/lv_draw_sdl.c | 245 +- .../lvgl/src/draw/sdl/lv_draw_sdl.h | 14 +- .../lvgl/src/draw/sw/arm2d/lv_draw_sw_arm2d.h | 29 +- .../src/draw/sw/blend/arm2d/lv_blend_arm2d.h | 635 +- .../draw/sw/blend/helium/lv_blend_helium.S | 660 +- .../draw/sw/blend/helium/lv_blend_helium.h | 240 +- .../lvgl/src/draw/sw/blend/lv_draw_sw_blend.c | 100 +- .../lvgl/src/draw/sw/blend/lv_draw_sw_blend.h | 41 - .../draw/sw/blend/lv_draw_sw_blend_private.h | 92 + .../draw/sw/blend/lv_draw_sw_blend_to_al88.c | 1036 + .../draw/sw/blend/lv_draw_sw_blend_to_al88.h | 45 + .../sw/blend/lv_draw_sw_blend_to_argb8888.c | 430 +- .../sw/blend/lv_draw_sw_blend_to_argb8888.h | 12 +- .../draw/sw/blend/lv_draw_sw_blend_to_i1.c | 1117 + .../draw/sw/blend/lv_draw_sw_blend_to_i1.h | 45 + .../draw/sw/blend/lv_draw_sw_blend_to_l8.c | 897 + .../draw/sw/blend/lv_draw_sw_blend_to_l8.h | 45 + .../sw/blend/lv_draw_sw_blend_to_rgb565.c | 504 +- .../sw/blend/lv_draw_sw_blend_to_rgb565.h | 12 +- .../sw/blend/lv_draw_sw_blend_to_rgb888.c | 396 +- .../sw/blend/lv_draw_sw_blend_to_rgb888.h | 12 +- .../src/draw/sw/blend/neon/lv_blend_neon.S | 17 +- .../src/draw/sw/blend/neon/lv_blend_neon.h | 1634 +- .../lvgl/src/draw/sw/lv_draw_sw.c | 397 +- .../lvgl/src/draw/sw/lv_draw_sw.h | 62 +- .../lvgl/src/draw/sw/lv_draw_sw_arc.c | 59 +- .../lvgl/src/draw/sw/lv_draw_sw_border.c | 8 +- .../lvgl/src/draw/sw/lv_draw_sw_box_shadow.c | 63 +- .../lvgl/src/draw/sw/lv_draw_sw_fill.c | 204 +- .../lvgl/src/draw/sw/lv_draw_sw_gradient.c | 534 +- .../lvgl/src/draw/sw/lv_draw_sw_gradient.h | 150 +- .../src/draw/sw/lv_draw_sw_gradient_private.h | 50 + .../lvgl/src/draw/sw/lv_draw_sw_img.c | 96 +- .../lvgl/src/draw/sw/lv_draw_sw_letter.c | 4 +- .../lvgl/src/draw/sw/lv_draw_sw_line.c | 19 +- .../lvgl/src/draw/sw/lv_draw_sw_mask.c | 21 +- .../lvgl/src/draw/sw/lv_draw_sw_mask.h | 150 +- .../src/draw/sw/lv_draw_sw_mask_private.h | 153 + .../lvgl/src/draw/sw/lv_draw_sw_mask_rect.c | 8 +- .../lvgl/src/draw/sw/lv_draw_sw_private.h | 68 + .../lvgl/src/draw/sw/lv_draw_sw_transform.c | 236 +- .../lvgl/src/draw/sw/lv_draw_sw_triangle.c | 11 +- .../lvgl/src/draw/sw/lv_draw_sw_vector.c | 96 +- .../src/draw/vg_lite/lv_draw_buf_vg_lite.c | 1 + .../lvgl/src/draw/vg_lite/lv_draw_vg_lite.c | 44 +- .../lvgl/src/draw/vg_lite/lv_draw_vg_lite.h | 14 +- .../src/draw/vg_lite/lv_draw_vg_lite_arc.c | 12 +- .../src/draw/vg_lite/lv_draw_vg_lite_border.c | 15 +- .../draw/vg_lite/lv_draw_vg_lite_box_shadow.c | 6 +- .../src/draw/vg_lite/lv_draw_vg_lite_fill.c | 19 +- .../src/draw/vg_lite/lv_draw_vg_lite_img.c | 54 +- .../src/draw/vg_lite/lv_draw_vg_lite_label.c | 58 +- .../src/draw/vg_lite/lv_draw_vg_lite_layer.c | 2 +- .../src/draw/vg_lite/lv_draw_vg_lite_line.c | 8 +- .../draw/vg_lite/lv_draw_vg_lite_mask_rect.c | 53 +- .../draw/vg_lite/lv_draw_vg_lite_triangle.c | 15 +- .../src/draw/vg_lite/lv_draw_vg_lite_type.h | 19 +- .../src/draw/vg_lite/lv_draw_vg_lite_vector.c | 235 +- .../src/draw/vg_lite/lv_vg_lite_decoder.c | 113 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_grad.c | 632 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_grad.h | 26 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_math.c | 4 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_math.h | 2 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_path.c | 91 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_path.h | 8 +- .../src/draw/vg_lite/lv_vg_lite_pending.c | 2 +- .../src/draw/vg_lite/lv_vg_lite_pending.h | 2 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_stroke.c | 310 + .../lvgl/src/draw/vg_lite/lv_vg_lite_stroke.h | 84 + .../lvgl/src/draw/vg_lite/lv_vg_lite_utils.c | 207 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_utils.h | 21 +- .../src/drivers/display/drm/lv_linux_drm.c | 19 +- .../src/drivers/display/drm/lv_linux_drm.h | 2 +- .../src/drivers/display/fb/lv_linux_fbdev.c | 91 +- .../src/drivers/display/fb/lv_linux_fbdev.h | 8 +- .../src/drivers/display/ili9341/lv_ili9341.h | 4 +- .../drivers/display/lcd/lv_lcd_generic_mipi.c | 4 +- .../drivers/display/lcd/lv_lcd_generic_mipi.h | 4 +- .../display/renesas_glcdc/lv_renesas_glcdc.c | 360 + .../display/renesas_glcdc/lv_renesas_glcdc.h | 57 + .../src/drivers/display/st7735/lv_st7735.h | 4 +- .../src/drivers/display/st7789/lv_st7789.h | 4 +- .../src/drivers/display/st7796/lv_st7796.h | 4 +- .../drivers/display/tft_espi/lv_tft_espi.cpp | 31 +- .../drivers/display/tft_espi/lv_tft_espi.h | 2 +- .../lvgl/src/drivers/evdev/lv_evdev.c | 21 + .../lvgl/src/drivers/glfw/lv_glfw_window.c | 391 + .../lvgl/src/drivers/glfw/lv_glfw_window.h | 108 + .../src/drivers/glfw/lv_glfw_window_private.h | 70 + .../lvgl/src/drivers/glfw/lv_opengles_debug.c | 58 + .../lvgl/src/drivers/glfw/lv_opengles_debug.h | 38 + .../src/drivers/glfw/lv_opengles_driver.c | 409 + .../src/drivers/glfw/lv_opengles_driver.h | 82 + .../src/drivers/glfw/lv_opengles_texture.c | 151 + .../src/drivers/glfw/lv_opengles_texture.h | 66 + .../lvgl/src/drivers/libinput/lv_libinput.c | 6 +- .../lvgl/src/drivers/libinput/lv_libinput.h | 37 +- .../drivers/libinput/lv_libinput_private.h | 79 + .../lvgl/src/drivers/libinput/lv_xkb.c | 2 +- .../lvgl/src/drivers/libinput/lv_xkb.h | 9 - .../src/drivers/libinput/lv_xkb_private.h | 53 + .../lvgl/src/drivers/lv_drivers.h | 8 + .../lvgl/src/drivers/nuttx/lv_nuttx_cache.c | 41 +- .../lvgl/src/drivers/nuttx/lv_nuttx_cache.h | 2 + .../lvgl/src/drivers/nuttx/lv_nuttx_entry.c | 105 +- .../lvgl/src/drivers/nuttx/lv_nuttx_entry.h | 25 +- .../lvgl/src/drivers/nuttx/lv_nuttx_fbdev.c | 129 +- .../lvgl/src/drivers/nuttx/lv_nuttx_fbdev.h | 2 +- .../src/drivers/nuttx/lv_nuttx_image_cache.c | 69 +- .../src/drivers/nuttx/lv_nuttx_image_cache.h | 6 +- .../lvgl/src/drivers/nuttx/lv_nuttx_lcd.c | 4 +- .../lvgl/src/drivers/nuttx/lv_nuttx_libuv.c | 6 +- .../src/drivers/nuttx/lv_nuttx_touchscreen.c | 77 +- .../lvgl/src/drivers/qnx/lv_qnx.c | 542 + .../lvgl/src/drivers/qnx/lv_qnx.h | 86 + .../lvgl/src/drivers/sdl/lv_sdl_keyboard.c | 16 +- .../lvgl/src/drivers/sdl/lv_sdl_mouse.c | 13 +- .../lvgl/src/drivers/sdl/lv_sdl_mouse.h | 2 +- .../lvgl/src/drivers/sdl/lv_sdl_mousewheel.c | 14 +- .../lvgl/src/drivers/sdl/lv_sdl_private.h | 49 + .../lvgl/src/drivers/sdl/lv_sdl_window.c | 208 +- .../lvgl/src/drivers/sdl/lv_sdl_window.h | 10 +- .../lvgl/src/drivers/wayland/lv_wayland.c | 2860 +++ .../lvgl/src/drivers/wayland/lv_wayland.h | 142 + .../lvgl/src/drivers/wayland/lv_wayland_smm.c | 675 + .../lvgl/src/drivers/wayland/lv_wayland_smm.h | 105 + .../src/drivers/windows/lv_windows_context.c | 89 +- .../src/drivers/windows/lv_windows_context.h | 27 +- .../src/drivers/windows/lv_windows_input.c | 41 +- .../windows/lv_windows_input_private.h | 65 + .../lvgl/src/drivers/x11/lv_x11.h | 8 +- .../lvgl/src/drivers/x11/lv_x11_display.c | 20 +- .../lvgl/src/drivers/x11/lv_x11_input.c | 9 +- .../lvgl/src/font/lv_binfont_loader.c | 21 +- .../lvgl/src/font/lv_binfont_loader.h | 12 +- lib/libesp32_lvgl/lvgl/src/font/lv_font.c | 28 +- lib/libesp32_lvgl/lvgl/src/font/lv_font.h | 80 +- .../lvgl/src/font/lv_font_fmt_txt.c | 49 +- .../lvgl/src/font/lv_font_fmt_txt.h | 65 +- .../lvgl/src/font/lv_font_fmt_txt_private.h | 56 + .../lvgl/src/font/lv_font_simsun_14_cjk.c | 20783 ++++++++++++++++ .../lvgl/src/font/lv_font_simsun_16_cjk.c | 2768 +- .../lvgl/src/font/lv_symbol_def.h | 133 +- lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c | 167 +- lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h | 39 +- .../lvgl/src/indev/lv_indev_private.h | 15 +- .../lvgl/src/indev/lv_indev_scroll.c | 230 +- .../lvgl/src/indev/lv_indev_scroll.h | 4 +- .../lvgl/src/layouts/flex/lv_flex.c | 12 +- .../lvgl/src/layouts/flex/lv_flex.h | 23 +- .../lvgl/src/layouts/grid/lv_grid.c | 76 +- .../lvgl/src/layouts/grid/lv_grid.h | 5 +- .../lvgl/src/layouts/lv_layout.c | 8 +- .../lvgl/src/layouts/lv_layout.h | 28 +- .../lvgl/src/layouts/lv_layout_private.h | 58 + .../lvgl/src/libs/barcode/lv_barcode.c | 117 +- .../lvgl/src/libs/barcode/lv_barcode.h | 18 +- .../src/libs/barcode/lv_barcode_private.h | 55 + .../src/libs/bin_decoder/lv_bin_decoder.c | 162 +- .../src/libs/bin_decoder/lv_bin_decoder.h | 4 +- lib/libesp32_lvgl/lvgl/src/libs/bmp/lv_bmp.c | 40 +- .../lvgl/src/libs/ffmpeg/lv_ffmpeg.c | 18 +- .../lvgl/src/libs/ffmpeg/lv_ffmpeg.h | 12 +- .../lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h | 51 + .../lvgl/src/libs/freetype/lv_freetype.c | 17 +- .../lvgl/src/libs/freetype/lv_freetype.h | 26 +- .../src/libs/freetype/lv_freetype_glyph.c | 13 +- .../src/libs/freetype/lv_freetype_image.c | 32 +- .../src/libs/freetype/lv_freetype_outline.c | 34 +- .../src/libs/freetype/lv_freetype_private.h | 31 +- .../libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp | 201 + .../lvgl/src/libs/fsdrv/lv_fs_arduino_sd.cpp | 192 + .../lvgl/src/libs/fsdrv/lv_fs_fatfs.c | 21 +- .../lvgl/src/libs/fsdrv/lv_fs_littlefs.c | 150 +- .../lvgl/src/libs/fsdrv/lv_fs_memfs.c | 13 + .../lvgl/src/libs/fsdrv/lv_fs_posix.c | 101 +- .../lvgl/src/libs/fsdrv/lv_fs_stdio.c | 25 +- .../lvgl/src/libs/fsdrv/lv_fs_win32.c | 17 +- .../lvgl/src/libs/fsdrv/lv_fsdrv.h | 10 + lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c | 6 +- lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.h | 2 +- lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c | 29 +- lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h | 16 +- .../lvgl/src/libs/gif/lv_gif_private.h | 57 + .../src/libs/libjpeg_turbo/lv_libjpeg_turbo.c | 59 +- .../lvgl/src/libs/libpng/lv_libpng.c | 218 +- .../lvgl/src/libs/lodepng/lodepng.c | 1060 +- .../lvgl/src/libs/lodepng/lodepng.h | 205 +- .../lvgl/src/libs/lodepng/lv_lodepng.c | 107 +- lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h | 4 +- .../lvgl/src/libs/qrcode/lv_qrcode.c | 31 +- .../lvgl/src/libs/qrcode/lv_qrcode.h | 14 +- .../lvgl/src/libs/qrcode/lv_qrcode_private.h | 52 + .../lvgl/src/libs/qrcode/qrcodegen.c | 7 +- .../lvgl/src/libs/qrcode/qrcodegen.h | 5 + .../lvgl/src/libs/rlottie/lv_rlottie.c | 17 +- .../lvgl/src/libs/rlottie/lv_rlottie.h | 17 - .../src/libs/rlottie/lv_rlottie_private.h | 61 + .../lvgl/src/libs/thorvg/config.h | 10 +- .../src/libs/thorvg/rapidjson/allocators.h | 693 + .../thorvg/rapidjson/cursorstreamwrapper.h | 78 + .../lvgl/src/libs/thorvg/rapidjson/document.h | 3043 +++ .../src/libs/thorvg/rapidjson/encodedstream.h | 299 + .../src/libs/thorvg/rapidjson/encodings.h | 716 + .../lvgl/src/libs/thorvg/rapidjson/error/en.h | 176 + .../src/libs/thorvg/rapidjson/error/error.h | 285 + .../libs/thorvg/rapidjson/filereadstream.h | 99 + .../libs/thorvg/rapidjson/filewritestream.h | 104 + .../lvgl/src/libs/thorvg/rapidjson/fwd.h | 151 + .../thorvg/rapidjson/internal/biginteger.h | 297 + .../libs/thorvg/rapidjson/internal/clzll.h | 71 + .../libs/thorvg/rapidjson/internal/diyfp.h | 261 + .../src/libs/thorvg/rapidjson/internal/dtoa.h | 249 + .../libs/thorvg/rapidjson/internal/ieee754.h | 78 + .../src/libs/thorvg/rapidjson/internal/itoa.h | 308 + .../src/libs/thorvg/rapidjson/internal/meta.h | 186 + .../libs/thorvg/rapidjson/internal/pow10.h | 55 + .../libs/thorvg/rapidjson/internal/regex.h | 739 + .../libs/thorvg/rapidjson/internal/stack.h | 232 + .../libs/thorvg/rapidjson/internal/strfunc.h | 83 + .../libs/thorvg/rapidjson/internal/strtod.h | 293 + .../src/libs/thorvg/rapidjson/internal/swap.h | 46 + .../libs/thorvg/rapidjson/istreamwrapper.h | 128 + .../src/libs/thorvg/rapidjson/memorybuffer.h | 70 + .../src/libs/thorvg/rapidjson/memorystream.h | 71 + .../thorvg/rapidjson/msinttypes/inttypes.h | 316 + .../libs/thorvg/rapidjson/msinttypes/stdint.h | 300 + .../libs/thorvg/rapidjson/ostreamwrapper.h | 81 + .../lvgl/src/libs/thorvg/rapidjson/pointer.h | 1470 ++ .../src/libs/thorvg/rapidjson/prettywriter.h | 277 + .../src/libs/thorvg/rapidjson/rapidjson.h | 741 + .../lvgl/src/libs/thorvg/rapidjson/reader.h | 2246 ++ .../lvgl/src/libs/thorvg/rapidjson/schema.h | 3262 +++ .../lvgl/src/libs/thorvg/rapidjson/stream.h | 223 + .../src/libs/thorvg/rapidjson/stringbuffer.h | 121 + .../lvgl/src/libs/thorvg/rapidjson/uri.h | 481 + .../lvgl/src/libs/thorvg/rapidjson/writer.h | 710 + .../lvgl/src/libs/thorvg/thorvg.h | 467 +- .../lvgl/src/libs/thorvg/thorvg_capi.h | 224 +- .../lvgl/src/libs/thorvg/thorvg_lottie.h | 100 + .../lvgl/src/libs/thorvg/tvgAccessor.cpp | 91 + .../lvgl/src/libs/thorvg/tvgAnimation.cpp | 65 +- .../lvgl/src/libs/thorvg/tvgAnimation.h | 54 + .../lvgl/src/libs/thorvg/tvgArray.h | 19 +- .../lvgl/src/libs/thorvg/tvgBinaryDesc.h | 106 + .../lvgl/src/libs/thorvg/tvgCanvas.cpp | 16 +- .../lvgl/src/libs/thorvg/tvgCanvas.h | 105 +- .../lvgl/src/libs/thorvg/tvgCapi.cpp | 101 +- .../lvgl/src/libs/thorvg/tvgCommon.h | 5 +- .../lvgl/src/libs/thorvg/tvgCompressor.cpp | 6 +- .../lvgl/src/libs/thorvg/tvgCompressor.h | 2 +- .../lvgl/src/libs/thorvg/tvgFill.cpp | 2 +- .../lvgl/src/libs/thorvg/tvgFill.h | 2 +- .../lvgl/src/libs/thorvg/tvgFrameModule.h | 27 +- .../lvgl/src/libs/thorvg/tvgGlCanvas.cpp | 96 + .../lvgl/src/libs/thorvg/tvgInitializer.cpp | 4 +- .../lvgl/src/libs/thorvg/tvgInlist.h | 117 + .../src/libs/thorvg/tvgIteratorAccessor.h | 2 +- .../thorvg/{tvgBezier.cpp => tvgLines.cpp} | 128 +- .../libs/thorvg/{tvgBezier.h => tvgLines.h} | 21 +- .../lvgl/src/libs/thorvg/tvgLoadModule.h | 85 +- .../lvgl/src/libs/thorvg/tvgLoader.cpp | 292 +- .../lvgl/src/libs/thorvg/tvgLoader.h | 11 +- .../lvgl/src/libs/thorvg/tvgLock.h | 77 + .../src/libs/thorvg/tvgLottieAnimation.cpp | 98 + .../lvgl/src/libs/thorvg/tvgLottieBuilder.cpp | 1378 + .../lvgl/src/libs/thorvg/tvgLottieBuilder.h | 54 + .../src/libs/thorvg/tvgLottieExpressions.cpp | 1298 + .../src/libs/thorvg/tvgLottieExpressions.h | 171 + .../src/libs/thorvg/tvgLottieInterpolator.cpp | 146 + .../src/libs/thorvg/tvgLottieInterpolator.h | 51 + .../lvgl/src/libs/thorvg/tvgLottieLoader.cpp | 407 + .../lvgl/src/libs/thorvg/tvgLottieLoader.h | 86 + .../lvgl/src/libs/thorvg/tvgLottieModel.cpp | 424 + .../lvgl/src/libs/thorvg/tvgLottieModel.h | 685 + .../lvgl/src/libs/thorvg/tvgLottieParser.cpp | 1405 ++ .../lvgl/src/libs/thorvg/tvgLottieParser.h | 124 + .../libs/thorvg/tvgLottieParserHandler.cpp | 241 + .../src/libs/thorvg/tvgLottieParserHandler.h | 206 + .../lvgl/src/libs/thorvg/tvgLottieProperty.h | 935 + .../lvgl/src/libs/thorvg/tvgMath.cpp | 8 +- .../lvgl/src/libs/thorvg/tvgMath.h | 48 +- .../lvgl/src/libs/thorvg/tvgPaint.cpp | 124 +- .../lvgl/src/libs/thorvg/tvgPaint.h | 110 +- .../lvgl/src/libs/thorvg/tvgPicture.cpp | 107 +- .../lvgl/src/libs/thorvg/tvgPicture.h | 141 +- .../lvgl/src/libs/thorvg/tvgRawLoader.cpp | 57 +- .../lvgl/src/libs/thorvg/tvgRawLoader.h | 11 +- .../lvgl/src/libs/thorvg/tvgRender.cpp | 53 +- .../lvgl/src/libs/thorvg/tvgRender.h | 100 +- .../lvgl/src/libs/thorvg/tvgSaveModule.h | 3 +- .../lvgl/src/libs/thorvg/tvgSaver.cpp | 74 +- .../lvgl/src/libs/thorvg/tvgScene.cpp | 3 +- .../lvgl/src/libs/thorvg/tvgScene.h | 68 +- .../lvgl/src/libs/thorvg/tvgShape.cpp | 39 +- .../lvgl/src/libs/thorvg/tvgShape.h | 75 +- .../lvgl/src/libs/thorvg/tvgStr.cpp | 7 +- .../lvgl/src/libs/thorvg/tvgStr.h | 2 +- .../lvgl/src/libs/thorvg/tvgSvgCssStyle.cpp | 18 +- .../lvgl/src/libs/thorvg/tvgSvgCssStyle.h | 2 +- .../lvgl/src/libs/thorvg/tvgSvgLoader.cpp | 366 +- .../lvgl/src/libs/thorvg/tvgSvgLoader.h | 11 +- .../lvgl/src/libs/thorvg/tvgSvgLoaderCommon.h | 9 +- .../lvgl/src/libs/thorvg/tvgSvgPath.cpp | 56 +- .../lvgl/src/libs/thorvg/tvgSvgPath.h | 4 +- .../src/libs/thorvg/tvgSvgSceneBuilder.cpp | 30 +- .../lvgl/src/libs/thorvg/tvgSvgSceneBuilder.h | 4 +- .../lvgl/src/libs/thorvg/tvgSvgUtil.cpp | 6 +- .../lvgl/src/libs/thorvg/tvgSvgUtil.h | 2 +- .../lvgl/src/libs/thorvg/tvgSwCanvas.cpp | 8 +- .../lvgl/src/libs/thorvg/tvgSwCommon.h | 17 +- .../lvgl/src/libs/thorvg/tvgSwFill.cpp | 15 +- .../lvgl/src/libs/thorvg/tvgSwImage.cpp | 2 +- .../lvgl/src/libs/thorvg/tvgSwMath.cpp | 14 +- .../lvgl/src/libs/thorvg/tvgSwMemPool.cpp | 3 +- .../lvgl/src/libs/thorvg/tvgSwRaster.cpp | 80 +- .../lvgl/src/libs/thorvg/tvgSwRasterAvx.h | 23 +- .../lvgl/src/libs/thorvg/tvgSwRasterC.h | 2 +- .../lvgl/src/libs/thorvg/tvgSwRasterNeon.h | 62 +- .../lvgl/src/libs/thorvg/tvgSwRasterTexmap.h | 31 +- .../lvgl/src/libs/thorvg/tvgSwRenderer.cpp | 77 +- .../lvgl/src/libs/thorvg/tvgSwRenderer.h | 5 +- .../lvgl/src/libs/thorvg/tvgSwRle.cpp | 24 +- .../lvgl/src/libs/thorvg/tvgSwShape.cpp | 183 +- .../lvgl/src/libs/thorvg/tvgSwStroke.cpp | 14 +- .../lvgl/src/libs/thorvg/tvgTaskScheduler.cpp | 173 +- .../lvgl/src/libs/thorvg/tvgTaskScheduler.h | 66 +- .../lvgl/src/libs/thorvg/tvgText.cpp | 115 + .../lvgl/src/libs/thorvg/tvgText.h | 189 + .../lvgl/src/libs/thorvg/tvgWgCanvas.cpp | 89 + .../lvgl/src/libs/thorvg/tvgXmlParser.cpp | 14 +- .../lvgl/src/libs/thorvg/tvgXmlParser.h | 8 +- .../lvgl/src/libs/tiny_ttf/lv_tiny_ttf.c | 334 +- .../lvgl/src/libs/tiny_ttf/lv_tiny_ttf.h | 58 +- .../lvgl/src/libs/tiny_ttf/stb_rect_pack.h | 2 +- .../src/libs/tiny_ttf/stb_truetype_htcw.h | 42 +- .../lvgl/src/libs/tjpgd/lv_tjpgd.c | 58 +- lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.c | 29 +- lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.h | 7 +- lib/libesp32_lvgl/lvgl/src/lv_api_map_v8.h | 52 +- lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_0.h | 14 + lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h | 98 + lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h | 766 +- lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h | 2 + lib/libesp32_lvgl/lvgl/src/lv_init.c | 99 +- lib/libesp32_lvgl/lvgl/src/lv_init.h | 2 +- lib/libesp32_lvgl/lvgl/src/lvgl.h | 2 +- lib/libesp32_lvgl/lvgl/src/lvgl_private.h | 87 + .../lvgl/src/misc/cache/lv_cache.c | 83 +- .../lvgl/src/misc/cache/lv_cache.h | 76 +- .../lvgl/src/misc/cache/lv_cache_entry.c | 2 +- .../lvgl/src/misc/cache/lv_cache_entry.h | 4 +- .../src/misc/cache/lv_cache_entry_private.h | 13 +- .../{_lv_cache_lru_rb.c => lv_cache_lru_rb.c} | 38 +- .../{_lv_cache_lru_rb.h => lv_cache_lru_rb.h} | 2 +- .../lvgl/src/misc/cache/lv_cache_private.h | 69 +- .../lvgl/src/misc/cache/lv_image_cache.c | 132 +- .../lvgl/src/misc/cache/lv_image_cache.h | 24 +- .../src/misc/cache/lv_image_header_cache.c | 133 + .../src/misc/cache/lv_image_header_cache.h | 72 + lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c | 212 +- lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h | 240 +- .../lvgl/src/misc/lv_anim_private.h | 56 + .../lvgl/src/misc/lv_anim_timeline.c | 115 +- .../lvgl/src/misc/lv_anim_timeline.h | 28 +- lib/libesp32_lvgl/lvgl/src/misc/lv_area.c | 134 +- lib/libesp32_lvgl/lvgl/src/misc/lv_area.h | 218 +- .../lvgl/src/misc/lv_area_private.h | 115 + lib/libesp32_lvgl/lvgl/src/misc/lv_array.c | 60 +- lib/libesp32_lvgl/lvgl/src/misc/lv_array.h | 54 +- lib/libesp32_lvgl/lvgl/src/misc/lv_async.c | 4 +- lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.c | 92 +- lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.h | 83 +- .../lvgl/src/misc/lv_bidi_private.h | 98 + lib/libesp32_lvgl/lvgl/src/misc/lv_color.c | 142 +- lib/libesp32_lvgl/lvgl/src/misc/lv_color.h | 198 +- lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c | 43 +- lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h | 52 +- .../lvgl/src/misc/lv_color_op_private.h | 39 + lib/libesp32_lvgl/lvgl/src/misc/lv_event.c | 10 +- lib/libesp32_lvgl/lvgl/src/misc/lv_event.h | 44 +- .../lvgl/src/misc/lv_event_private.h | 73 + lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c | 439 +- lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h | 61 +- .../lvgl/src/misc/lv_fs_private.h | 69 + lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c | 67 +- lib/libesp32_lvgl/lvgl/src/misc/lv_ll.h | 47 +- lib/libesp32_lvgl/lvgl/src/misc/lv_log.c | 11 +- lib/libesp32_lvgl/lvgl/src/misc/lv_log.h | 31 +- lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c | 8 +- lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h | 5 +- lib/libesp32_lvgl/lvgl/src/misc/lv_math.c | 103 +- lib/libesp32_lvgl/lvgl/src/misc/lv_math.h | 37 +- lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c | 225 + lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h | 129 + lib/libesp32_lvgl/lvgl/src/misc/lv_palette.c | 6 +- lib/libesp32_lvgl/lvgl/src/misc/lv_palette.h | 5 +- .../lvgl/src/misc/lv_profiler_builtin.c | 4 +- .../lvgl/src/misc/lv_profiler_builtin.h | 16 +- .../src/misc/lv_profiler_builtin_private.h | 56 + lib/libesp32_lvgl/lvgl/src/misc/lv_rb.c | 2 +- lib/libesp32_lvgl/lvgl/src/misc/lv_rb.h | 16 +- .../lvgl/src/misc/lv_rb_private.h | 54 + lib/libesp32_lvgl/lvgl/src/misc/lv_style.c | 44 +- lib/libesp32_lvgl/lvgl/src/misc/lv_style.h | 187 +- .../lvgl/src/misc/lv_style_gen.c | 222 +- .../lvgl/src/misc/lv_style_gen.h | 332 +- .../lvgl/src/misc/lv_style_private.h | 39 + lib/libesp32_lvgl/lvgl/src/misc/lv_text.c | 130 +- lib/libesp32_lvgl/lvgl/src/misc/lv_text.h | 266 +- lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c | 32 +- lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.h | 6 +- .../lvgl/src/misc/lv_text_private.h | 273 + lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c | 52 +- lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h | 66 +- .../lvgl/src/misc/lv_timer_private.h | 81 + lib/libesp32_lvgl/lvgl/src/misc/lv_types.h | 301 +- lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c | 7 +- lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h | 14 +- .../lvgl/src/osal/lv_cmsis_rtos2.c | 5 + lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c | 162 +- lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h | 33 +- lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c | 169 + lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.h | 51 + lib/libesp32_lvgl/lvgl/src/osal/lv_os.c | 71 + lib/libesp32_lvgl/lvgl/src/osal/lv_os.h | 33 +- lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c | 7 + .../lvgl/src/osal/lv_os_private.h | 47 + lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c | 20 +- lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c | 6 + lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c | 7 + .../others/file_explorer/lv_file_explorer.c | 7 +- .../others/file_explorer/lv_file_explorer.h | 24 - .../file_explorer/lv_file_explorer_private.h | 69 + .../lvgl/src/others/fragment/lv_fragment.c | 2 +- .../lvgl/src/others/fragment/lv_fragment.h | 44 +- .../src/others/fragment/lv_fragment_manager.c | 46 +- .../src/others/fragment/lv_fragment_private.h | 77 + .../lvgl/src/others/gridnav/lv_gridnav.c | 23 +- .../lvgl/src/others/gridnav/lv_gridnav.h | 58 +- .../lvgl/src/others/ime/lv_ime_pinyin.c | 37 +- .../lvgl/src/others/ime/lv_ime_pinyin.h | 23 - .../src/others/ime/lv_ime_pinyin_private.h | 68 + .../lvgl/src/others/imgfont/lv_imgfont.c | 12 +- .../lvgl/src/others/monkey/lv_monkey.c | 8 +- .../lvgl/src/others/monkey/lv_monkey.h | 8 +- .../src/others/monkey/lv_monkey_private.h | 43 + .../lvgl/src/others/observer/lv_observer.c | 126 +- .../lvgl/src/others/observer/lv_observer.h | 98 +- .../src/others/observer/lv_observer_private.h | 57 + .../lvgl/src/others/snapshot/lv_snapshot.c | 44 +- .../lvgl/src/others/snapshot/lv_snapshot.h | 29 +- .../lvgl/src/others/sysmon/lv_sysmon.c | 171 +- .../lvgl/src/others/sysmon/lv_sysmon.h | 78 +- .../src/others/sysmon/lv_sysmon_private.h | 91 + .../lvgl/src/others/vg_lite_tvg/vg_lite.h | 29 +- .../src/others/vg_lite_tvg/vg_lite_matrix.c | 2 +- .../src/others/vg_lite_tvg/vg_lite_tvg.cpp | 181 +- .../src/stdlib/builtin/lv_mem_core_builtin.c | 16 +- .../src/stdlib/builtin/lv_sprintf_builtin.c | 8 +- .../src/stdlib/builtin/lv_string_builtin.c | 54 +- .../lvgl/src/stdlib/builtin/lv_tlsf.c | 18 +- .../lvgl/src/stdlib/builtin/lv_tlsf.h | 13 +- .../lvgl/src/stdlib/builtin/lv_tlsf_private.h | 53 + .../lvgl/src/stdlib/clib/lv_string_clib.c | 35 +- lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c | 2 +- lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h | 18 +- .../lvgl/src/stdlib/lv_mem_private.h | 39 + .../lvgl/src/stdlib/lv_sprintf.h | 16 +- lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h | 52 +- .../micropython/lv_mem_core_micropython.c | 15 + .../src/stdlib/rtthread/lv_string_rtthread.c | 45 +- .../src/themes/default/lv_theme_default.c | 121 +- lib/libesp32_lvgl/lvgl/src/themes/lv_theme.c | 3 + lib/libesp32_lvgl/lvgl/src/themes/lv_theme.h | 13 - .../lvgl/src/themes/lv_theme_private.h | 53 + .../lvgl/src/themes/mono/lv_theme_mono.c | 15 +- .../lvgl/src/themes/mono/lv_theme_mono.h | 6 +- .../lvgl/src/themes/simple/lv_theme_simple.c | 15 +- lib/libesp32_lvgl/lvgl/src/tick/lv_tick.c | 4 +- lib/libesp32_lvgl/lvgl/src/tick/lv_tick.h | 22 +- .../lvgl/src/tick/lv_tick_private.h | 46 + .../lvgl/src/widgets/animimage/lv_animimage.c | 17 +- .../lvgl/src/widgets/animimage/lv_animimage.h | 29 +- .../widgets/animimage/lv_animimage_private.h | 55 + .../lvgl/src/widgets/arc/lv_arc.c | 104 +- .../lvgl/src/widgets/arc/lv_arc.h | 30 +- .../lvgl/src/widgets/arc/lv_arc_private.h | 64 + .../lvgl/src/widgets/bar/lv_bar.c | 56 +- .../lvgl/src/widgets/bar/lv_bar.h | 50 +- .../lvgl/src/widgets/bar/lv_bar_private.h | 66 + .../lvgl/src/widgets/button/lv_button.c | 3 +- .../lvgl/src/widgets/button/lv_button.h | 10 +- .../src/widgets/button/lv_button_private.h | 53 + .../widgets/buttonmatrix/lv_buttonmatrix.c | 21 +- .../widgets/buttonmatrix/lv_buttonmatrix.h | 32 +- .../buttonmatrix/lv_buttonmatrix_private.h | 57 + .../lvgl/src/widgets/calendar/lv_calendar.c | 102 +- .../lvgl/src/widgets/calendar/lv_calendar.h | 18 +- .../widgets/calendar/lv_calendar_chinese.c | 288 + .../widgets/calendar/lv_calendar_chinese.h | 59 + .../calendar/lv_calendar_chinese_private.h | 53 + .../calendar/lv_calendar_header_arrow.c | 1 + .../calendar/lv_calendar_header_dropdown.c | 5 +- .../widgets/calendar/lv_calendar_private.h | 70 + .../lvgl/src/widgets/canvas/lv_canvas.c | 102 +- .../lvgl/src/widgets/canvas/lv_canvas.h | 40 +- .../src/widgets/canvas/lv_canvas_private.h | 52 + .../lvgl/src/widgets/chart/lv_chart.c | 89 +- .../lvgl/src/widgets/chart/lv_chart.h | 80 +- .../lvgl/src/widgets/chart/lv_chart_private.h | 85 + .../lvgl/src/widgets/checkbox/lv_checkbox.c | 8 +- .../lvgl/src/widgets/checkbox/lv_checkbox.h | 12 +- .../widgets/checkbox/lv_checkbox_private.h | 55 + .../lvgl/src/widgets/dropdown/lv_dropdown.c | 90 +- .../lvgl/src/widgets/dropdown/lv_dropdown.h | 38 +- .../widgets/dropdown/lv_dropdown_private.h | 69 + .../lvgl/src/widgets/image/lv_image.c | 108 +- .../lvgl/src/widgets/image/lv_image.h | 109 +- .../lvgl/src/widgets/image/lv_image_private.h | 66 + .../src/widgets/imagebutton/lv_imagebutton.c | 9 +- .../src/widgets/imagebutton/lv_imagebutton.h | 15 +- .../imagebutton/lv_imagebutton_private.h | 58 + .../lvgl/src/widgets/keyboard/lv_keyboard.c | 60 +- .../lvgl/src/widgets/keyboard/lv_keyboard.h | 45 +- .../widgets/keyboard/lv_keyboard_private.h | 53 + .../lvgl/src/widgets/label/lv_label.c | 142 +- .../lvgl/src/widgets/label/lv_label.h | 57 +- .../lvgl/src/widgets/label/lv_label_private.h | 73 + .../lvgl/src/widgets/led/lv_led.c | 5 +- .../lvgl/src/widgets/led/lv_led.h | 7 - .../lvgl/src/widgets/led/lv_led_private.h | 52 + .../lvgl/src/widgets/line/lv_line.c | 95 +- .../lvgl/src/widgets/line/lv_line.h | 44 +- .../lvgl/src/widgets/line/lv_line_private.h | 57 + .../lvgl/src/widgets/list/lv_list.c | 1 + .../lvgl/src/widgets/list/lv_list.h | 3 +- .../lvgl/src/widgets/lottie/lv_lottie.c | 237 + .../lvgl/src/widgets/lottie/lv_lottie.h | 102 + .../src/widgets/lottie/lv_lottie_private.h | 60 + .../lvgl/src/widgets/menu/lv_menu.c | 25 +- .../lvgl/src/widgets/menu/lv_menu.h | 71 +- .../lvgl/src/widgets/menu/lv_menu_private.h | 84 + .../lvgl/src/widgets/msgbox/lv_msgbox.c | 18 +- .../lvgl/src/widgets/msgbox/lv_msgbox.h | 32 +- .../src/widgets/msgbox/lv_msgbox_private.h | 57 + .../widgets/property/lv_dropdown_properties.c | 31 + .../widgets/property/lv_image_properties.c | 33 + .../widgets/property/lv_keyboard_properties.c | 26 + .../widgets/property/lv_label_properties.c | 26 + .../src/widgets/property/lv_obj_properties.c | 93 + .../widgets/property/lv_obj_property_names.h | 22 + .../widgets/property/lv_roller_properties.c | 25 + .../widgets/property/lv_style_properties.c | 132 + .../widgets/property/lv_style_properties.h | 130 + .../widgets/property/lv_textarea_properties.c | 37 + .../lvgl/src/widgets/roller/lv_roller.c | 99 +- .../lvgl/src/widgets/roller/lv_roller.h | 35 +- .../src/widgets/roller/lv_roller_private.h | 55 + .../lvgl/src/widgets/scale/lv_scale.c | 500 +- .../lvgl/src/widgets/scale/lv_scale.h | 60 +- .../lvgl/src/widgets/scale/lv_scale_private.h | 82 + .../lvgl/src/widgets/slider/lv_slider.c | 63 +- .../lvgl/src/widgets/slider/lv_slider.h | 73 +- .../src/widgets/slider/lv_slider_private.h | 55 + .../lvgl/src/widgets/span/lv_span.c | 139 +- .../lvgl/src/widgets/span/lv_span.h | 57 +- .../lvgl/src/widgets/span/lv_span_private.h | 65 + .../lvgl/src/widgets/spinbox/lv_spinbox.c | 5 +- .../lvgl/src/widgets/spinbox/lv_spinbox.h | 14 - .../src/widgets/spinbox/lv_spinbox_private.h | 59 + .../lvgl/src/widgets/spinner/lv_spinner.c | 2 + .../lvgl/src/widgets/switch/lv_switch.c | 8 +- .../lvgl/src/widgets/switch/lv_switch.h | 11 +- .../src/widgets/switch/lv_switch_private.h | 54 + .../lvgl/src/widgets/table/lv_table.c | 43 +- .../lvgl/src/widgets/table/lv_table.h | 37 +- .../lvgl/src/widgets/table/lv_table_private.h | 64 + .../lvgl/src/widgets/tabview/lv_tabview.c | 12 + .../lvgl/src/widgets/tabview/lv_tabview.h | 17 +- .../src/widgets/tabview/lv_tabview_private.h | 55 + .../lvgl/src/widgets/textarea/lv_textarea.c | 160 +- .../lvgl/src/widgets/textarea/lv_textarea.h | 51 +- .../widgets/textarea/lv_textarea_private.h | 75 + .../lvgl/src/widgets/tileview/lv_tileview.c | 3 +- .../lvgl/src/widgets/tileview/lv_tileview.h | 13 - .../widgets/tileview/lv_tileview_private.h | 58 + .../lvgl/src/widgets/win/lv_win.c | 2 + .../lvgl/src/widgets/win/lv_win.h | 8 +- .../lvgl/src/widgets/win/lv_win_private.h | 52 + tasmota/lvgl_berry/tasmota_lv_conf.h | 197 +- .../xdrv_52_3_berry_lvgl.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino | 5 +- 711 files changed, 90476 insertions(+), 14405 deletions(-) delete mode 100644 lib/libesp32_lvgl/lvgl/README_Tasmota.md create mode 100644 lib/libesp32_lvgl/lvgl/lv_version.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_obj_class_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_obj_event_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/core/lv_refr_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_14_cjk.c create mode 100644 lib/libesp32_lvgl/lvgl/src/layouts/lv_layout_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_sd.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/allocators.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/cursorstreamwrapper.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/document.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodedstream.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodings.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/en.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/error.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filereadstream.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filewritestream.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/fwd.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/biginteger.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/clzll.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/diyfp.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/dtoa.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/ieee754.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/itoa.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/meta.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/pow10.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/regex.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/stack.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strfunc.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strtod.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/swap.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/istreamwrapper.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorybuffer.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorystream.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/inttypes.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/stdint.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/ostreamwrapper.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/pointer.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/prettywriter.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/rapidjson.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/reader.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/schema.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stream.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stringbuffer.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/uri.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/writer.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_lottie.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAccessor.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBinaryDesc.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgGlCanvas.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInlist.h rename lib/libesp32_lvgl/lvgl/src/libs/thorvg/{tvgBezier.cpp => tvgLines.cpp} (77%) rename lib/libesp32_lvgl/lvgl/src/libs/thorvg/{tvgBezier.h => tvgLines.h} (80%) create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLock.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieAnimation.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieProperty.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h rename lib/libesp32_lvgl/lvgl/src/misc/cache/{_lv_cache_lru_rb.c => lv_cache_lru_rb.c} (94%) rename lib/libesp32_lvgl/lvgl/src/misc/cache/{_lv_cache_lru_rb.h => lv_cache_lru_rb.h} (96%) create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_anim_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_area_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_color_op_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_style_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.h create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_os.c create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_os_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/tick/lv_tick_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_dropdown_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_image_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_keyboard_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_label_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_property_names.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_roller_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_textarea_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win_private.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 40275a003..f81ca1a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 platform update from 2024.08.10 to 2024.08.11 (#22021) +- ESP32 LVGL library from v9.1.0 to v9.2.0 ### Fixed - Matter fixed UI bug when no endpoints configured (#22008) diff --git a/lib/libesp32_lvgl/LVGL_assets/src/lv_theme_haspmota.c b/lib/libesp32_lvgl/LVGL_assets/src/lv_theme_haspmota.c index 6d891a1b5..8e08583a3 100644 --- a/lib/libesp32_lvgl/LVGL_assets/src/lv_theme_haspmota.c +++ b/lib/libesp32_lvgl/LVGL_assets/src/lv_theme_haspmota.c @@ -3,11 +3,14 @@ * */ +#include + /********************* * INCLUDES *********************/ #include "../lvgl.h" /*To see all the widgets*/ +#include "themes/lv_theme_private.h" #include "lv_theme_haspmota.h" // #include "misc/lv_gc.h" TODO @@ -633,7 +636,7 @@ lv_theme_t * lv_theme_haspmota_init(lv_display_t * disp, lv_color_t color_primar *In a general case styles could be in simple `static lv_style_t my_style...` variables*/ if(!inited) { // LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t)); - styles = (my_theme_styles_t *)malloc(sizeof(my_theme_styles_t)); // TODO LVGL + styles = (my_theme_styles_t *) malloc(sizeof(my_theme_styles_t)); // TODO LVGL } if(LV_HOR_RES <= 320) disp_size = DISP_SMALL; diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md b/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md index 58093cce8..f3ca20c89 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/LVGL_API_Reference.md @@ -17,6 +17,7 @@ anim_get_timer||lv.timer|[lv_anim_get_timer](https://docs.lvgl.io/9.0/search.htm anim_refr_now|||[lv_anim_refr_now](https://docs.lvgl.io/9.0/search.html?q=lv_anim_refr_now) anim_speed|int|int|[lv_anim_speed](https://docs.lvgl.io/9.0/search.html?q=lv_anim_speed) anim_speed_clamped|int, int, int|int|[lv_anim_speed_clamped](https://docs.lvgl.io/9.0/search.html?q=lv_anim_speed_clamped) +anim_speed_to_time|int, int, int|int|[lv_anim_speed_to_time](https://docs.lvgl.io/9.0/search.html?q=lv_anim_speed_to_time) area_align|lv.area, lv.area, int, int, int||[lv_area_align](https://docs.lvgl.io/9.0/search.html?q=lv_area_align) area_copy|lv.area, lv.area||[lv_area_copy](https://docs.lvgl.io/9.0/search.html?q=lv_area_copy) area_get_height|lv.area|int|[lv_area_get_height](https://docs.lvgl.io/9.0/search.html?q=lv_area_get_height) @@ -31,6 +32,7 @@ canvas_buf_size|int, int, int, int|int|[lv_canvas_buf_size](https://docs.lvgl.io clamp_height|int, int, int, int|int|[lv_clamp_height](https://docs.lvgl.io/9.0/search.html?q=lv_clamp_height) clamp_width|int, int, int, int|int|[lv_clamp_width](https://docs.lvgl.io/9.0/search.html?q=lv_clamp_width) color32_eq|int, int|bool|[lv_color32_eq](https://docs.lvgl.io/9.0/search.html?q=lv_color32_eq) +color32_luminance|int|int|[lv_color32_luminance](https://docs.lvgl.io/9.0/search.html?q=lv_color32_luminance) color32_make|int, int, int, int|int|[lv_color32_make](https://docs.lvgl.io/9.0/search.html?q=lv_color32_make) color_16_16_mix|int, int, int|int|[lv_color_16_16_mix](https://docs.lvgl.io/9.0/search.html?q=lv_color_16_16_mix) color_black||lv.color|[lv_color_black](https://docs.lvgl.io/9.0/search.html?q=lv_color_black) @@ -44,6 +46,7 @@ color_hex|int|lv.color|[lv_color_hex](https://docs.lvgl.io/9.0/search.html?q=lv_ color_hex3|int|lv.color|[lv_color_hex3](https://docs.lvgl.io/9.0/search.html?q=lv_color_hex3) color_hsv_to_rgb|int, int, int|lv.color|[lv_color_hsv_to_rgb](https://docs.lvgl.io/9.0/search.html?q=lv_color_hsv_to_rgb) color_lighten|lv.color, int|lv.color|[lv_color_lighten](https://docs.lvgl.io/9.0/search.html?q=lv_color_lighten) +color_luminance|lv.color|int|[lv_color_luminance](https://docs.lvgl.io/9.0/search.html?q=lv_color_luminance) color_make|int, int, int|lv.color|[lv_color_make](https://docs.lvgl.io/9.0/search.html?q=lv_color_make) color_mix|lv.color, lv.color, int|lv.color|[lv_color_mix](https://docs.lvgl.io/9.0/search.html?q=lv_color_mix) color_mix32|int, int|int|[lv_color_mix32](https://docs.lvgl.io/9.0/search.html?q=lv_color_mix32) @@ -67,6 +70,7 @@ draw_dispatch|||[lv_draw_dispatch](https://docs.lvgl.io/9.0/search.html?q=lv_dra draw_dispatch_layer|lv.display, lv.layer|bool|[lv_draw_dispatch_layer](https://docs.lvgl.io/9.0/search.html?q=lv_draw_dispatch_layer) draw_dispatch_request|||[lv_draw_dispatch_request](https://docs.lvgl.io/9.0/search.html?q=lv_draw_dispatch_request) draw_dispatch_wait_for_request|||[lv_draw_dispatch_wait_for_request](https://docs.lvgl.io/9.0/search.html?q=lv_draw_dispatch_wait_for_request) +draw_get_unit_count||int|[lv_draw_get_unit_count](https://docs.lvgl.io/9.0/search.html?q=lv_draw_get_unit_count) draw_init|||[lv_draw_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_init) draw_label|lv.layer, lv.draw_label_dsc, lv.area||[lv_draw_label](https://docs.lvgl.io/9.0/search.html?q=lv_draw_label) draw_label_dsc_init|lv.draw_label_dsc||[lv_draw_label_dsc_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_label_dsc_init) @@ -77,6 +81,7 @@ draw_line|lv.layer, lv.draw_line_dsc||[lv_draw_line](https://docs.lvgl.io/9.0/se draw_line_dsc_init|lv.draw_line_dsc||[lv_draw_line_dsc_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_line_dsc_init) draw_rect|lv.layer, lv.draw_rect_dsc, lv.area||[lv_draw_rect](https://docs.lvgl.io/9.0/search.html?q=lv_draw_rect) draw_rect_dsc_init|lv.draw_rect_dsc||[lv_draw_rect_dsc_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_rect_dsc_init) +draw_wait_for_finish|||[lv_draw_wait_for_finish](https://docs.lvgl.io/9.0/search.html?q=lv_draw_wait_for_finish) event_dsc_get_cb|lv.event_dsc|lv.event_cb|[lv_event_dsc_get_cb](https://docs.lvgl.io/9.0/search.html?q=lv_event_dsc_get_cb) event_dsc_get_user_data|lv.event_dsc|comptr|[lv_event_dsc_get_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_event_dsc_get_user_data) event_register_id||int|[lv_event_register_id](https://docs.lvgl.io/9.0/search.html?q=lv_event_register_id) @@ -104,6 +109,7 @@ obj_class_create_obj|lv.obj_class, lv.obj|lv.obj|[lv_obj_class_create_obj](https obj_delete_anim_completed_cb|lv.anim||[lv_obj_delete_anim_completed_cb](https://docs.lvgl.io/9.0/search.html?q=lv_obj_delete_anim_completed_cb) obj_enable_style_refresh|bool||[lv_obj_enable_style_refresh](https://docs.lvgl.io/9.0/search.html?q=lv_obj_enable_style_refresh) obj_event_base|lv.obj_class, lv.event|int|[lv_obj_event_base](https://docs.lvgl.io/9.0/search.html?q=lv_obj_event_base) +obj_id_compare|\, \|int|[lv_obj_id_compare](https://docs.lvgl.io/9.0/search.html?q=lv_obj_id_compare) obj_redraw|lv.layer, lv.obj||[lv_obj_redraw](https://docs.lvgl.io/9.0/search.html?q=lv_obj_redraw) obj_report_style_change|lv.style||[lv_obj_report_style_change](https://docs.lvgl.io/9.0/search.html?q=lv_obj_report_style_change) obj_style_get_selector_part|int|int|[lv_obj_style_get_selector_part](https://docs.lvgl.io/9.0/search.html?q=lv_obj_style_get_selector_part) @@ -131,8 +137,10 @@ screen_load_anim|lv.obj, int, int, int, bool||[lv_screen_load_anim](https://docs span_stack_deinit|||[lv_span_stack_deinit](https://docs.lvgl.io/9.0/search.html?q=lv_span_stack_deinit) span_stack_init|||[lv_span_stack_init](https://docs.lvgl.io/9.0/search.html?q=lv_span_stack_init) style_get_num_custom_props||int|[lv_style_get_num_custom_props](https://docs.lvgl.io/9.0/search.html?q=lv_style_get_num_custom_props) +style_get_prop_group|int|int|[lv_style_get_prop_group](https://docs.lvgl.io/9.0/search.html?q=lv_style_get_prop_group) style_prop_get_default|int|int|[lv_style_prop_get_default](https://docs.lvgl.io/9.0/search.html?q=lv_style_prop_get_default) style_prop_has_flag|int, int|bool|[lv_style_prop_has_flag](https://docs.lvgl.io/9.0/search.html?q=lv_style_prop_has_flag) +style_prop_lookup_flags|int|int|[lv_style_prop_lookup_flags](https://docs.lvgl.io/9.0/search.html?q=lv_style_prop_lookup_flags) style_register_prop|int|int|[lv_style_register_prop](https://docs.lvgl.io/9.0/search.html?q=lv_style_register_prop) task_handler||int|[lv_task_handler](https://docs.lvgl.io/9.0/search.html?q=lv_task_handler) text_get_size|comptr, string, lv.font, int, int, int, int||[lv_text_get_size](https://docs.lvgl.io/9.0/search.html?q=lv_text_get_size) @@ -253,6 +261,7 @@ is_invalidation_enabled||bool|[lv_display_is_invalidation_enabled](https://docs. is_invalidation_enabled||bool|[lv_display_is_invalidation_enabled](https://docs.lvgl.io/9.0/search.html?q=lv_display_is_invalidation_enabled) remove|||[lv_display_delete](https://docs.lvgl.io/9.0/search.html?q=lv_display_delete) remove_event_cb_with_user_data|\, \|int|[lv_display_remove_event_cb_with_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_display_remove_event_cb_with_user_data) +rotate_area|lv.area||[lv_display_rotate_area](https://docs.lvgl.io/9.0/search.html?q=lv_display_rotate_area) send_event|int, \|int|[lv_display_send_event](https://docs.lvgl.io/9.0/search.html?q=lv_display_send_event) send_event|int, \|int|[lv_display_send_event](https://docs.lvgl.io/9.0/search.html?q=lv_display_send_event) set_angle|int||[lv_display_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_rotation) @@ -315,6 +324,7 @@ get_edge_cb||callback|[lv_group_get_edge_cb](https://docs.lvgl.io/9.0/search.htm get_editing||bool|[lv_group_get_editing](https://docs.lvgl.io/9.0/search.html?q=lv_group_get_editing) get_focus_cb||lv.group_focus_cb|[lv_group_get_focus_cb](https://docs.lvgl.io/9.0/search.html?q=lv_group_get_focus_cb) get_focused||lv.obj|[lv_group_get_focused](https://docs.lvgl.io/9.0/search.html?q=lv_group_get_focused) +get_obj_by_index|int|lv.obj|[lv_group_get_obj_by_index](https://docs.lvgl.io/9.0/search.html?q=lv_group_get_obj_by_index) get_obj_count||int|[lv_group_get_obj_count](https://docs.lvgl.io/9.0/search.html?q=lv_group_get_obj_count) get_wrap||bool|[lv_group_get_wrap](https://docs.lvgl.io/9.0/search.html?q=lv_group_get_wrap) remove|||[lv_group_delete](https://docs.lvgl.io/9.0/search.html?q=lv_group_delete) @@ -349,6 +359,7 @@ get_mode||int|[lv_indev_get_mode](https://docs.lvgl.io/9.0/search.html?q=lv_inde get_next||lv.indev|[lv_indev_get_next](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_next) get_next||lv.indev|[lv_indev_get_next](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_next) get_point|comptr||[lv_indev_get_point](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_point) +get_press_moved||bool|[lv_indev_get_press_moved](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_press_moved) get_read_timer||lv.timer|[lv_indev_get_read_timer](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_read_timer) get_scroll_dir||int|[lv_indev_get_scroll_dir](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_scroll_dir) get_scroll_obj||lv.obj|[lv_indev_get_scroll_obj](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_scroll_obj) @@ -371,9 +382,13 @@ set_disp|lv.display||[lv_indev_set_display](https://docs.lvgl.io/9.0/search.html set_display|lv.display||[lv_indev_set_display](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_display) set_driver_data|\||[lv_indev_set_driver_data](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_driver_data) set_group|lv.group||[lv_indev_set_group](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_group) +set_long_press_time|int||[lv_indev_set_long_press_time](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_long_press_time) set_mode|int||[lv_indev_set_mode](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_mode) +set_scroll_limit|int||[lv_indev_set_scroll_limit](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_scroll_limit) +set_scroll_throw|int||[lv_indev_set_scroll_throw](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_scroll_throw) set_type|int||[lv_indev_set_type](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_type) set_user_data|\||[lv_indev_set_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_user_data) +stop_processing|||[lv_indev_stop_processing](https://docs.lvgl.io/9.0/search.html?q=lv_indev_stop_processing) wait_release|||[lv_indev_wait_release](https://docs.lvgl.io/9.0/search.html?q=lv_indev_wait_release) ### class `lv.style` @@ -413,7 +428,7 @@ set_bg_img_tiled|bool||[lv_style_set_bg_image_tiled](https://docs.lvgl.io/9.0/se set_bg_main_opa|int||[lv_style_set_bg_main_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_bg_main_opa) set_bg_main_stop|int||[lv_style_set_bg_main_stop](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_bg_main_stop) set_bg_opa|int||[lv_style_set_bg_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_bg_opa) -set_bitmap_mask_src|lv.image_dsc||[lv_style_set_bitmap_mask_src](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_bitmap_mask_src) +set_bitmap_mask_src|\||[lv_style_set_bitmap_mask_src](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_bitmap_mask_src) set_blend_mode|int||[lv_style_set_blend_mode](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_blend_mode) set_border_color|lv.color||[lv_style_set_border_color](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_border_color) set_border_opa|int||[lv_style_set_border_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_border_opa) @@ -568,6 +583,7 @@ fade_in|int, int||[lv_obj_fade_in](https://docs.lvgl.io/9.0/search.html?q=lv_obj fade_out|int, int||[lv_obj_fade_out](https://docs.lvgl.io/9.0/search.html?q=lv_obj_fade_out) free_id|||[lv_obj_free_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_free_id) get_child|int|lv.obj|[lv_obj_get_child](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_child) +get_child_by_id|\|lv.obj|[lv_obj_get_child_by_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_child_by_id) get_child_by_type|int, lv.obj_class|lv.obj|[lv_obj_get_child_by_type](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_child_by_type) get_child_cnt||int|[lv_obj_get_child_count](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_child_count) get_child_count||int|[lv_obj_get_child_count](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_child_count) @@ -584,6 +600,7 @@ get_event_count||int|[lv_obj_get_event_count](https://docs.lvgl.io/9.0/search.ht get_event_dsc|int|lv.event_dsc|[lv_obj_get_event_dsc](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_event_dsc) get_group||lv.group|[lv_obj_get_group](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_group) get_height||int|[lv_obj_get_height](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_height) +get_id||comptr|[lv_obj_get_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_id) get_index||int|[lv_obj_get_index](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_index) get_index_by_type|lv.obj_class|int|[lv_obj_get_index_by_type](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_index_by_type) get_parent||lv.obj|[lv_obj_get_parent](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_parent) @@ -633,7 +650,7 @@ get_style_bg_image_tiled|int|bool|[lv_obj_get_style_bg_image_tiled](https://docs get_style_bg_main_opa|int|int|[lv_obj_get_style_bg_main_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_bg_main_opa) get_style_bg_main_stop|int|int|[lv_obj_get_style_bg_main_stop](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_bg_main_stop) get_style_bg_opa|int|int|[lv_obj_get_style_bg_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_bg_opa) -get_style_bitmap_mask_src|int|lv.image_dsc|[lv_obj_get_style_bitmap_mask_src](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_bitmap_mask_src) +get_style_bitmap_mask_src|int|comptr|[lv_obj_get_style_bitmap_mask_src](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_bitmap_mask_src) get_style_blend_mode|int|int|[lv_obj_get_style_blend_mode](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_blend_mode) get_style_border_color|int|lv.color|[lv_obj_get_style_border_color](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_border_color) get_style_border_color_filtered|int|lv.color|[lv_obj_get_style_border_color_filtered](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_border_color_filtered) @@ -814,6 +831,7 @@ set_grid_align|int, int||[lv_obj_set_grid_align](https://docs.lvgl.io/9.0/search set_grid_cell|int, int, int, int, int, int||[lv_obj_set_grid_cell](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_grid_cell) set_grid_dsc_array|lv.int_arr, lv.int_arr||[lv_obj_set_grid_dsc_array](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_grid_dsc_array) set_height|int||[lv_obj_set_height](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_height) +set_id|\||[lv_obj_set_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_id) set_layout|int||[lv_obj_set_layout](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_layout) set_local_style_prop|int, int, int||[lv_obj_set_local_style_prop](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_local_style_prop) set_parent|lv.obj||[lv_obj_set_parent](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_parent) @@ -848,7 +866,7 @@ set_style_bg_image_tiled|bool, int||[lv_obj_set_style_bg_image_tiled](https://do set_style_bg_main_opa|int, int||[lv_obj_set_style_bg_main_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_bg_main_opa) set_style_bg_main_stop|int, int||[lv_obj_set_style_bg_main_stop](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_bg_main_stop) set_style_bg_opa|int, int||[lv_obj_set_style_bg_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_bg_opa) -set_style_bitmap_mask_src|lv.image_dsc, int||[lv_obj_set_style_bitmap_mask_src](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_bitmap_mask_src) +set_style_bitmap_mask_src|\, int||[lv_obj_set_style_bitmap_mask_src](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_bitmap_mask_src) set_style_blend_mode|int, int||[lv_obj_set_style_blend_mode](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_blend_mode) set_style_border_color|lv.color, int||[lv_obj_set_style_border_color](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_border_color) set_style_border_opa|int, int||[lv_obj_set_style_border_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_border_opa) @@ -956,6 +974,7 @@ set_width|int||[lv_obj_set_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_ set_x|int||[lv_obj_set_x](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_x) set_y|int||[lv_obj_set_y](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_y) stringify_id|comptr, int|string|[lv_obj_stringify_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_stringify_id) +style_apply_color_filter|int, int|int|[lv_obj_style_apply_color_filter](https://docs.lvgl.io/9.0/search.html?q=lv_obj_style_apply_color_filter) swap|lv.obj||[lv_obj_swap](https://docs.lvgl.io/9.0/search.html?q=lv_obj_swap) transform_point|comptr, int||[lv_obj_transform_point](https://docs.lvgl.io/9.0/search.html?q=lv_obj_transform_point) transform_point_array|lv.point_arr, int, int||[lv_obj_transform_point_array](https://docs.lvgl.io/9.0/search.html?q=lv_obj_transform_point_array) @@ -1004,10 +1023,12 @@ get_indic_area||lv.area|[lv_bar_get_indic_area](https://docs.lvgl.io/9.0/search. get_max_value||int|[lv_bar_get_max_value](https://docs.lvgl.io/9.0/search.html?q=lv_bar_get_max_value) get_min_value||int|[lv_bar_get_min_value](https://docs.lvgl.io/9.0/search.html?q=lv_bar_get_min_value) get_mode||int|[lv_bar_get_mode](https://docs.lvgl.io/9.0/search.html?q=lv_bar_get_mode) +get_orientation||int|[lv_bar_get_orientation](https://docs.lvgl.io/9.0/search.html?q=lv_bar_get_orientation) get_start_value||int|[lv_bar_get_start_value](https://docs.lvgl.io/9.0/search.html?q=lv_bar_get_start_value) get_value||int|[lv_bar_get_value](https://docs.lvgl.io/9.0/search.html?q=lv_bar_get_value) is_symmetrical||bool|[lv_bar_is_symmetrical](https://docs.lvgl.io/9.0/search.html?q=lv_bar_is_symmetrical) set_mode|int||[lv_bar_set_mode](https://docs.lvgl.io/9.0/search.html?q=lv_bar_set_mode) +set_orientation|int||[lv_bar_set_orientation](https://docs.lvgl.io/9.0/search.html?q=lv_bar_set_orientation) set_range|int, int||[lv_bar_set_range](https://docs.lvgl.io/9.0/search.html?q=lv_bar_set_range) set_start_value|int, int||[lv_bar_set_start_value](https://docs.lvgl.io/9.0/search.html?q=lv_bar_set_start_value) set_value|int, int||[lv_bar_set_value](https://docs.lvgl.io/9.0/search.html?q=lv_bar_set_value) @@ -1027,7 +1048,6 @@ clear_button_ctrl_all|int||[lv_buttonmatrix_clear_button_ctrl_all](https://docs. get_button_text|int|string|[lv_buttonmatrix_get_button_text](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_get_button_text) get_map||comptr|[lv_buttonmatrix_get_map](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_get_map) get_one_checked||bool|[lv_buttonmatrix_get_one_checked](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_get_one_checked) -get_popovers||bool|[lv_buttonmatrix_get_popovers](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_get_popovers) get_selected_button||int|[lv_buttonmatrix_get_selected_button](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_get_selected_button) has_button_ctrl|int, int|bool|[lv_buttonmatrix_has_button_ctrl](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_has_button_ctrl) set_button_ctrl|int, int||[lv_buttonmatrix_set_button_ctrl](https://docs.lvgl.io/9.0/search.html?q=lv_buttonmatrix_set_button_ctrl) @@ -1149,10 +1169,13 @@ set_text_static|string||[lv_label_set_text_static](https://docs.lvgl.io/9.0/sear Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- -get_points||comptr|[lv_line_get_points](https://docs.lvgl.io/9.0/search.html?q=lv_line_get_points) -get_points_num||int|[lv_line_get_points_num](https://docs.lvgl.io/9.0/search.html?q=lv_line_get_points_num) +get_point_count||int|[lv_line_get_point_count](https://docs.lvgl.io/9.0/search.html?q=lv_line_get_point_count) +get_points||lv.point_precise|[lv_line_get_points](https://docs.lvgl.io/9.0/search.html?q=lv_line_get_points) +get_points_mutable||lv.point_precise|[lv_line_get_points_mutable](https://docs.lvgl.io/9.0/search.html?q=lv_line_get_points_mutable) get_y_invert||bool|[lv_line_get_y_invert](https://docs.lvgl.io/9.0/search.html?q=lv_line_get_y_invert) +is_point_array_mutable||bool|[lv_line_is_point_array_mutable](https://docs.lvgl.io/9.0/search.html?q=lv_line_is_point_array_mutable) set_points|lv.point_arr, int||[lv_line_set_points](https://docs.lvgl.io/9.0/search.html?q=lv_line_set_points) +set_points_mutable|lv.point_arr, int||[lv_line_set_points_mutable](https://docs.lvgl.io/9.0/search.html?q=lv_line_set_points_mutable) set_y_invert|bool||[lv_line_set_y_invert](https://docs.lvgl.io/9.0/search.html?q=lv_line_set_y_invert) ### widget `lv.roller` @@ -1215,6 +1238,7 @@ set_column_count|int||[lv_table_set_column_count](https://docs.lvgl.io/9.0/searc set_column_width|int, int||[lv_table_set_column_width](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_column_width) set_row_cnt|int||[lv_table_set_row_count](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_row_count) set_row_count|int||[lv_table_set_row_count](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_row_count) +set_selected_cell|int, int||[lv_table_set_selected_cell](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_selected_cell) ### widget `lv.textarea` @@ -1309,6 +1333,7 @@ get_range_min_value||int|[lv_scale_get_range_min_value](https://docs.lvgl.io/9.0 get_total_tick_count||int|[lv_scale_get_total_tick_count](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_total_tick_count) set_angle|int||[lv_scale_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_rotation) set_angle_range|int||[lv_scale_set_angle_range](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_angle_range) +set_draw_ticks_on_top|bool||[lv_scale_set_draw_ticks_on_top](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_draw_ticks_on_top) set_image_needle_value|lv.obj, int||[lv_scale_set_image_needle_value](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_image_needle_value) set_label_show|bool||[lv_scale_set_label_show](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_label_show) set_line_needle_value|lv.obj, int, int||[lv_scale_set_line_needle_value](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_line_needle_value) @@ -1332,6 +1357,7 @@ get_first_point_center_offset||int|[lv_chart_get_first_point_center_offset](http get_point_count||int|[lv_chart_get_point_count](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_point_count) get_point_pos_by_id|lv.chart_series, int, comptr||[lv_chart_get_point_pos_by_id](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_point_pos_by_id) get_pressed_point||int|[lv_chart_get_pressed_point](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_pressed_point) +get_series_color|lv.chart_series|lv.color|[lv_chart_get_series_color](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_series_color) get_series_next|lv.chart_series|lv.chart_series|[lv_chart_get_series_next](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_series_next) get_type||int|[lv_chart_get_type](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_type) get_x_array|lv.chart_series|lv.int_arr|[lv_chart_get_x_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_x_array) @@ -1424,6 +1450,7 @@ _btn_text|int|string|[lv_keyboard_get_button_text](https://docs.lvgl.io/9.0/sear get_button_text|int|string|[lv_keyboard_get_button_text](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_get_button_text) get_map_array||comptr|[lv_keyboard_get_map_array](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_get_map_array) get_mode||int|[lv_keyboard_get_mode](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_get_mode) +get_popovers||bool|[lv_keyboard_get_popovers](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_get_popovers) get_selected_button||int|[lv_keyboard_get_selected_button](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_get_selected_button) get_textarea||lv.obj|[lv_keyboard_get_textarea](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_get_textarea) set_mode|int||[lv_keyboard_set_mode](https://docs.lvgl.io/9.0/search.html?q=lv_keyboard_set_mode) @@ -1489,6 +1516,7 @@ Method|Arguments|Return type|LVGL equivalent get_btnmatrix||lv.obj|[lv_calendar_get_btnmatrix](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_get_btnmatrix) get_highlighted_dates_num||int|[lv_calendar_get_highlighted_dates_num](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_get_highlighted_dates_num) header_dropdown_set_year_list|string||[lv_calendar_header_dropdown_set_year_list](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_header_dropdown_set_year_list) +set_chinese_mode|bool||[lv_calendar_set_chinese_mode](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_set_chinese_mode) set_day_names|comptr||[lv_calendar_set_day_names](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_set_day_names) set_showed_date|int, int||[lv_calendar_set_showed_date](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_set_showed_date) set_today_date|int, int, int||[lv_calendar_set_today_date](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_set_today_date) diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h index 7ebd3b27f..8f3f45329 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h @@ -45,7 +45,7 @@ const be_ntv_func_def_t lv_style_func[] = { { "set_bg_main_opa", { (const void*) &lv_style_set_bg_main_opa, "", "(lv.style)i" } }, { "set_bg_main_stop", { (const void*) &lv_style_set_bg_main_stop, "", "(lv.style)i" } }, { "set_bg_opa", { (const void*) &lv_style_set_bg_opa, "", "(lv.style)i" } }, - { "set_bitmap_mask_src", { (const void*) &lv_style_set_bitmap_mask_src, "", "(lv.style)(lv.image_dsc)" } }, + { "set_bitmap_mask_src", { (const void*) &lv_style_set_bitmap_mask_src, "", "(lv.style)." } }, { "set_blend_mode", { (const void*) &lv_style_set_blend_mode, "", "(lv.style)i" } }, { "set_border_color", { (const void*) &lv_style_set_border_color, "", "(lv.style)(lv.color)" } }, { "set_border_opa", { (const void*) &lv_style_set_border_opa, "", "(lv.style)i" } }, @@ -173,6 +173,7 @@ const be_ntv_func_def_t lv_group_func[] = { { "get_editing", { (const void*) &lv_group_get_editing, "b", "(lv.group)" } }, { "get_focus_cb", { (const void*) &lv_group_get_focus_cb, "lv.group_focus_cb", "(lv.group)" } }, { "get_focused", { (const void*) &lv_group_get_focused, "lv.obj", "(lv.group)" } }, + { "get_obj_by_index", { (const void*) &lv_group_get_obj_by_index, "lv.obj", "(lv.group)i" } }, { "get_obj_count", { (const void*) &lv_group_get_obj_count, "i", "(lv.group)" } }, { "get_wrap", { (const void*) &lv_group_get_wrap, "b", "(lv.group)" } }, { "remove", { (const void*) &lv_group_delete, "", "(lv.group)" } }, @@ -216,6 +217,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "fade_out", { (const void*) &lv_obj_fade_out, "", "(lv.obj)ii" } }, { "free_id", { (const void*) &lv_obj_free_id, "", "(lv.obj)" } }, { "get_child", { (const void*) &lv_obj_get_child, "lv.obj", "(lv.obj)i" } }, + { "get_child_by_id", { (const void*) &lv_obj_get_child_by_id, "lv.obj", "(lv.obj)." } }, { "get_child_by_type", { (const void*) &lv_obj_get_child_by_type, "lv.obj", "(lv.obj)i(lv.obj_class)" } }, { "get_child_cnt", { (const void*) &lv_obj_get_child_count, "i", "(lv.obj)" } }, { "get_child_count", { (const void*) &lv_obj_get_child_count, "i", "(lv.obj)" } }, @@ -232,6 +234,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "get_event_dsc", { (const void*) &lv_obj_get_event_dsc, "lv.event_dsc", "(lv.obj)i" } }, { "get_group", { (const void*) &lv_obj_get_group, "lv.group", "(lv.obj)" } }, { "get_height", { (const void*) &lv_obj_get_height, "i", "(lv.obj)" } }, + { "get_id", { (const void*) &lv_obj_get_id, "c", "(lv.obj)" } }, { "get_index", { (const void*) &lv_obj_get_index, "i", "(lv.obj)" } }, { "get_index_by_type", { (const void*) &lv_obj_get_index_by_type, "i", "(lv.obj)(lv.obj_class)" } }, { "get_parent", { (const void*) &lv_obj_get_parent, "lv.obj", "(lv.obj)" } }, @@ -281,7 +284,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "get_style_bg_main_opa", { (const void*) &lv_obj_get_style_bg_main_opa, "i", "(lv.obj)i" } }, { "get_style_bg_main_stop", { (const void*) &lv_obj_get_style_bg_main_stop, "i", "(lv.obj)i" } }, { "get_style_bg_opa", { (const void*) &lv_obj_get_style_bg_opa, "i", "(lv.obj)i" } }, - { "get_style_bitmap_mask_src", { (const void*) &lv_obj_get_style_bitmap_mask_src, "lv.image_dsc", "(lv.obj)i" } }, + { "get_style_bitmap_mask_src", { (const void*) &lv_obj_get_style_bitmap_mask_src, "c", "(lv.obj)i" } }, { "get_style_blend_mode", { (const void*) &lv_obj_get_style_blend_mode, "i", "(lv.obj)i" } }, { "get_style_border_color", { (const void*) &lv_obj_get_style_border_color, "lv.color", "(lv.obj)i" } }, { "get_style_border_color_filtered", { (const void*) &lv_obj_get_style_border_color_filtered, "lv.color", "(lv.obj)i" } }, @@ -460,6 +463,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_grid_cell", { (const void*) &lv_obj_set_grid_cell, "", "(lv.obj)iiiiii" } }, { "set_grid_dsc_array", { (const void*) &lv_obj_set_grid_dsc_array, "", "(lv.obj)(lv.int_arr)(lv.int_arr)" } }, { "set_height", { (const void*) &lv_obj_set_height, "", "(lv.obj)i" } }, + { "set_id", { (const void*) &lv_obj_set_id, "", "(lv.obj)." } }, { "set_layout", { (const void*) &lv_obj_set_layout, "", "(lv.obj)i" } }, { "set_local_style_prop", { (const void*) &lv_obj_set_local_style_prop, "", "(lv.obj)iii" } }, { "set_parent", { (const void*) &lv_obj_set_parent, "", "(lv.obj)(lv.obj)" } }, @@ -494,7 +498,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_style_bg_main_opa", { (const void*) &lv_obj_set_style_bg_main_opa, "", "(lv.obj)ii" } }, { "set_style_bg_main_stop", { (const void*) &lv_obj_set_style_bg_main_stop, "", "(lv.obj)ii" } }, { "set_style_bg_opa", { (const void*) &lv_obj_set_style_bg_opa, "", "(lv.obj)ii" } }, - { "set_style_bitmap_mask_src", { (const void*) &lv_obj_set_style_bitmap_mask_src, "", "(lv.obj)(lv.image_dsc)i" } }, + { "set_style_bitmap_mask_src", { (const void*) &lv_obj_set_style_bitmap_mask_src, "", "(lv.obj).i" } }, { "set_style_blend_mode", { (const void*) &lv_obj_set_style_blend_mode, "", "(lv.obj)ii" } }, { "set_style_border_color", { (const void*) &lv_obj_set_style_border_color, "", "(lv.obj)(lv.color)i" } }, { "set_style_border_opa", { (const void*) &lv_obj_set_style_border_opa, "", "(lv.obj)ii" } }, @@ -602,6 +606,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_x", { (const void*) &lv_obj_set_x, "", "(lv.obj)i" } }, { "set_y", { (const void*) &lv_obj_set_y, "", "(lv.obj)i" } }, { "stringify_id", { (const void*) &lv_obj_stringify_id, "s", "(lv.obj)ci" } }, + { "style_apply_color_filter", { (const void*) &lv_obj_style_apply_color_filter, "i", "(lv.obj)ii" } }, { "swap", { (const void*) &lv_obj_swap, "", "(lv.obj)(lv.obj)" } }, { "transform_point", { (const void*) &lv_obj_transform_point, "", "(lv.obj)ci" } }, { "transform_point_array", { (const void*) &lv_obj_transform_point_array, "", "(lv.obj)(lv.point_arr)ii" } }, @@ -678,6 +683,7 @@ const be_ntv_func_def_t lv_display_func[] = { { "is_invalidation_enabled", { (const void*) &lv_display_is_invalidation_enabled, "b", "(lv.display)" } }, { "remove", { (const void*) &lv_display_delete, "", "(lv.display)" } }, { "remove_event_cb_with_user_data", { (const void*) &lv_display_remove_event_cb_with_user_data, "i", "(lv.display).." } }, + { "rotate_area", { (const void*) &lv_display_rotate_area, "", "(lv.display)(lv.area)" } }, { "send_event", { (const void*) &lv_display_send_event, "i", "(lv.display)i." } }, { "set_angle", { (const void*) &lv_display_set_rotation, "", "(lv.display)i" } }, { "set_antialiasing", { (const void*) &lv_display_set_antialiasing, "", "(lv.display)b" } }, @@ -714,6 +720,7 @@ const be_ntv_func_def_t lv_indev_func[] = { { "get_mode", { (const void*) &lv_indev_get_mode, "i", "(lv.indev)" } }, { "get_next", { (const void*) &lv_indev_get_next, "lv.indev", "(lv.indev)" } }, { "get_point", { (const void*) &lv_indev_get_point, "", "(lv.indev)c" } }, + { "get_press_moved", { (const void*) &lv_indev_get_press_moved, "b", "(lv.indev)" } }, { "get_read_timer", { (const void*) &lv_indev_get_read_timer, "lv.timer", "(lv.indev)" } }, { "get_scroll_dir", { (const void*) &lv_indev_get_scroll_dir, "i", "(lv.indev)" } }, { "get_scroll_obj", { (const void*) &lv_indev_get_scroll_obj, "lv.obj", "(lv.indev)" } }, @@ -735,9 +742,13 @@ const be_ntv_func_def_t lv_indev_func[] = { { "set_display", { (const void*) &lv_indev_set_display, "", "(lv.indev)(lv.display)" } }, { "set_driver_data", { (const void*) &lv_indev_set_driver_data, "", "(lv.indev)." } }, { "set_group", { (const void*) &lv_indev_set_group, "", "(lv.indev)(lv.group)" } }, + { "set_long_press_time", { (const void*) &lv_indev_set_long_press_time, "", "(lv.indev)i" } }, { "set_mode", { (const void*) &lv_indev_set_mode, "", "(lv.indev)i" } }, + { "set_scroll_limit", { (const void*) &lv_indev_set_scroll_limit, "", "(lv.indev)i" } }, + { "set_scroll_throw", { (const void*) &lv_indev_set_scroll_throw, "", "(lv.indev)i" } }, { "set_type", { (const void*) &lv_indev_set_type, "", "(lv.indev)i" } }, { "set_user_data", { (const void*) &lv_indev_set_user_data, "", "(lv.indev)." } }, + { "stop_processing", { (const void*) &lv_indev_stop_processing, "", "(lv.indev)" } }, { "wait_release", { (const void*) &lv_indev_wait_release, "", "(lv.indev)" } }, }; @@ -855,10 +866,12 @@ const be_ntv_func_def_t lv_bar_func[] = { { "get_max_value", { (const void*) &lv_bar_get_max_value, "i", "(lv.obj)" } }, { "get_min_value", { (const void*) &lv_bar_get_min_value, "i", "(lv.obj)" } }, { "get_mode", { (const void*) &lv_bar_get_mode, "i", "(lv.obj)" } }, + { "get_orientation", { (const void*) &lv_bar_get_orientation, "i", "(lv.obj)" } }, { "get_start_value", { (const void*) &lv_bar_get_start_value, "i", "(lv.obj)" } }, { "get_value", { (const void*) &lv_bar_get_value, "i", "(lv.obj)" } }, { "is_symmetrical", { (const void*) &lv_bar_is_symmetrical, "b", "(lv.obj)" } }, { "set_mode", { (const void*) &lv_bar_set_mode, "", "(lv.obj)i" } }, + { "set_orientation", { (const void*) &lv_bar_set_orientation, "", "(lv.obj)i" } }, { "set_range", { (const void*) &lv_bar_set_range, "", "(lv.obj)ii" } }, { "set_start_value", { (const void*) &lv_bar_set_start_value, "", "(lv.obj)ii" } }, { "set_value", { (const void*) &lv_bar_set_value, "", "(lv.obj)ii" } }, @@ -880,7 +893,6 @@ const be_ntv_func_def_t lv_buttonmatrix_func[] = { { "get_button_text", { (const void*) &lv_buttonmatrix_get_button_text, "s", "(lv.obj)i" } }, { "get_map", { (const void*) &lv_buttonmatrix_get_map, "c", "(lv.obj)" } }, { "get_one_checked", { (const void*) &lv_buttonmatrix_get_one_checked, "b", "(lv.obj)" } }, - { "get_popovers", { (const void*) &lv_buttonmatrix_get_popovers, "b", "(lv.obj)" } }, { "get_selected_button", { (const void*) &lv_buttonmatrix_get_selected_button, "i", "(lv.obj)" } }, { "has_button_ctrl", { (const void*) &lv_buttonmatrix_has_button_ctrl, "b", "(lv.obj)ii" } }, { "set_button_ctrl", { (const void*) &lv_buttonmatrix_set_button_ctrl, "", "(lv.obj)ii" } }, @@ -898,6 +910,7 @@ const be_ntv_func_def_t lv_calendar_func[] = { { "get_btnmatrix", { (const void*) &lv_calendar_get_btnmatrix, "lv.obj", "(lv.obj)" } }, { "get_highlighted_dates_num", { (const void*) &lv_calendar_get_highlighted_dates_num, "i", "(lv.obj)" } }, { "header_dropdown_set_year_list", { (const void*) &lv_calendar_header_dropdown_set_year_list, "", "(lv.obj)s" } }, + { "set_chinese_mode", { (const void*) &lv_calendar_set_chinese_mode, "", "(lv.obj)b" } }, { "set_day_names", { (const void*) &lv_calendar_set_day_names, "", "(lv.obj)c" } }, { "set_showed_date", { (const void*) &lv_calendar_set_showed_date, "", "(lv.obj)ii" } }, { "set_today_date", { (const void*) &lv_calendar_set_today_date, "", "(lv.obj)iii" } }, @@ -929,6 +942,7 @@ const be_ntv_func_def_t lv_chart_func[] = { { "get_point_count", { (const void*) &lv_chart_get_point_count, "i", "(lv.obj)" } }, { "get_point_pos_by_id", { (const void*) &lv_chart_get_point_pos_by_id, "", "(lv.obj)(lv.chart_series)ic" } }, { "get_pressed_point", { (const void*) &lv_chart_get_pressed_point, "i", "(lv.obj)" } }, + { "get_series_color", { (const void*) &lv_chart_get_series_color, "lv.color", "(lv.obj)(lv.chart_series)" } }, { "get_series_next", { (const void*) &lv_chart_get_series_next, "lv.chart_series", "(lv.obj)(lv.chart_series)" } }, { "get_type", { (const void*) &lv_chart_get_type, "i", "(lv.obj)" } }, { "get_x_array", { (const void*) &lv_chart_get_x_array, "lv.int_arr", "(lv.obj)(lv.chart_series)" } }, @@ -1044,6 +1058,7 @@ const be_ntv_func_def_t lv_keyboard_func[] = { { "get_button_text", { (const void*) &lv_keyboard_get_button_text, "s", "(lv.obj)i" } }, { "get_map_array", { (const void*) &lv_keyboard_get_map_array, "c", "(lv.obj)" } }, { "get_mode", { (const void*) &lv_keyboard_get_mode, "i", "(lv.obj)" } }, + { "get_popovers", { (const void*) &lv_keyboard_get_popovers, "b", "(lv.obj)" } }, { "get_selected_button", { (const void*) &lv_keyboard_get_selected_button, "i", "(lv.obj)" } }, { "get_textarea", { (const void*) &lv_keyboard_get_textarea, "lv.obj", "(lv.obj)" } }, { "set_mode", { (const void*) &lv_keyboard_set_mode, "", "(lv.obj)i" } }, @@ -1088,10 +1103,13 @@ const be_ntv_func_def_t lv_led_func[] = { /* `lv_line` methods */ #ifdef BE_LV_WIDGET_LINE const be_ntv_func_def_t lv_line_func[] = { - { "get_points", { (const void*) &lv_line_get_points, "c", "(lv.obj)" } }, - { "get_points_num", { (const void*) &lv_line_get_points_num, "i", "(lv.obj)" } }, + { "get_point_count", { (const void*) &lv_line_get_point_count, "i", "(lv.obj)" } }, + { "get_points", { (const void*) &lv_line_get_points, "lv.point_precise", "(lv.obj)" } }, + { "get_points_mutable", { (const void*) &lv_line_get_points_mutable, "lv.point_precise", "(lv.obj)" } }, { "get_y_invert", { (const void*) &lv_line_get_y_invert, "b", "(lv.obj)" } }, + { "is_point_array_mutable", { (const void*) &lv_line_is_point_array_mutable, "b", "(lv.obj)" } }, { "set_points", { (const void*) &lv_line_set_points, "", "(lv.obj)(lv.point_arr)i" } }, + { "set_points_mutable", { (const void*) &lv_line_set_points_mutable, "", "(lv.obj)(lv.point_arr)i" } }, { "set_y_invert", { (const void*) &lv_line_set_y_invert, "", "(lv.obj)b" } }, }; #endif // BE_LV_WIDGET_LINE @@ -1175,6 +1193,7 @@ const be_ntv_func_def_t lv_scale_func[] = { { "get_total_tick_count", { (const void*) &lv_scale_get_total_tick_count, "i", "(lv.obj)" } }, { "set_angle", { (const void*) &lv_scale_set_rotation, "", "(lv.obj)i" } }, { "set_angle_range", { (const void*) &lv_scale_set_angle_range, "", "(lv.obj)i" } }, + { "set_draw_ticks_on_top", { (const void*) &lv_scale_set_draw_ticks_on_top, "", "(lv.obj)b" } }, { "set_image_needle_value", { (const void*) &lv_scale_set_image_needle_value, "", "(lv.obj)(lv.obj)i" } }, { "set_label_show", { (const void*) &lv_scale_set_label_show, "", "(lv.obj)b" } }, { "set_line_needle_value", { (const void*) &lv_scale_set_line_needle_value, "", "(lv.obj)(lv.obj)ii" } }, @@ -1303,6 +1322,7 @@ const be_ntv_func_def_t lv_table_func[] = { { "set_column_width", { (const void*) &lv_table_set_column_width, "", "(lv.obj)ii" } }, { "set_row_cnt", { (const void*) &lv_table_set_row_count, "", "(lv.obj)i" } }, { "set_row_count", { (const void*) &lv_table_set_row_count, "", "(lv.obj)i" } }, + { "set_selected_cell", { (const void*) &lv_table_set_selected_cell, "", "(lv.obj)ii" } }, }; #endif // BE_LV_WIDGET_TABLE diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c index 456c7d065..a21b4b3e6 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c @@ -39,6 +39,7 @@ const be_ntv_func_def_t lv_func[] = { { "anim_refr_now", { (const void*) &lv_anim_refr_now, "", "" } }, { "anim_speed", { (const void*) &lv_anim_speed, "i", "i" } }, { "anim_speed_clamped", { (const void*) &lv_anim_speed_clamped, "i", "iii" } }, + { "anim_speed_to_time", { (const void*) &lv_anim_speed_to_time, "i", "iii" } }, { "area_align", { (const void*) &lv_area_align, "", "(lv.area)(lv.area)iii" } }, { "area_copy", { (const void*) &lv_area_copy, "", "(lv.area)(lv.area)" } }, { "area_get_height", { (const void*) &lv_area_get_height, "i", "(lv.area)" } }, @@ -53,6 +54,7 @@ const be_ntv_func_def_t lv_func[] = { { "clamp_height", { (const void*) &lv_clamp_height, "i", "iiii" } }, { "clamp_width", { (const void*) &lv_clamp_width, "i", "iiii" } }, { "color32_eq", { (const void*) &lv_color32_eq, "b", "ii" } }, + { "color32_luminance", { (const void*) &lv_color32_luminance, "i", "i" } }, { "color32_make", { (const void*) &lv_color32_make, "i", "iiii" } }, { "color_16_16_mix", { (const void*) &lv_color_16_16_mix, "i", "iii" } }, { "color_black", { (const void*) &lv_color_black, "lv.color", "" } }, @@ -66,6 +68,7 @@ const be_ntv_func_def_t lv_func[] = { { "color_hex3", { (const void*) &lv_color_hex3, "lv.color", "i" } }, { "color_hsv_to_rgb", { (const void*) &lv_color_hsv_to_rgb, "lv.color", "iii" } }, { "color_lighten", { (const void*) &lv_color_lighten, "lv.color", "(lv.color)i" } }, + { "color_luminance", { (const void*) &lv_color_luminance, "i", "(lv.color)" } }, { "color_make", { (const void*) &lv_color_make, "lv.color", "iii" } }, { "color_mix", { (const void*) &lv_color_mix, "lv.color", "(lv.color)(lv.color)i" } }, { "color_mix32", { (const void*) &lv_color_mix32, "i", "ii" } }, @@ -89,6 +92,7 @@ const be_ntv_func_def_t lv_func[] = { { "draw_dispatch_layer", { (const void*) &lv_draw_dispatch_layer, "b", "(lv.display)(lv.layer)" } }, { "draw_dispatch_request", { (const void*) &lv_draw_dispatch_request, "", "" } }, { "draw_dispatch_wait_for_request", { (const void*) &lv_draw_dispatch_wait_for_request, "", "" } }, + { "draw_get_unit_count", { (const void*) &lv_draw_get_unit_count, "i", "" } }, { "draw_init", { (const void*) &lv_draw_init, "", "" } }, { "draw_label", { (const void*) &lv_draw_label, "", "(lv.layer)(lv.draw_label_dsc)(lv.area)" } }, { "draw_label_dsc_init", { (const void*) &lv_draw_label_dsc_init, "", "(lv.draw_label_dsc)" } }, @@ -99,6 +103,7 @@ const be_ntv_func_def_t lv_func[] = { { "draw_line_dsc_init", { (const void*) &lv_draw_line_dsc_init, "", "(lv.draw_line_dsc)" } }, { "draw_rect", { (const void*) &lv_draw_rect, "", "(lv.layer)(lv.draw_rect_dsc)(lv.area)" } }, { "draw_rect_dsc_init", { (const void*) &lv_draw_rect_dsc_init, "", "(lv.draw_rect_dsc)" } }, + { "draw_wait_for_finish", { (const void*) &lv_draw_wait_for_finish, "", "" } }, { "event_dsc_get_cb", { (const void*) &lv_event_dsc_get_cb, "lv.event_cb", "(lv.event_dsc)" } }, { "event_dsc_get_user_data", { (const void*) &lv_event_dsc_get_user_data, "c", "(lv.event_dsc)" } }, { "event_register_id", { (const void*) &lv_event_register_id, "i", "" } }, @@ -126,6 +131,7 @@ const be_ntv_func_def_t lv_func[] = { { "obj_delete_anim_completed_cb", { (const void*) &lv_obj_delete_anim_completed_cb, "", "(lv.anim)" } }, { "obj_enable_style_refresh", { (const void*) &lv_obj_enable_style_refresh, "", "b" } }, { "obj_event_base", { (const void*) &lv_obj_event_base, "i", "(lv.obj_class)(lv.event)" } }, + { "obj_id_compare", { (const void*) &lv_obj_id_compare, "i", ".." } }, { "obj_redraw", { (const void*) &lv_obj_redraw, "", "(lv.layer)(lv.obj)" } }, { "obj_report_style_change", { (const void*) &lv_obj_report_style_change, "", "(lv.style)" } }, { "obj_style_get_selector_part", { (const void*) &lv_obj_style_get_selector_part, "i", "i" } }, @@ -153,8 +159,10 @@ const be_ntv_func_def_t lv_func[] = { { "span_stack_deinit", { (const void*) &lv_span_stack_deinit, "", "" } }, { "span_stack_init", { (const void*) &lv_span_stack_init, "", "" } }, { "style_get_num_custom_props", { (const void*) &lv_style_get_num_custom_props, "i", "" } }, + { "style_get_prop_group", { (const void*) &lv_style_get_prop_group, "i", "i" } }, { "style_prop_get_default", { (const void*) &lv_style_prop_get_default, "i", "i" } }, { "style_prop_has_flag", { (const void*) &lv_style_prop_has_flag, "b", "ii" } }, + { "style_prop_lookup_flags", { (const void*) &lv_style_prop_lookup_flags, "i", "i" } }, { "style_register_prop", { (const void*) &lv_style_register_prop, "i", "i" } }, { "task_handler", { (const void*) &lv_task_handler, "i", "" } }, { "text_get_size", { (const void*) &lv_text_get_size, "", "cs(lv.font)iiii" } }, @@ -223,6 +231,9 @@ const be_const_member_t lv0_constants[] = { { "BAR_MODE_NORMAL", be_cconst_int(LV_BAR_MODE_NORMAL) }, { "BAR_MODE_RANGE", be_cconst_int(LV_BAR_MODE_RANGE) }, { "BAR_MODE_SYMMETRICAL", be_cconst_int(LV_BAR_MODE_SYMMETRICAL) }, + { "BAR_ORIENTATION_AUTO", be_cconst_int(LV_BAR_ORIENTATION_AUTO) }, + { "BAR_ORIENTATION_HORIZONTAL", be_cconst_int(LV_BAR_ORIENTATION_HORIZONTAL) }, + { "BAR_ORIENTATION_VERTICAL", be_cconst_int(LV_BAR_ORIENTATION_VERTICAL) }, { "BASE_DIR_AUTO", be_cconst_int(LV_BASE_DIR_AUTO) }, { "BASE_DIR_LTR", be_cconst_int(LV_BASE_DIR_LTR) }, { "BASE_DIR_NEUTRAL", be_cconst_int(LV_BASE_DIR_NEUTRAL) }, @@ -259,6 +270,10 @@ const be_const_member_t lv0_constants[] = { { "BUTTONMATRIX_CTRL_HIDDEN", be_cconst_int(LV_BUTTONMATRIX_CTRL_HIDDEN) }, { "BUTTONMATRIX_CTRL_NO_REPEAT", be_cconst_int(LV_BUTTONMATRIX_CTRL_NO_REPEAT) }, { "BUTTONMATRIX_CTRL_POPOVER", be_cconst_int(LV_BUTTONMATRIX_CTRL_POPOVER) }, + { "BUTTONMATRIX_CTRL_RESERVED_1", be_cconst_int(LV_BUTTONMATRIX_CTRL_RESERVED_1) }, + { "BUTTONMATRIX_CTRL_RESERVED_2", be_cconst_int(LV_BUTTONMATRIX_CTRL_RESERVED_2) }, + { "BUTTONMATRIX_CTRL_RESERVED_3", be_cconst_int(LV_BUTTONMATRIX_CTRL_RESERVED_3) }, + { "CHART_AXIS_LAST", be_cconst_int(LV_CHART_AXIS_LAST) }, { "CHART_AXIS_PRIMARY_X", be_cconst_int(LV_CHART_AXIS_PRIMARY_X) }, { "CHART_AXIS_PRIMARY_Y", be_cconst_int(LV_CHART_AXIS_PRIMARY_Y) }, { "CHART_AXIS_SECONDARY_X", be_cconst_int(LV_CHART_AXIS_SECONDARY_X) }, @@ -279,6 +294,7 @@ const be_const_member_t lv0_constants[] = { { "COLOR_FORMAT_A2", be_cconst_int(LV_COLOR_FORMAT_A2) }, { "COLOR_FORMAT_A4", be_cconst_int(LV_COLOR_FORMAT_A4) }, { "COLOR_FORMAT_A8", be_cconst_int(LV_COLOR_FORMAT_A8) }, + { "COLOR_FORMAT_AL88", be_cconst_int(LV_COLOR_FORMAT_AL88) }, { "COLOR_FORMAT_ARGB8565", be_cconst_int(LV_COLOR_FORMAT_ARGB8565) }, { "COLOR_FORMAT_ARGB8888", be_cconst_int(LV_COLOR_FORMAT_ARGB8888) }, { "COLOR_FORMAT_I1", be_cconst_int(LV_COLOR_FORMAT_I1) }, @@ -360,6 +376,7 @@ const be_const_member_t lv0_constants[] = { { "DRAW_TASK_TYPE_LINE", be_cconst_int(LV_DRAW_TASK_TYPE_LINE) }, { "DRAW_TASK_TYPE_MASK_BITMAP", be_cconst_int(LV_DRAW_TASK_TYPE_MASK_BITMAP) }, { "DRAW_TASK_TYPE_MASK_RECTANGLE", be_cconst_int(LV_DRAW_TASK_TYPE_MASK_RECTANGLE) }, + { "DRAW_TASK_TYPE_NONE", be_cconst_int(LV_DRAW_TASK_TYPE_NONE) }, { "DRAW_TASK_TYPE_TRIANGLE", be_cconst_int(LV_DRAW_TASK_TYPE_TRIANGLE) }, { "DRAW_TASK_TYPE_VECTOR", be_cconst_int(LV_DRAW_TASK_TYPE_VECTOR) }, { "DROPDOWN_POS_LAST", be_cconst_int(LV_DROPDOWN_POS_LAST) }, @@ -389,10 +406,13 @@ const be_const_member_t lv0_constants[] = { { "EVENT_GESTURE", be_cconst_int(LV_EVENT_GESTURE) }, { "EVENT_GET_SELF_SIZE", be_cconst_int(LV_EVENT_GET_SELF_SIZE) }, { "EVENT_HIT_TEST", be_cconst_int(LV_EVENT_HIT_TEST) }, + { "EVENT_HOVER_LEAVE", be_cconst_int(LV_EVENT_HOVER_LEAVE) }, + { "EVENT_HOVER_OVER", be_cconst_int(LV_EVENT_HOVER_OVER) }, { "EVENT_INDEV_RESET", be_cconst_int(LV_EVENT_INDEV_RESET) }, { "EVENT_INSERT", be_cconst_int(LV_EVENT_INSERT) }, { "EVENT_INVALIDATE_AREA", be_cconst_int(LV_EVENT_INVALIDATE_AREA) }, { "EVENT_KEY", be_cconst_int(LV_EVENT_KEY) }, + { "EVENT_LAST", be_cconst_int(LV_EVENT_LAST) }, { "EVENT_LAYOUT_CHANGED", be_cconst_int(LV_EVENT_LAYOUT_CHANGED) }, { "EVENT_LEAVE", be_cconst_int(LV_EVENT_LEAVE) }, { "EVENT_LONG_PRESSED", be_cconst_int(LV_EVENT_LONG_PRESSED) }, @@ -460,9 +480,15 @@ const be_const_member_t lv0_constants[] = { { "FT_FONT_STYLE_BOLD", be_cconst_int(FT_FONT_STYLE_BOLD) }, { "FT_FONT_STYLE_ITALIC", be_cconst_int(FT_FONT_STYLE_ITALIC) }, { "FT_FONT_STYLE_NORMAL", be_cconst_int(FT_FONT_STYLE_NORMAL) }, + { "GRAD_DIR_CONICAL", be_cconst_int(LV_GRAD_DIR_CONICAL) }, { "GRAD_DIR_HOR", be_cconst_int(LV_GRAD_DIR_HOR) }, + { "GRAD_DIR_LINEAR", be_cconst_int(LV_GRAD_DIR_LINEAR) }, { "GRAD_DIR_NONE", be_cconst_int(LV_GRAD_DIR_NONE) }, + { "GRAD_DIR_RADIAL", be_cconst_int(LV_GRAD_DIR_RADIAL) }, { "GRAD_DIR_VER", be_cconst_int(LV_GRAD_DIR_VER) }, + { "GRAD_EXTEND_PAD", be_cconst_int(LV_GRAD_EXTEND_PAD) }, + { "GRAD_EXTEND_REFLECT", be_cconst_int(LV_GRAD_EXTEND_REFLECT) }, + { "GRAD_EXTEND_REPEAT", be_cconst_int(LV_GRAD_EXTEND_REPEAT) }, { "GRID_ALIGN_CENTER", be_cconst_int(LV_GRID_ALIGN_CENTER) }, { "GRID_ALIGN_END", be_cconst_int(LV_GRID_ALIGN_END) }, { "GRID_ALIGN_SPACE_AROUND", be_cconst_int(LV_GRID_ALIGN_SPACE_AROUND) }, @@ -479,8 +505,10 @@ const be_const_member_t lv0_constants[] = { { "IMAGEBUTTON_STATE_CHECKED_PRESSED", be_cconst_int(LV_IMAGEBUTTON_STATE_CHECKED_PRESSED) }, { "IMAGEBUTTON_STATE_CHECKED_RELEASED", be_cconst_int(LV_IMAGEBUTTON_STATE_CHECKED_RELEASED) }, { "IMAGEBUTTON_STATE_DISABLED", be_cconst_int(LV_IMAGEBUTTON_STATE_DISABLED) }, + { "IMAGEBUTTON_STATE_NUM", be_cconst_int(LV_IMAGEBUTTON_STATE_NUM) }, { "IMAGEBUTTON_STATE_PRESSED", be_cconst_int(LV_IMAGEBUTTON_STATE_PRESSED) }, { "IMAGEBUTTON_STATE_RELEASED", be_cconst_int(LV_IMAGEBUTTON_STATE_RELEASED) }, + { "IMAGE_ALIGN_AUTO_TRANSFORM", be_cconst_int(LV_IMAGE_ALIGN_AUTO_TRANSFORM) }, { "IMAGE_ALIGN_BOTTOM_LEFT", be_cconst_int(LV_IMAGE_ALIGN_BOTTOM_LEFT) }, { "IMAGE_ALIGN_BOTTOM_MID", be_cconst_int(LV_IMAGE_ALIGN_BOTTOM_MID) }, { "IMAGE_ALIGN_BOTTOM_RIGHT", be_cconst_int(LV_IMAGE_ALIGN_BOTTOM_RIGHT) }, @@ -548,6 +576,7 @@ const be_const_member_t lv0_constants[] = { { "LAYER_TYPE_TRANSFORM", be_cconst_int(LV_LAYER_TYPE_TRANSFORM) }, { "LAYOUT_FLEX", be_cconst_int(LV_LAYOUT_FLEX) }, { "LAYOUT_GRID", be_cconst_int(LV_LAYOUT_GRID) }, + { "LAYOUT_LAST", be_cconst_int(LV_LAYOUT_LAST) }, { "LAYOUT_NONE", be_cconst_int(LV_LAYOUT_NONE) }, { "LOG_LEVEL_ERROR", be_cconst_int(LV_LOG_LEVEL_ERROR) }, { "LOG_LEVEL_INFO", be_cconst_int(LV_LOG_LEVEL_INFO) }, @@ -629,6 +658,7 @@ const be_const_member_t lv0_constants[] = { { "PALETTE_GREEN", be_cconst_int(LV_PALETTE_GREEN) }, { "PALETTE_GREY", be_cconst_int(LV_PALETTE_GREY) }, { "PALETTE_INDIGO", be_cconst_int(LV_PALETTE_INDIGO) }, + { "PALETTE_LAST", be_cconst_int(LV_PALETTE_LAST) }, { "PALETTE_LIGHT_BLUE", be_cconst_int(LV_PALETTE_LIGHT_BLUE) }, { "PALETTE_LIGHT_GREEN", be_cconst_int(LV_PALETTE_LIGHT_GREEN) }, { "PALETTE_LIME", be_cconst_int(LV_PALETTE_LIME) }, @@ -662,6 +692,7 @@ const be_const_member_t lv0_constants[] = { { "SCALE_MAJOR_TICK_EVERY_DEFAULT", be_cconst_int(LV_SCALE_MAJOR_TICK_EVERY_DEFAULT) }, { "SCALE_MODE_HORIZONTAL_BOTTOM", be_cconst_int(LV_SCALE_MODE_HORIZONTAL_BOTTOM) }, { "SCALE_MODE_HORIZONTAL_TOP", be_cconst_int(LV_SCALE_MODE_HORIZONTAL_TOP) }, + { "SCALE_MODE_LAST", be_cconst_int(LV_SCALE_MODE_LAST) }, { "SCALE_MODE_ROUND_INNER", be_cconst_int(LV_SCALE_MODE_ROUND_INNER) }, { "SCALE_MODE_ROUND_OUTER", be_cconst_int(LV_SCALE_MODE_ROUND_OUTER) }, { "SCALE_MODE_VERTICAL_LEFT", be_cconst_int(LV_SCALE_MODE_VERTICAL_LEFT) }, @@ -699,8 +730,10 @@ const be_const_member_t lv0_constants[] = { { "SPAN_MODE_BREAK", be_cconst_int(LV_SPAN_MODE_BREAK) }, { "SPAN_MODE_EXPAND", be_cconst_int(LV_SPAN_MODE_EXPAND) }, { "SPAN_MODE_FIXED", be_cconst_int(LV_SPAN_MODE_FIXED) }, + { "SPAN_MODE_LAST", be_cconst_int(LV_SPAN_MODE_LAST) }, { "SPAN_OVERFLOW_CLIP", be_cconst_int(LV_SPAN_OVERFLOW_CLIP) }, { "SPAN_OVERFLOW_ELLIPSIS", be_cconst_int(LV_SPAN_OVERFLOW_ELLIPSIS) }, + { "SPAN_OVERFLOW_LAST", be_cconst_int(LV_SPAN_OVERFLOW_LAST) }, { "STATE_ANY", be_cconst_int(LV_STATE_ANY) }, { "STATE_CHECKED", be_cconst_int(LV_STATE_CHECKED) }, { "STATE_DEFAULT", be_cconst_int(LV_STATE_DEFAULT) }, @@ -772,6 +805,7 @@ const be_const_member_t lv0_constants[] = { { "STYLE_IMG_OPA", be_cconst_int(LV_STYLE_IMAGE_OPA) }, { "STYLE_IMG_RECOLOR", be_cconst_int(LV_STYLE_IMAGE_RECOLOR) }, { "STYLE_IMG_RECOLOR_OPA", be_cconst_int(LV_STYLE_IMAGE_RECOLOR_OPA) }, + { "STYLE_LAST_BUILT_IN_PROP", be_cconst_int(LV_STYLE_LAST_BUILT_IN_PROP) }, { "STYLE_LAYOUT", be_cconst_int(LV_STYLE_LAYOUT) }, { "STYLE_LENGTH", be_cconst_int(LV_STYLE_LENGTH) }, { "STYLE_LINE_COLOR", be_cconst_int(LV_STYLE_LINE_COLOR) }, @@ -788,6 +822,7 @@ const be_const_member_t lv0_constants[] = { { "STYLE_MAX_WIDTH", be_cconst_int(LV_STYLE_MAX_WIDTH) }, { "STYLE_MIN_HEIGHT", be_cconst_int(LV_STYLE_MIN_HEIGHT) }, { "STYLE_MIN_WIDTH", be_cconst_int(LV_STYLE_MIN_WIDTH) }, + { "STYLE_NUM_BUILT_IN_PROPS", be_cconst_int(LV_STYLE_NUM_BUILT_IN_PROPS) }, { "STYLE_OPA", be_cconst_int(LV_STYLE_OPA) }, { "STYLE_OPA_LAYERED", be_cconst_int(LV_STYLE_OPA_LAYERED) }, { "STYLE_OUTLINE_COLOR", be_cconst_int(LV_STYLE_OUTLINE_COLOR) }, @@ -801,6 +836,7 @@ const be_const_member_t lv0_constants[] = { { "STYLE_PAD_ROW", be_cconst_int(LV_STYLE_PAD_ROW) }, { "STYLE_PAD_TOP", be_cconst_int(LV_STYLE_PAD_TOP) }, { "STYLE_PROP_ANY", be_cconst_int(LV_STYLE_PROP_ANY) }, + { "STYLE_PROP_CONST", be_cconst_int(LV_STYLE_PROP_CONST) }, { "STYLE_PROP_INV", be_cconst_int(LV_STYLE_PROP_INV) }, { "STYLE_RADIUS", be_cconst_int(LV_STYLE_RADIUS) }, { "STYLE_RES_FOUND", be_cconst_int(LV_STYLE_RES_FOUND) }, @@ -814,6 +850,10 @@ const be_const_member_t lv0_constants[] = { { "STYLE_SHADOW_OPA", be_cconst_int(LV_STYLE_SHADOW_OPA) }, { "STYLE_SHADOW_SPREAD", be_cconst_int(LV_STYLE_SHADOW_SPREAD) }, { "STYLE_SHADOW_WIDTH", be_cconst_int(LV_STYLE_SHADOW_WIDTH) }, + { "STYLE_STATE_CMP_DIFF_DRAW_PAD", be_cconst_int(LV_STYLE_STATE_CMP_DIFF_DRAW_PAD) }, + { "STYLE_STATE_CMP_DIFF_LAYOUT", be_cconst_int(LV_STYLE_STATE_CMP_DIFF_LAYOUT) }, + { "STYLE_STATE_CMP_DIFF_REDRAW", be_cconst_int(LV_STYLE_STATE_CMP_DIFF_REDRAW) }, + { "STYLE_STATE_CMP_SAME", be_cconst_int(LV_STYLE_STATE_CMP_SAME) }, { "STYLE_TEXT_ALIGN", be_cconst_int(LV_STYLE_TEXT_ALIGN) }, { "STYLE_TEXT_COLOR", be_cconst_int(LV_STYLE_TEXT_COLOR) }, { "STYLE_TEXT_DECOR", be_cconst_int(LV_STYLE_TEXT_DECOR) }, @@ -911,6 +951,7 @@ const be_const_member_t lv0_constants[] = { { "TEXT_DECOR_NONE", be_cconst_int(LV_TEXT_DECOR_NONE) }, { "TEXT_DECOR_STRIKETHROUGH", be_cconst_int(LV_TEXT_DECOR_STRIKETHROUGH) }, { "TEXT_DECOR_UNDERLINE", be_cconst_int(LV_TEXT_DECOR_UNDERLINE) }, + { "TEXT_FLAG_BREAK_ALL", be_cconst_int(LV_TEXT_FLAG_BREAK_ALL) }, { "TEXT_FLAG_EXPAND", be_cconst_int(LV_TEXT_FLAG_EXPAND) }, { "TEXT_FLAG_FIT", be_cconst_int(LV_TEXT_FLAG_FIT) }, { "TEXT_FLAG_NONE", be_cconst_int(LV_TEXT_FLAG_NONE) }, diff --git a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_enum.h b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_enum.h index de79bdd39..b2d70de4f 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_enum.h +++ b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_enum.h @@ -259,7 +259,6 @@ LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE_RECURSIVE -// File: ../../lvgl/src/core/lv_obj_property.h // File: ../../lvgl/src/core/lv_obj_scroll.h LV_SCROLLBAR_MODE_OFF LV_SCROLLBAR_MODE_ON @@ -271,6 +270,10 @@ LV_SCROLL_SNAP_START LV_SCROLL_SNAP_END LV_SCROLL_SNAP_CENTER // File: ../../lvgl/src/core/lv_obj_style.h +LV_STYLE_STATE_CMP_SAME +LV_STYLE_STATE_CMP_DIFF_REDRAW +LV_STYLE_STATE_CMP_DIFF_DRAW_PAD +LV_STYLE_STATE_CMP_DIFF_LAYOUT // File: ../../lvgl/src/core/lv_obj_style_gen.h // File: ../../lvgl/src/core/lv_obj_tree.h @@ -306,6 +309,7 @@ LV_SCR_LOAD_ANIM_OUT_TOP LV_SCR_LOAD_ANIM_OUT_BOTTOM // File: ../../lvgl/src/draw/lv_draw.h +LV_DRAW_TASK_TYPE_NONE LV_DRAW_TASK_TYPE_FILL LV_DRAW_TASK_TYPE_BORDER LV_DRAW_TASK_TYPE_BOX_SHADOW @@ -401,6 +405,7 @@ LV_GRID_TEMPLATE_LAST LV_LAYOUT_NONE LV_LAYOUT_FLEX LV_LAYOUT_GRID +LV_LAYOUT_LAST // File: ../../lvgl/src/misc/lv_anim.h LV_ANIM_OFF LV_ANIM_ON @@ -441,9 +446,9 @@ LV_DIR_HOR LV_DIR_VER LV_DIR_ALL -LV_SIZE_CONTENT LV_COORD_MAX LV_COORD_MIN +LV_SIZE_CONTENT // File: ../../lvgl/src/misc/lv_array.h // File: ../../lvgl/src/misc/lv_assert.h // File: ../../lvgl/src/misc/lv_async.h @@ -481,6 +486,7 @@ LV_COLOR_FORMAT_A8 LV_COLOR_FORMAT_RGB565 LV_COLOR_FORMAT_ARGB8565 LV_COLOR_FORMAT_RGB565A8 +LV_COLOR_FORMAT_AL88 LV_COLOR_FORMAT_RGB888 LV_COLOR_FORMAT_ARGB8888 LV_COLOR_FORMAT_XRGB8888 @@ -498,6 +504,9 @@ LV_COLOR_FORMAT_YUY2 LV_COLOR_FORMAT_UYVY LV_COLOR_FORMAT_YUV_END LV_COLOR_FORMAT_NATIVE +LV_COLOR_FORMAT_NATIVE_WITH_ALPHA +LV_COLOR_FORMAT_NATIVE +LV_COLOR_FORMAT_NATIVE_WITH_ALPHA LV_COLOR_FORMAT_NATIVE LV_COLOR_FORMAT_NATIVE_WITH_ALPHA LV_COLOR_FORMAT_NATIVE @@ -529,6 +538,8 @@ LV_EVENT_DEFOCUSED LV_EVENT_LEAVE LV_EVENT_HIT_TEST LV_EVENT_INDEV_RESET +LV_EVENT_HOVER_OVER +LV_EVENT_HOVER_LEAVE LV_EVENT_COVER_CHECK LV_EVENT_REFR_EXT_DRAW_SIZE LV_EVENT_DRAW_MAIN_BEGIN @@ -569,6 +580,7 @@ LV_EVENT_FLUSH_FINISH LV_EVENT_FLUSH_WAIT_START LV_EVENT_FLUSH_WAIT_FINISH LV_EVENT_VSYNC +LV_EVENT_LAST LV_EVENT_PREPROCESS // File: ../../lvgl/src/misc/lv_fs.h @@ -603,6 +615,7 @@ LV_LOG_LEVEL_USER LV_LOG_LEVEL_NONE // File: ../../lvgl/src/misc/lv_lru.h // File: ../../lvgl/src/misc/lv_math.h +// File: ../../lvgl/src/misc/lv_matrix.h // File: ../../lvgl/src/misc/lv_palette.h LV_PALETTE_RED LV_PALETTE_PINK @@ -623,6 +636,7 @@ LV_PALETTE_DEEP_ORANGE LV_PALETTE_BROWN LV_PALETTE_BLUE_GREY LV_PALETTE_GREY +LV_PALETTE_LAST LV_PALETTE_NONE // File: ../../lvgl/src/misc/lv_profiler.h @@ -651,6 +665,13 @@ LV_BORDER_SIDE_INTERNAL LV_GRAD_DIR_NONE LV_GRAD_DIR_VER LV_GRAD_DIR_HOR +LV_GRAD_DIR_LINEAR +LV_GRAD_DIR_RADIAL +LV_GRAD_DIR_CONICAL + +LV_GRAD_EXTEND_PAD +LV_GRAD_EXTEND_REPEAT +LV_GRAD_EXTEND_REFLECT LV_STYLE_PROP_INV LV_STYLE_WIDTH @@ -763,7 +784,10 @@ LV_STYLE_GRID_CELL_X_ALIGN LV_STYLE_GRID_CELL_ROW_POS LV_STYLE_GRID_CELL_ROW_SPAN LV_STYLE_GRID_CELL_Y_ALIGN +LV_STYLE_LAST_BUILT_IN_PROP +LV_STYLE_NUM_BUILT_IN_PROPS LV_STYLE_PROP_ANY +LV_STYLE_PROP_CONST LV_STYLE_RES_NOT_FOUND LV_STYLE_RES_FOUND @@ -774,6 +798,7 @@ LV_SCALE_NONE LV_TEXT_FLAG_NONE LV_TEXT_FLAG_EXPAND LV_TEXT_FLAG_FIT +LV_TEXT_FLAG_BREAK_ALL LV_TEXT_ALIGN_AUTO LV_TEXT_ALIGN_LEFT @@ -798,6 +823,9 @@ LV_ARC_MODE_REVERSE LV_BAR_MODE_NORMAL LV_BAR_MODE_SYMMETRICAL LV_BAR_MODE_RANGE +LV_BAR_ORIENTATION_AUTO +LV_BAR_ORIENTATION_HORIZONTAL +LV_BAR_ORIENTATION_VERTICAL // File: ../../lvgl/src/widgets/button/lv_button.h // File: ../../lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h LV_BUTTONMATRIX_CTRL_HIDDEN @@ -807,11 +835,15 @@ LV_BUTTONMATRIX_CTRL_CHECKABLE LV_BUTTONMATRIX_CTRL_CHECKED LV_BUTTONMATRIX_CTRL_CLICK_TRIG LV_BUTTONMATRIX_CTRL_POPOVER +LV_BUTTONMATRIX_CTRL_RESERVED_1 +LV_BUTTONMATRIX_CTRL_RESERVED_2 +LV_BUTTONMATRIX_CTRL_RESERVED_3 LV_BUTTONMATRIX_CTRL_CUSTOM_1 LV_BUTTONMATRIX_CTRL_CUSTOM_2 LV_BUTTONMATRIX_BUTTON_NONE // File: ../../lvgl/src/widgets/calendar/lv_calendar.h +// File: ../../lvgl/src/widgets/calendar/lv_calendar_chinese.h // File: ../../lvgl/src/widgets/calendar/lv_calendar_header_arrow.h // File: ../../lvgl/src/widgets/calendar/lv_calendar_header_dropdown.h // File: ../../lvgl/src/widgets/canvas/lv_canvas.h @@ -828,6 +860,7 @@ LV_CHART_AXIS_PRIMARY_Y LV_CHART_AXIS_SECONDARY_Y LV_CHART_AXIS_PRIMARY_X LV_CHART_AXIS_SECONDARY_X +LV_CHART_AXIS_LAST LV_CHART_POINT_NONE // File: ../../lvgl/src/widgets/checkbox/lv_checkbox.h // File: ../../lvgl/src/widgets/dropdown/lv_dropdown.h @@ -843,6 +876,7 @@ LV_IMAGE_ALIGN_BOTTOM_RIGHT LV_IMAGE_ALIGN_LEFT_MID LV_IMAGE_ALIGN_RIGHT_MID LV_IMAGE_ALIGN_CENTER +LV_IMAGE_ALIGN_AUTO_TRANSFORM LV_IMAGE_ALIGN_STRETCH LV_IMAGE_ALIGN_TILE @@ -853,6 +887,7 @@ LV_IMAGEBUTTON_STATE_DISABLED LV_IMAGEBUTTON_STATE_CHECKED_RELEASED LV_IMAGEBUTTON_STATE_CHECKED_PRESSED LV_IMAGEBUTTON_STATE_CHECKED_DISABLED +LV_IMAGEBUTTON_STATE_NUM // File: ../../lvgl/src/widgets/keyboard/lv_keyboard.h LV_KEYBOARD_MODE_TEXT_LOWER @@ -895,6 +930,7 @@ LV_SCALE_MODE_VERTICAL_LEFT LV_SCALE_MODE_VERTICAL_RIGHT LV_SCALE_MODE_ROUND_INNER LV_SCALE_MODE_ROUND_OUTER +LV_SCALE_MODE_LAST LV_SCALE_TOTAL_TICK_COUNT_DEFAULT LV_SCALE_MAJOR_TICK_EVERY_DEFAULT LV_SCALE_LABEL_ENABLED_DEFAULT @@ -905,10 +941,12 @@ LV_SLIDER_MODE_RANGE // File: ../../lvgl/src/widgets/span/lv_span.h LV_SPAN_OVERFLOW_CLIP LV_SPAN_OVERFLOW_ELLIPSIS +LV_SPAN_OVERFLOW_LAST LV_SPAN_MODE_FIXED LV_SPAN_MODE_EXPAND LV_SPAN_MODE_BREAK +LV_SPAN_MODE_LAST // File: ../../lvgl/src/widgets/spinbox/lv_spinbox.h // File: ../../lvgl/src/widgets/spinner/lv_spinner.h // File: ../../lvgl/src/widgets/switch/lv_switch.h diff --git a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h index db4df5776..401402cce 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h +++ b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h @@ -52,6 +52,7 @@ lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group) bool lv_group_get_editing(const lv_group_t * group) bool lv_group_get_wrap(lv_group_t * group) uint32_t lv_group_get_obj_count(lv_group_t * group) +lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index) uint32_t lv_group_get_count(void) lv_group_t * lv_group_by_index(uint32_t index) @@ -63,20 +64,25 @@ void lv_obj_update_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v) void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) void lv_obj_remove_state(lv_obj_t * obj, lv_state_t state) void lv_obj_set_state(lv_obj_t * obj, lv_state_t state, bool v) -static inline void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) +void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f) bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f) lv_state_t lv_obj_get_state(const lv_obj_t * obj) bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state) lv_group_t * lv_obj_get_group(const lv_obj_t * obj) -static inline void * lv_obj_get_user_data(lv_obj_t * obj) +void * lv_obj_get_user_data(lv_obj_t * obj) void lv_obj_allocate_spec_attr(lv_obj_t * obj) bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p) bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p) const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj) bool lv_obj_is_valid(const lv_obj_t * obj) +void lv_obj_null_on_delete(lv_obj_t ** obj_ptr) +void lv_obj_set_id(lv_obj_t * obj, void * id) +void * lv_obj_get_id(const lv_obj_t * obj) +lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id) void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj) void lv_obj_free_id(lv_obj_t * obj) +int lv_obj_id_compare(const void * id1, const void * id2) const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len) void lv_objid_builtin_destroy(void) @@ -87,12 +93,12 @@ bool lv_obj_is_editable(lv_obj_t * obj) bool lv_obj_is_group_def(lv_obj_t * obj) // ../../lvgl/src/core/lv_obj_draw.h -void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc) -void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc) -void lv_obj_init_draw_image_dsc(lv_obj_t * obj, uint32_t part, lv_draw_image_dsc_t * draw_dsc) -void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc) -void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc) -int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part) +void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc) +void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc) +void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc) +void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc) +void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc) +int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part) void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) // ../../lvgl/src/core/lv_obj_event.h @@ -137,7 +143,7 @@ void lv_obj_update_layout(const lv_obj_t * obj) void lv_obj_set_align(lv_obj_t * obj, lv_align_t align) void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_ofs, int32_t y_ofs) void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, int32_t x_ofs, int32_t y_ofs) -static inline void lv_obj_center(lv_obj_t * obj) +void lv_obj_center(lv_obj_t * obj) void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * coords) int32_t lv_obj_get_x(const lv_obj_t * obj) int32_t lv_obj_get_x2(const lv_obj_t * obj) @@ -169,8 +175,6 @@ bool lv_obj_hit_test(lv_obj_t * obj, const lv_point_t * point) int32_t lv_clamp_width(int32_t width, int32_t min_width, int32_t max_width, int32_t ref_width) int32_t lv_clamp_height(int32_t height, int32_t min_height, int32_t max_height, int32_t ref_height) -// ../../lvgl/src/core/lv_obj_property.h - // ../../lvgl/src/core/lv_obj_scroll.h void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode) void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir) @@ -213,6 +217,7 @@ bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, l void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, lv_style_selector_t selector) lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value, lv_style_selector_t selector) bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector) +lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v) void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay) void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay) static inline lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector) @@ -226,136 +231,136 @@ static inline void lv_obj_set_style_margin_ver(lv_obj_t * obj, int32_t value, lv static inline void lv_obj_set_style_pad_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) static inline void lv_obj_set_style_size(lv_obj_t * obj, int32_t width, int32_t height, lv_style_selector_t selector) static inline void lv_obj_set_style_transform_scale(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) -static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, lv_part_t part) lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_t part, const char * txt) -static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, lv_part_t part) lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) // ../../lvgl/src/core/lv_obj_style_gen.h -static inline int32_t lv_obj_get_style_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_min_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_max_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_height(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_max_height(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_length(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_x(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_y(const lv_obj_t * obj, uint32_t part) -static inline lv_align_t lv_obj_get_style_align(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_height(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_translate_x(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_scale_x(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_scale_y(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_rotation(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_pivot_x(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_pivot_y(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_skew_x(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_transform_skew_y(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_pad_top(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_pad_bottom(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_pad_right(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_pad_row(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_margin_top(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_margin_bottom(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_margin_left(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_margin_right(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_bg_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_bg_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_bg_opa(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_bg_main_stop(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_bg_grad_stop(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_bg_main_opa(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_bg_grad_opa(const lv_obj_t * obj, uint32_t part) -static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const lv_obj_t * obj, uint32_t part) -static inline const void * lv_obj_get_style_bg_image_src(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_bg_image_opa(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_bg_image_recolor_opa(const lv_obj_t * obj, uint32_t part) -static inline bool lv_obj_get_style_bg_image_tiled(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_border_opa(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_border_width(const lv_obj_t * obj, uint32_t part) -static inline lv_border_side_t lv_obj_get_style_border_side(const lv_obj_t * obj, uint32_t part) -static inline bool lv_obj_get_style_border_post(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_outline_width(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_outline_opa(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_outline_pad(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_shadow_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_shadow_offset_x(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_shadow_offset_y(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_shadow_spread(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_shadow_opa(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_image_opa(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_line_dash_width(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_line_dash_gap(const lv_obj_t * obj, uint32_t part) -static inline bool lv_obj_get_style_line_rounded(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_line_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_line_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_line_opa(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_arc_width(const lv_obj_t * obj, uint32_t part) -static inline bool lv_obj_get_style_arc_rounded(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_arc_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_arc_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_arc_opa(const lv_obj_t * obj, uint32_t part) -static inline const void * lv_obj_get_style_arc_image_src(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_text_color(const lv_obj_t * obj, uint32_t part) -static inline lv_color_t lv_obj_get_style_text_color_filtered(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_text_opa(const lv_obj_t * obj, uint32_t part) -static inline const lv_font_t * lv_obj_get_style_text_font(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_text_line_space(const lv_obj_t * obj, uint32_t part) -static inline lv_text_decor_t lv_obj_get_style_text_decor(const lv_obj_t * obj, uint32_t part) -static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_radius(const lv_obj_t * obj, uint32_t part) -static inline bool lv_obj_get_style_clip_corner(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_opa_layered(const lv_obj_t * obj, uint32_t part) -static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const lv_obj_t * obj, uint32_t part) -static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, uint32_t part) -static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, uint32_t part) -static inline uint32_t lv_obj_get_style_anim_duration(const lv_obj_t * obj, uint32_t part) -static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const lv_obj_t * obj, uint32_t part) -static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const lv_obj_t * obj, uint32_t part) -static inline uint16_t lv_obj_get_style_layout(const lv_obj_t * obj, uint32_t part) -static inline lv_base_dir_t lv_obj_get_style_base_dir(const lv_obj_t * obj, uint32_t part) -static inline const lv_image_dsc_t * lv_obj_get_style_bitmap_mask_src(const lv_obj_t * obj, uint32_t part) -static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, uint32_t part) -static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, uint32_t part) -static inline lv_flex_align_t lv_obj_get_style_flex_main_place(const lv_obj_t * obj, uint32_t part) -static inline lv_flex_align_t lv_obj_get_style_flex_cross_place(const lv_obj_t * obj, uint32_t part) -static inline lv_flex_align_t lv_obj_get_style_flex_track_place(const lv_obj_t * obj, uint32_t part) -static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, uint32_t part) -static inline const int32_t * lv_obj_get_style_grid_column_dsc_array(const lv_obj_t * obj, uint32_t part) -static inline lv_grid_align_t lv_obj_get_style_grid_column_align(const lv_obj_t * obj, uint32_t part) -static inline const int32_t * lv_obj_get_style_grid_row_dsc_array(const lv_obj_t * obj, uint32_t part) -static inline lv_grid_align_t lv_obj_get_style_grid_row_align(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_grid_cell_column_pos(const lv_obj_t * obj, uint32_t part) -static inline lv_grid_align_t lv_obj_get_style_grid_cell_x_align(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_grid_cell_column_span(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_grid_cell_row_pos(const lv_obj_t * obj, uint32_t part) -static inline lv_grid_align_t lv_obj_get_style_grid_cell_y_align(const lv_obj_t * obj, uint32_t part) -static inline int32_t lv_obj_get_style_grid_cell_row_span(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_min_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_max_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_height(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_max_height(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_length(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_x(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_y(const lv_obj_t * obj, lv_part_t part) +static inline lv_align_t lv_obj_get_style_align(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_height(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_translate_x(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_scale_x(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_scale_y(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_rotation(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_pivot_x(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_pivot_y(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_skew_x(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_transform_skew_y(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_pad_top(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_pad_bottom(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_pad_right(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_pad_row(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_margin_top(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_margin_bottom(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_margin_left(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_margin_right(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_bg_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_bg_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_bg_opa(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_bg_main_stop(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_bg_grad_stop(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_bg_main_opa(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_bg_grad_opa(const lv_obj_t * obj, lv_part_t part) +static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const lv_obj_t * obj, lv_part_t part) +static inline const void * lv_obj_get_style_bg_image_src(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_bg_image_opa(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_bg_image_recolor_opa(const lv_obj_t * obj, lv_part_t part) +static inline bool lv_obj_get_style_bg_image_tiled(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_border_opa(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_border_width(const lv_obj_t * obj, lv_part_t part) +static inline lv_border_side_t lv_obj_get_style_border_side(const lv_obj_t * obj, lv_part_t part) +static inline bool lv_obj_get_style_border_post(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_outline_width(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_outline_opa(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_outline_pad(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_shadow_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_shadow_offset_x(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_shadow_offset_y(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_shadow_spread(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_shadow_opa(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_image_opa(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_line_dash_width(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_line_dash_gap(const lv_obj_t * obj, lv_part_t part) +static inline bool lv_obj_get_style_line_rounded(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_line_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_line_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_line_opa(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_arc_width(const lv_obj_t * obj, lv_part_t part) +static inline bool lv_obj_get_style_arc_rounded(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_arc_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_arc_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_arc_opa(const lv_obj_t * obj, lv_part_t part) +static inline const void * lv_obj_get_style_arc_image_src(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_text_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_text_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_text_opa(const lv_obj_t * obj, lv_part_t part) +static inline const lv_font_t * lv_obj_get_style_text_font(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_text_line_space(const lv_obj_t * obj, lv_part_t part) +static inline lv_text_decor_t lv_obj_get_style_text_decor(const lv_obj_t * obj, lv_part_t part) +static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_radius(const lv_obj_t * obj, lv_part_t part) +static inline bool lv_obj_get_style_clip_corner(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_opa_layered(const lv_obj_t * obj, lv_part_t part) +static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, lv_part_t part) +static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, lv_part_t part) +static inline uint32_t lv_obj_get_style_anim_duration(const lv_obj_t * obj, lv_part_t part) +static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const lv_obj_t * obj, lv_part_t part) +static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const lv_obj_t * obj, lv_part_t part) +static inline uint16_t lv_obj_get_style_layout(const lv_obj_t * obj, lv_part_t part) +static inline lv_base_dir_t lv_obj_get_style_base_dir(const lv_obj_t * obj, lv_part_t part) +static inline const void * lv_obj_get_style_bitmap_mask_src(const lv_obj_t * obj, lv_part_t part) +static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, lv_part_t part) +static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, lv_part_t part) +static inline lv_flex_align_t lv_obj_get_style_flex_main_place(const lv_obj_t * obj, lv_part_t part) +static inline lv_flex_align_t lv_obj_get_style_flex_cross_place(const lv_obj_t * obj, lv_part_t part) +static inline lv_flex_align_t lv_obj_get_style_flex_track_place(const lv_obj_t * obj, lv_part_t part) +static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, lv_part_t part) +static inline const int32_t * lv_obj_get_style_grid_column_dsc_array(const lv_obj_t * obj, lv_part_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_column_align(const lv_obj_t * obj, lv_part_t part) +static inline const int32_t * lv_obj_get_style_grid_row_dsc_array(const lv_obj_t * obj, lv_part_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_row_align(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_grid_cell_column_pos(const lv_obj_t * obj, lv_part_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_cell_x_align(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_grid_cell_column_span(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_grid_cell_row_pos(const lv_obj_t * obj, lv_part_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_cell_y_align(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_grid_cell_row_span(const lv_obj_t * obj, lv_part_t part) void lv_obj_set_style_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_min_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_max_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) @@ -449,7 +454,7 @@ void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t void lv_obj_set_style_blend_mode(lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector) void lv_obj_set_style_layout(lv_obj_t * obj, uint16_t value, lv_style_selector_t selector) void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector) -void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const lv_image_dsc_t * value, lv_style_selector_t selector) +void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector) void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector) void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector) void lv_obj_set_style_flex_main_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector) @@ -488,7 +493,7 @@ uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class int32_t lv_obj_get_index(const lv_obj_t * obj) int32_t lv_obj_get_index_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p) void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data) -void lv_obj_dump_tree(lv_obj_t * start_ob) +void lv_obj_dump_tree(lv_obj_t * start_obj) // ../../lvgl/src/core/lv_refr.h void lv_refr_now(lv_display_t * disp) @@ -528,12 +533,12 @@ lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp) lv_obj_t * lv_display_get_layer_top(lv_display_t * disp) lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp) lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp) -void lv_screen_load(struct _lv_obj_t * scr) +void lv_screen_load(struct lv_obj_t * scr) void lv_screen_load_anim(lv_obj_t * scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del) -static inline lv_obj_t * lv_screen_active(void) -static inline lv_obj_t * lv_layer_top(void) -static inline lv_obj_t * lv_layer_sys(void) -static inline lv_obj_t * lv_layer_bottom(void) +lv_obj_t * lv_screen_active(void) +lv_obj_t * lv_layer_top(void) +lv_obj_t * lv_layer_sys(void) +lv_obj_t * lv_layer_bottom(void) void lv_display_add_event_cb(lv_display_t * disp, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data) uint32_t lv_display_get_event_count(lv_display_t * disp) lv_event_dsc_t * lv_display_get_event_dsc(lv_display_t * disp, uint32_t index) @@ -553,10 +558,9 @@ void lv_display_set_driver_data(lv_display_t * disp, void * driver_data) void * lv_display_get_user_data(lv_display_t * disp) void * lv_display_get_driver_data(lv_display_t * disp) lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp) -static inline int32_t lv_dpx(int32_t n) -static inline int32_t lv_display_dpx(const lv_display_t * disp, int32_t n) - -// ../../lvgl/src/display/lv_display_private.h +void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area) +int32_t lv_dpx(int32_t n) +int32_t lv_display_dpx(const lv_display_t * disp, int32_t n) // ../../lvgl/src/draw/lv_draw.h void lv_draw_init(void) @@ -567,12 +571,17 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t) void lv_draw_dispatch(void) bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) void lv_draw_dispatch_wait_for_request(void) +void lv_draw_wait_for_finish(void) void lv_draw_dispatch_request(void) +uint32_t lv_draw_get_unit_count(void) lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id) uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t color_format, const lv_area_t * area) void * lv_draw_layer_alloc_buf(lv_layer_t * layer) void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y) +lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t) +void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t) +void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area) // ../../lvgl/src/draw/lv_draw_arc.h void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc) @@ -614,10 +623,11 @@ lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task) void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * draw_dsc) // ../../lvgl/src/font/lv_font.h -const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t letter, lv_draw_buf_t * draw_buf) +const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) bool lv_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next) +void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc) uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next) -static inline int32_t lv_font_get_line_height(const lv_font_t * font) +int32_t lv_font_get_line_height(const lv_font_t * font) void lv_font_set_kerning(lv_font_t * font, lv_font_kerning_t kerning) // ../../lvgl/src/indev/lv_indev.h @@ -632,7 +642,10 @@ void lv_indev_set_type(lv_indev_t * indev, lv_indev_type_t indev_type) void lv_indev_set_read_cb(lv_indev_t * indev, lv_indev_read_cb_t read_cb) void lv_indev_set_user_data(lv_indev_t * indev, void * user_data) void lv_indev_set_driver_data(lv_indev_t * indev, void * driver_data) -void lv_indev_set_display(lv_indev_t * indev, struct _lv_display_t * disp) +void lv_indev_set_display(lv_indev_t * indev, struct lv_display_t * disp) +void lv_indev_set_long_press_time(lv_indev_t * indev, uint16_t long_press_time) +void lv_indev_set_scroll_limit(lv_indev_t * indev, uint8_t scroll_limit) +void lv_indev_set_scroll_throw(lv_indev_t * indev, uint8_t scroll_throw) lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev) lv_indev_read_cb_t lv_indev_get_read_cb(lv_indev_t * indev) lv_indev_state_t lv_indev_get_state(const lv_indev_t * indev) @@ -640,7 +653,9 @@ lv_group_t * lv_indev_get_group(const lv_indev_t * indev) lv_display_t * lv_indev_get_display(const lv_indev_t * indev) void * lv_indev_get_user_data(const lv_indev_t * indev) void * lv_indev_get_driver_data(const lv_indev_t * indev) +bool lv_indev_get_press_moved(const lv_indev_t * indev) void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj) +void lv_indev_stop_processing(lv_indev_t * indev) void lv_indev_reset_long_press(lv_indev_t * indev) void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj) void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group) @@ -675,7 +690,7 @@ void lv_grid_init(void) void lv_obj_set_grid_dsc_array(lv_obj_t * obj, const int32_t col_dsc[], const int32_t row_dsc[]) void lv_obj_set_grid_align(lv_obj_t * obj, lv_grid_align_t column_align, lv_grid_align_t row_align) void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_align_t column_align, int32_t col_pos, int32_t col_span, lv_grid_align_t row_align, int32_t row_pos, int32_t row_span) -static inline int32_t lv_grid_fr(uint8_t x) +int32_t lv_grid_fr(uint8_t x) // ../../lvgl/src/libs/qrcode/lv_qrcode.h lv_obj_t * lv_qrcode_create(lv_obj_t * parent) @@ -691,50 +706,53 @@ static inline void lv_obj_move_background(lv_obj_t * obj) // ../../lvgl/src/lv_api_map_v9_0.h +// ../../lvgl/src/lv_api_map_v9_1.h + // ../../lvgl/src/misc/lv_anim.h void lv_anim_init(lv_anim_t * a) -static inline void lv_anim_set_var(lv_anim_t * a, void * var) -static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb) -static inline void lv_anim_set_duration(lv_anim_t * a, uint32_t duration) -static inline void lv_anim_set_time(lv_anim_t * a, uint32_t duration) -static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay) -static inline void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end) -static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) -static inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) -static inline void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_cb) -static inline void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb) -static inline void lv_anim_set_completed_cb(lv_anim_t * a, lv_anim_completed_cb_t completed_cb) -static inline void lv_anim_set_deleted_cb(lv_anim_t * a, lv_anim_deleted_cb_t deleted_cb) -static inline void lv_anim_set_playback_duration(lv_anim_t * a, uint32_t duration) -static inline void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration) -static inline void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay) -static inline void lv_anim_set_repeat_count(lv_anim_t * a, uint16_t cnt) -static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay) -static inline void lv_anim_set_early_apply(lv_anim_t * a, bool en) -static inline void lv_anim_set_user_data(lv_anim_t * a, void * user_data) -static inline void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2) +void lv_anim_set_var(lv_anim_t * a, void * var) +void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb) +void lv_anim_set_duration(lv_anim_t * a, uint32_t duration) +void lv_anim_set_time(lv_anim_t * a, uint32_t duration) +void lv_anim_set_delay(lv_anim_t * a, uint32_t delay) +void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end) +void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) +void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_cb) +void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb) +void lv_anim_set_completed_cb(lv_anim_t * a, lv_anim_completed_cb_t completed_cb) +void lv_anim_set_deleted_cb(lv_anim_t * a, lv_anim_deleted_cb_t deleted_cb) +void lv_anim_set_playback_duration(lv_anim_t * a, uint32_t duration) +void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration) +void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay) +void lv_anim_set_repeat_count(lv_anim_t * a, uint32_t cnt) +void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay) +void lv_anim_set_early_apply(lv_anim_t * a, bool en) +void lv_anim_set_user_data(lv_anim_t * a, void * user_data) +void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2) lv_anim_t * lv_anim_start(const lv_anim_t * a) -static inline uint32_t lv_anim_get_delay(const lv_anim_t * a) +uint32_t lv_anim_get_delay(const lv_anim_t * a) uint32_t lv_anim_get_playtime(const lv_anim_t * a) -static inline uint32_t lv_anim_get_time(const lv_anim_t * a) -static inline uint16_t lv_anim_get_repeat_count(const lv_anim_t * a) -static inline void * lv_anim_get_user_data(const lv_anim_t * a) +uint32_t lv_anim_get_time(const lv_anim_t * a) +uint32_t lv_anim_get_repeat_count(const lv_anim_t * a) +void * lv_anim_get_user_data(const lv_anim_t * a) bool lv_anim_delete(void * var, lv_anim_exec_xcb_t exec_cb) void lv_anim_delete_all(void) lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb) lv_timer_t * lv_anim_get_timer(void) -static inline bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) -static inline lv_anim_t * lv_anim_custom_get(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +lv_anim_t * lv_anim_custom_get(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) uint16_t lv_anim_count_running(void) uint32_t lv_anim_speed(uint32_t speed) uint32_t lv_anim_speed_clamped(uint32_t speed, uint32_t min_time, uint32_t max_time) +uint32_t lv_anim_speed_to_time(uint32_t speed, int32_t start, int32_t end) void lv_anim_refr_now(void) // ../../lvgl/src/misc/lv_area.h void lv_area_set(lv_area_t * area_p, int32_t x1, int32_t y1, int32_t x2, int32_t y2) inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src) -static inline int32_t lv_area_get_width(const lv_area_t * area_p) -static inline int32_t lv_area_get_height(const lv_area_t * area_p) +int32_t lv_area_get_width(const lv_area_t * area_p) +int32_t lv_area_get_height(const lv_area_t * area_p) void lv_area_set_width(lv_area_t * area_p, int32_t w) void lv_area_set_height(lv_area_t * area_p, int32_t h) uint32_t lv_area_get_size(const lv_area_t * area_p) @@ -743,45 +761,49 @@ void lv_area_move(lv_area_t * area, int32_t x_ofs, int32_t y_ofs) void lv_area_align(const lv_area_t * base, lv_area_t * to_align, lv_align_t align, int32_t ofs_x, int32_t ofs_y) void lv_point_transform(lv_point_t * point, int32_t angle, int32_t scale_x, int32_t scale_y, const lv_point_t * pivot, bool zoom_first) void lv_point_array_transform(lv_point_t * points, size_t count, int32_t angle, int32_t scale_x, int32_t scale_y, const lv_point_t * pivot, bool zoom_first) -static inline lv_point_t lv_point_from_precise(const lv_point_precise_t * p) -static inline lv_point_precise_t lv_point_to_precise(const lv_point_t * p) -static inline void lv_point_set(lv_point_t * p, int32_t x, int32_t y) -static inline void lv_point_precise_set(lv_point_precise_t * p, lv_value_precise_t x, lv_value_precise_t y) -static inline void lv_point_swap(lv_point_t * p1, lv_point_t * p2) -static inline void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_precise_t * p2) -static inline int32_t lv_pct(int32_t x) -static inline int32_t lv_pct_to_px(int32_t v, int32_t base) +lv_point_t lv_point_from_precise(const lv_point_precise_t * p) +lv_point_precise_t lv_point_to_precise(const lv_point_t * p) +void lv_point_set(lv_point_t * p, int32_t x, int32_t y) +void lv_point_precise_set(lv_point_precise_t * p, lv_value_precise_t x, lv_value_precise_t y) +void lv_point_swap(lv_point_t * p1, lv_point_t * p2) +void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_precise_t * p2) +int32_t lv_pct(int32_t x) +int32_t lv_pct_to_px(int32_t v, int32_t base) // ../../lvgl/src/misc/lv_color.h uint8_t lv_color_format_get_bpp(lv_color_format_t cf) -static inline uint8_t lv_color_format_get_size(lv_color_format_t cf) +uint8_t lv_color_format_get_size(lv_color_format_t cf) bool lv_color_format_has_alpha(lv_color_format_t src_cf) lv_color32_t lv_color_to_32(lv_color_t color, lv_opa_t opa) -static inline uint32_t lv_color_to_int(lv_color_t c) -static inline bool lv_color_eq(lv_color_t c1, lv_color_t c2) -static inline bool lv_color32_eq(lv_color32_t c1, lv_color32_t c2) -static inline lv_color_t lv_color_hex(uint32_t c) -static inline lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b) -static inline lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a) -static inline lv_color_t lv_color_hex3(uint32_t c) +uint32_t lv_color_to_int(lv_color_t c) +bool lv_color_eq(lv_color_t c1, lv_color_t c2) +bool lv_color32_eq(lv_color32_t c1, lv_color32_t c2) +lv_color_t lv_color_hex(uint32_t c) +lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b) +lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +lv_color_t lv_color_hex3(uint32_t c) uint16_t lv_color_to_u16(lv_color_t color) uint32_t lv_color_to_u32(lv_color_t color) -static inline uint16_t lv_color_16_16_mix(uint16_t c1, uint16_t c2, uint8_t mix) +uint16_t lv_color_16_16_mix(uint16_t c1, uint16_t c2, uint8_t mix) lv_color_t lv_color_lighten(lv_color_t c, lv_opa_t lvl) lv_color_t lv_color_darken(lv_color_t c, lv_opa_t lvl) lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v) lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) lv_color_hsv_t lv_color_to_hsv(lv_color_t color) -static inline lv_color_t lv_color_white(void) -static inline lv_color_t lv_color_black(void) -static inline void lv_color_premultiply(lv_color32_t * c) -static inline void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a) +lv_color_t lv_color_white(void) +lv_color_t lv_color_black(void) +void lv_color_premultiply(lv_color32_t * c) +void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a) +uint8_t lv_color_luminance(lv_color_t c) +uint8_t lv_color16_luminance(const lv_color16_t c) +uint8_t lv_color24_luminance(const uint8_t * c) +uint8_t lv_color32_luminance(lv_color32_t c) // ../../lvgl/src/misc/lv_color_op.h -static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix) -static inline lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg) -static inline uint8_t lv_color_brightness(lv_color_t c) -static inline void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t cb) +lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix) +lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg) +uint8_t lv_color_brightness(lv_color_t c) +void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t cb) // ../../lvgl/src/misc/lv_event.h lv_result_t lv_event_send(lv_event_list_t * list, lv_event_t * e, bool preprocess) @@ -820,6 +842,8 @@ void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value) bool lv_style_is_empty(const lv_style_t * style) +static inline uint32_t lv_style_get_prop_group(lv_style_prop_t prop) +uint8_t lv_style_prop_lookup_flags(lv_style_prop_t prop) static inline void lv_style_set_size(lv_style_t * style, int32_t width, int32_t height) static inline void lv_style_set_pad_all(lv_style_t * style, int32_t value) static inline void lv_style_set_pad_hor(lv_style_t * style, int32_t value) @@ -922,7 +946,7 @@ void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t void lv_style_set_blend_mode(lv_style_t * style, lv_blend_mode_t value) void lv_style_set_layout(lv_style_t * style, uint16_t value) void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value) -void lv_style_set_bitmap_mask_src(lv_style_t * style, const lv_image_dsc_t * value) +void lv_style_set_bitmap_mask_src(lv_style_t * style, const void * value) void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value) void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value) void lv_style_set_flex_main_place(lv_style_t * style, lv_flex_align_t value) @@ -943,19 +967,10 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value) // ../../lvgl/src/misc/lv_text.h void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, int32_t letter_space, int32_t line_space, int32_t max_width, lv_text_flag_t flag) int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space) -char * _lv_text_set_text_vfmt(const char * fmt, va_list ap) LV_FORMAT_ATTRIBUTE(1, 0) -uint8_t (*_lv_text_encoded_size)(const char *) -uint32_t (*_lv_text_unicode_to_encoded)(uint32_t) -uint32_t (*_lv_text_encoded_conv_wc)(uint32_t c) -uint32_t (*_lv_text_encoded_next)(const char *, uint32_t *) -uint32_t (*_lv_text_encoded_prev)(const char *, uint32_t *) -uint32_t (*_lv_text_encoded_get_byte_id)(const char *, uint32_t) -uint32_t (*_lv_text_encoded_get_char_id)(const char *, uint32_t) -uint32_t (*_lv_text_get_encoded_length)(const char *) // ../../lvgl/src/misc/lv_timer.h uint32_t lv_timer_handler(void) -static inline uint32_t lv_timer_handler_run_in_period(uint32_t period) +uint32_t lv_timer_handler_run_in_period(uint32_t period) void lv_timer_periodic_handler(void) void lv_timer_handler_set_resume_cb(lv_timer_handler_resume_cb_t cb, void * data) lv_timer_t * lv_timer_create_basic(void) @@ -974,8 +989,8 @@ void lv_timer_enable(bool en) uint32_t lv_timer_get_idle(void) uint32_t lv_timer_get_time_until_next(void) lv_timer_t * lv_timer_get_next(lv_timer_t * timer) -static inline void * lv_timer_get_user_data(lv_timer_t * timer) -static inline bool lv_timer_get_paused(lv_timer_t * timer) +void * lv_timer_get_user_data(lv_timer_t * timer) +bool lv_timer_get_paused(lv_timer_t * timer) // ../../lvgl/src/themes/lv_theme.h lv_theme_t * lv_theme_get_from_obj(lv_obj_t * obj) @@ -1032,11 +1047,13 @@ void lv_bar_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) void lv_bar_set_start_value(lv_obj_t * obj, int32_t start_value, lv_anim_enable_t anim) void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max) void lv_bar_set_mode(lv_obj_t * obj, lv_bar_mode_t mode) +void lv_bar_set_orientation(lv_obj_t * obj, lv_bar_orientation_t orientation) int32_t lv_bar_get_value(const lv_obj_t * obj) int32_t lv_bar_get_start_value(const lv_obj_t * obj) int32_t lv_bar_get_min_value(const lv_obj_t * obj) int32_t lv_bar_get_max_value(const lv_obj_t * obj) lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj) +lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj) bool lv_bar_is_symmetrical(lv_obj_t * obj) // ../../lvgl/src/widgets/button/lv_button.h @@ -1072,6 +1089,11 @@ lv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar size_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar) lv_result_t lv_calendar_get_pressed_date(const lv_obj_t * calendar, lv_calendar_date_t * date) +// ../../lvgl/src/widgets/calendar/lv_calendar_chinese.h +void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en) +const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) +lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian) + // ../../lvgl/src/widgets/calendar/lv_calendar_header_arrow.h lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent) @@ -1093,7 +1115,7 @@ void lv_canvas_copy_buf(lv_obj_t * obj, const lv_area_t * canvas_area, lv_draw_b void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa) void lv_canvas_init_layer(lv_obj_t * canvas, lv_layer_t * layer) void lv_canvas_finish_layer(lv_obj_t * canvas, lv_layer_t * layer) -static inline uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride) +uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride) // ../../lvgl/src/widgets/chart/lv_chart.h lv_obj_t * lv_chart_create(lv_obj_t * parent) @@ -1111,6 +1133,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_cha void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series) void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hide) void lv_chart_set_series_color(lv_obj_t * chart, lv_chart_series_t * series, lv_color_t color) +lv_color_t lv_chart_get_series_color(lv_obj_t * chart, const lv_chart_series_t * series) void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id) lv_chart_series_t * lv_chart_get_series_next(const lv_obj_t * chart, const lv_chart_series_t * ser) lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_dir_t dir) @@ -1200,10 +1223,10 @@ void lv_keyboard_set_popovers(lv_obj_t * kb, bool en) void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[], const lv_buttonmatrix_ctrl_t ctrl_map[]) lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb) lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb) -bool lv_buttonmatrix_get_popovers(const lv_obj_t * obj) -static inline const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) -static inline uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) -static inline const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id) +bool lv_keyboard_get_popovers(const lv_obj_t * obj) +const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) +uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) +const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id) // ../../lvgl/src/widgets/label/lv_label.h lv_obj_t * lv_label_create(lv_obj_t * parent) @@ -1235,7 +1258,12 @@ uint8_t lv_led_get_brightness(const lv_obj_t * obj) // ../../lvgl/src/widgets/line/lv_line.h lv_obj_t * lv_line_create(lv_obj_t * parent) void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num) +void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num) void lv_line_set_y_invert(lv_obj_t * obj, bool en) +const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj) +uint32_t lv_line_get_point_count(lv_obj_t * obj) +bool lv_line_is_point_array_mutable(lv_obj_t * obj) +lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj) bool lv_line_get_y_invert(const lv_obj_t * obj) // ../../lvgl/src/widgets/list/lv_list.h @@ -1306,9 +1334,10 @@ void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int3 void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value) void lv_scale_set_text_src(lv_obj_t * obj, const char * txt_src[]) void lv_scale_set_post_draw(lv_obj_t * obj, bool en) +void lv_scale_set_draw_ticks_on_top(lv_obj_t * obj, bool en) lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj) void lv_scale_section_set_range(lv_scale_section_t * section, int32_t minor_range, int32_t major_range) -void lv_scale_section_set_style(lv_scale_section_t * section, uint32_t part, lv_style_t * section_part_style) +void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style) lv_scale_mode_t lv_scale_get_mode(lv_obj_t * obj) int32_t lv_scale_get_total_tick_count(lv_obj_t * obj) int32_t lv_scale_get_major_tick_every(lv_obj_t * obj) @@ -1319,17 +1348,17 @@ int32_t lv_scale_get_range_max_value(lv_obj_t * obj) // ../../lvgl/src/widgets/slider/lv_slider.h lv_obj_t * lv_slider_create(lv_obj_t * parent) -static inline void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) -static inline void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) -static inline void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max) -static inline void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode) -static inline int32_t lv_slider_get_value(const lv_obj_t * obj) -static inline int32_t lv_slider_get_left_value(const lv_obj_t * obj) -static inline int32_t lv_slider_get_min_value(const lv_obj_t * obj) -static inline int32_t lv_slider_get_max_value(const lv_obj_t * obj) +void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) +void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) +void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max) +void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode) +int32_t lv_slider_get_value(const lv_obj_t * obj) +int32_t lv_slider_get_left_value(const lv_obj_t * obj) +int32_t lv_slider_get_min_value(const lv_obj_t * obj) +int32_t lv_slider_get_max_value(const lv_obj_t * obj) bool lv_slider_is_dragged(const lv_obj_t * obj) -static inline lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider) -static inline bool lv_slider_is_symmetrical(lv_obj_t * obj) +lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider) +bool lv_slider_is_symmetrical(lv_obj_t * obj) // ../../lvgl/src/widgets/span/lv_span.h void lv_span_stack_init(void) @@ -1344,6 +1373,7 @@ void lv_spangroup_set_overflow(lv_obj_t * obj, lv_span_overflow_t overflow) void lv_spangroup_set_indent(lv_obj_t * obj, int32_t indent) void lv_spangroup_set_mode(lv_obj_t * obj, lv_span_mode_t mode) void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines) +lv_style_t * lv_span_get_style(lv_span_t * span) lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id) uint32_t lv_spangroup_get_span_count(const lv_obj_t * obj) lv_text_align_t lv_spangroup_get_align(lv_obj_t * obj) @@ -1390,6 +1420,7 @@ void lv_table_set_column_width(lv_obj_t * obj, uint32_t col_id, int32_t w) void lv_table_add_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl) void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl) void lv_table_set_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, void * user_data) +void lv_table_set_selected_cell(lv_obj_t * obj, uint16_t row, uint16_t col) const char * lv_table_get_cell_value(lv_obj_t * obj, uint32_t row, uint32_t col) uint32_t lv_table_get_row_count(lv_obj_t * obj) uint32_t lv_table_get_column_count(lv_obj_t * obj) @@ -1465,8 +1496,5 @@ bool lv_theme_haspmota_is_inited(void) // ../src/lv_berry.h void be_load_lvgl_classes(bvm *vm) void lv_image_set_tasmota_logo(lv_obj_t * img) -lv_style_t * lv_span_get_style(lv_span_t * span) lv_area_t * lv_bar_get_indic_area(lv_obj_t * bar) -lv_point_t * lv_line_get_points(lv_obj_t * line) -int lv_line_get_points_num(lv_obj_t * line) diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c b/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c index 9279f8839..5f7a712de 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c +++ b/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c @@ -53,10 +53,11 @@ const be_ctypes_structure_t be_lv_gradient_stop = { const be_ctypes_structure_t be_lv_grad_dsc = { 12, /* size in bytes */ - 8, /* number of elements */ + 9, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[8]) { + (const be_ctypes_structure_item_t[9]) { { "dir", 11, 0, 3, ctypes_bf, 0 }, + { "extend", 11, 3, 2, ctypes_bf, 0 }, { "stops_0_color", 0, 0, 0, ctypes_u24, 1 }, { "stops_0_frac", 4, 0, 0, ctypes_u8, 0 }, { "stops_0_opa", 3, 0, 0, ctypes_u8, 0 }, @@ -82,9 +83,9 @@ const be_ctypes_structure_t be_lv_draw_dsc_base = { const be_ctypes_structure_t be_lv_draw_rect_dsc = { 112, /* size in bytes */ - 39, /* number of elements */ + 40, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[39]) { + (const be_ctypes_structure_item_t[40]) { { "base_dsc_size", 20, 0, 0, ctypes_u32, 0 }, { "base_id1", 8, 0, 0, ctypes_u32, 0 }, { "base_id2", 12, 0, 0, ctypes_u32, 0 }, @@ -94,6 +95,7 @@ const be_ctypes_structure_t be_lv_draw_rect_dsc = { { "base_user_data", 24, 0, 0, ctypes_ptr32, 0 }, { "bg_color", 33, 0, 0, ctypes_u24, 1 }, { "bg_grad_dir", 47, 0, 3, ctypes_bf, 0 }, + { "bg_grad_extend", 47, 3, 2, ctypes_bf, 0 }, { "bg_grad_stops_0_color", 36, 0, 0, ctypes_u24, 1 }, { "bg_grad_stops_0_frac", 40, 0, 0, ctypes_u8, 0 }, { "bg_grad_stops_0_opa", 39, 0, 0, ctypes_u8, 0 }, @@ -110,8 +112,8 @@ const be_ctypes_structure_t be_lv_draw_rect_dsc = { { "bg_opa", 32, 0, 0, ctypes_u8, 0 }, { "border_color", 62, 0, 0, ctypes_u24, 1 }, { "border_opa", 72, 0, 0, ctypes_u8, 0 }, - { "border_post", 73, 0, 1, ctypes_bf, 0 }, - { "border_side", 73, 1, 5, ctypes_bf, 0 }, + { "border_post", 73, 5, 1, ctypes_bf, 0 }, + { "border_side", 73, 0, 5, ctypes_bf, 0 }, { "border_width", 68, 0, 0, ctypes_i32, 0 }, { "outline_color", 74, 0, 0, ctypes_u24, 1 }, { "outline_opa", 88, 0, 0, ctypes_u8, 0 }, @@ -192,10 +194,10 @@ const be_ctypes_structure_t be_lv_image_header = { }}; const be_ctypes_structure_t be_lv_draw_image_dsc = { - 100, /* size in bytes */ - 33, /* number of elements */ + 108, /* size in bytes */ + 35, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[33]) { + (const be_ctypes_structure_item_t[35]) { { "antialias", 77, 4, 1, ctypes_bf, 0 }, { "base_dsc_size", 20, 0, 0, ctypes_u32, 0 }, { "base_id1", 8, 0, 0, ctypes_u32, 0 }, @@ -204,7 +206,9 @@ const be_ctypes_structure_t be_lv_draw_image_dsc = { { "base_obj", 0, 0, 0, ctypes_ptr32, 0 }, { "base_part", 4, 0, 0, ctypes_u32, 0 }, { "base_user_data", 24, 0, 0, ctypes_ptr32, 0 }, + { "bitmap_mask_src", 104, 0, 0, ctypes_ptr32, 0 }, { "blend_mode", 77, 0, 4, ctypes_bf, 0 }, + { "clip_radius", 100, 0, 0, ctypes_i32, 0 }, { "header_cf", 33, 0, 0, ctypes_u8, 0 }, { "header_flags", 34, 0, 0, ctypes_u16, 0 }, { "header_h", 38, 0, 0, ctypes_u16, 0 }, @@ -212,11 +216,11 @@ const be_ctypes_structure_t be_lv_draw_image_dsc = { { "header_reserved_2", 42, 0, 0, ctypes_u16, 0 }, { "header_stride", 40, 0, 0, ctypes_u16, 0 }, { "header_w", 36, 0, 0, ctypes_u16, 0 }, + { "image_area_x1", 84, 0, 0, ctypes_i32, 0 }, + { "image_area_x2", 92, 0, 0, ctypes_i32, 0 }, + { "image_area_y1", 88, 0, 0, ctypes_i32, 0 }, + { "image_area_y2", 96, 0, 0, ctypes_i32, 0 }, { "opa", 76, 0, 0, ctypes_u8, 0 }, - { "original_area_x1", 80, 0, 0, ctypes_i32, 0 }, - { "original_area_x2", 88, 0, 0, ctypes_i32, 0 }, - { "original_area_y1", 84, 0, 0, ctypes_i32, 0 }, - { "original_area_y2", 92, 0, 0, ctypes_i32, 0 }, { "pivot_x", 64, 0, 0, ctypes_i32, 0 }, { "pivot_y", 68, 0, 0, ctypes_i32, 0 }, { "recolor", 72, 0, 0, ctypes_u24, 1 }, @@ -227,7 +231,7 @@ const be_ctypes_structure_t be_lv_draw_image_dsc = { { "skew_x", 56, 0, 0, ctypes_i32, 0 }, { "skew_y", 60, 0, 0, ctypes_i32, 0 }, { "src", 28, 0, 0, ctypes_ptr32, 0 }, - { "sup", 96, 0, 0, ctypes_ptr32, 0 }, + { "sup", 80, 0, 0, ctypes_ptr32, 0 }, { "tile", 77, 5, 1, ctypes_bf, 0 }, }}; @@ -319,13 +323,13 @@ const be_ctypes_structure_t be_lv_event = { be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[9]) { { "code", 8, 0, 0, ctypes_i32, 0 }, - { "current_target", 4, 0, 0, ctypes_ptr32, 0 }, + { "current_target", 0, 0, 0, ctypes_ptr32, 0 }, { "deleted", 24, 0, 1, ctypes_bf, 0 }, + { "original_target", 4, 0, 0, ctypes_ptr32, 0 }, { "param", 16, 0, 0, ctypes_ptr32, 0 }, { "prev", 20, 0, 0, ctypes_ptr32, 0 }, { "stop_bubbling", 24, 2, 1, ctypes_bf, 0 }, { "stop_processing", 24, 1, 1, ctypes_bf, 0 }, - { "target", 0, 0, 0, ctypes_ptr32, 0 }, { "user_data", 12, 0, 0, ctypes_ptr32, 0 }, }}; @@ -359,10 +363,10 @@ const be_ctypes_structure_t be_lv_style_transition_dsc = { }}; const be_ctypes_structure_t be_lv_layer = { - 56, /* size in bytes */ - 14, /* number of elements */ + 72, /* size in bytes */ + 18, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[14]) { + (const be_ctypes_structure_item_t[18]) { { "_clip_area_x1", 24, 0, 0, ctypes_i32, 0 }, { "_clip_area_x2", 32, 0, 0, ctypes_i32, 0 }, { "_clip_area_y1", 28, 0, 0, ctypes_i32, 0 }, @@ -371,12 +375,16 @@ const be_ctypes_structure_t be_lv_layer = { { "buf_area_x2", 12, 0, 0, ctypes_i32, 0 }, { "buf_area_y1", 8, 0, 0, ctypes_i32, 0 }, { "buf_area_y2", 16, 0, 0, ctypes_i32, 0 }, - { "color_format", 20, 0, 0, ctypes_u8, 0 }, + { "color_format", 20, 0, 0, ctypes_u32, 0 }, { "draw_buf", 0, 0, 0, ctypes_ptr32, 0 }, - { "draw_task_head", 40, 0, 0, ctypes_ptr32, 0 }, - { "next", 48, 0, 0, ctypes_ptr32, 0 }, - { "parent", 44, 0, 0, ctypes_ptr32, 0 }, - { "user_data", 52, 0, 0, ctypes_ptr32, 0 }, + { "draw_task_head", 56, 0, 0, ctypes_ptr32, 0 }, + { "next", 64, 0, 0, ctypes_ptr32, 0 }, + { "parent", 60, 0, 0, ctypes_ptr32, 0 }, + { "phy_clip_area_x1", 40, 0, 0, ctypes_i32, 0 }, + { "phy_clip_area_x2", 48, 0, 0, ctypes_i32, 0 }, + { "phy_clip_area_y1", 44, 0, 0, ctypes_i32, 0 }, + { "phy_clip_area_y2", 52, 0, 0, ctypes_i32, 0 }, + { "user_data", 68, 0, 0, ctypes_ptr32, 0 }, }}; const be_ctypes_structure_t be_lv_color_filter_dsc = { diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py index cc7833f92..820d5e8cb 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py +++ b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py @@ -51,7 +51,7 @@ int32_t = ct.i32 size_t = ct.u32 ptr = ct.ptr32 -lv_point = [ # valid LVGL9 +lv_point = [ # valid LVGL92 [int32_t, "x"], [int32_t, "y"], ] @@ -61,13 +61,13 @@ lv_point = ct.structure(lv_point, "lv_point") # lv_value_precise_t x; # lv_value_precise_t y; # } lv_point_precise_t; -lv_point_precise = [ # valid LVGL9 +lv_point_precise = [ # valid LVGL92 [lv_value_precise, "x"], [lv_value_precise, "y"], ] lv_point_precise = ct.structure(lv_point_precise, "lv_point_precise") -lv_area = [ # valid LVGL9 +lv_area = [ # valid LVGL92 [int32_t, "x1"], [int32_t, "y1"], [int32_t, "x2"], @@ -82,7 +82,7 @@ lv_area = ct.structure(lv_area, "lv_area") # lv_opa_t opa; /**< The opacity of the color*/ # uint8_t frac; /**< The stop position in 1/255 unit */ # } lv_gradient_stop_t; -lv_gradient_stop = [ # valid LVGL91 +lv_gradient_stop = [ # valid LVGL92 [lv_color, "color"], [lv_opa, "opa"], [uint8_t, "frac"], @@ -90,12 +90,15 @@ lv_gradient_stop = [ # valid LVGL91 lv_gradient_stop = ct.structure(lv_gradient_stop, "lv_gradient_stop") # typedef struct { -# lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ -# uint8_t stops_count; /**< The number of used stops in the array */ -# lv_grad_dir_t dir : 3; /**< The gradient direction. +# lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ +# uint8_t stops_count; /**< The number of used stops in the array */ +# lv_grad_dir_t dir : 3; /**< The gradient direction. +# * Any of LV_GRAD_DIR_NONE, LV_GRAD_DIR_VER, LV_GRAD_DIR_HOR, +# * LV_GRAD_TYPE_LINEAR, LV_GRAD_TYPE_RADIAL, LV_GRAD_TYPE_CONICAL */ +# lv_grad_extend_t extend : 2; /**< Behaviour outside the defined range. # * Any of LV_GRAD_DIR_HOR, LV_GRAD_DIR_VER, LV_GRAD_DIR_NONE */ # } lv_grad_dsc_t; -lv_grad_dsc = [ # valid LVGL91 +lv_grad_dsc = [ # valid LVGL92 # since it's an array and not two structures, we need to explicitly unroll it here or the alignment is wrong # [lv_gradient_stop, "stops_0"], [lv_color, "stops_0_color"], @@ -108,6 +111,7 @@ lv_grad_dsc = [ # valid LVGL91 [uint8_t, "stops_count"], [uint8_t_3, "dir"], + [uint8_t_2, "extend"], ] lv_grad_dsc = ct.structure(lv_grad_dsc, "lv_grad_dsc") @@ -121,7 +125,7 @@ lv_grad_dsc = ct.structure(lv_grad_dsc, "lv_grad_dsc") # size_t dsc_size; # void * user_data; # } lv_draw_dsc_base_t; -lv_draw_dsc_base = [ # valid LVGL91 +lv_draw_dsc_base = [ # valid LVGL92 [ptr, "obj"], [uint32_t, "part"], [uint32_t, "id1"], @@ -171,7 +175,7 @@ lv_draw_dsc_base = ct.structure(lv_draw_dsc_base, "lv_draw_dsc_base") # int32_t shadow_spread; # lv_opa_t shadow_opa; # } lv_draw_rect_dsc_t; -lv_draw_rect_dsc = [ # valid LVGL91 +lv_draw_rect_dsc = [ # valid LVGL92 [lv_draw_dsc_base, "base"], [int32_t, "radius"], @@ -193,8 +197,8 @@ lv_draw_rect_dsc = [ # valid LVGL91 [lv_color, "border_color"], [int32_t, "border_width"], [lv_opa, "border_opa"], - [uint8_t_1, "border_post"], [uint8_t_5, "border_side"], + [uint8_t_1, "border_post"], #/*Outline*/ [lv_color, "outline_color"], @@ -227,7 +231,7 @@ lv_draw_rect_dsc = ct.structure(lv_draw_rect_dsc, "lv_draw_rect_dsc") # uint8_t round_end : 1; # uint8_t raw_end : 1; /*Do not bother with perpendicular line ending if it's not visible for any reason*/ # } lv_draw_line_dsc_t; -lv_draw_line_dsc = [ # valid LVGL91 +lv_draw_line_dsc = [ # valid LVGL92 [lv_draw_dsc_base, "base"], [lv_point_precise, "p1"], @@ -257,7 +261,7 @@ lv_draw_line_dsc = ct.structure(lv_draw_line_dsc, "lv_draw_line_dsc") # lv_opa_t opa; # uint8_t rounded : 1; # } lv_draw_arc_dsc_t; -lv_draw_arc_dsc = [ # valid LVGL91 +lv_draw_arc_dsc = [ # valid LVGL92 [lv_draw_dsc_base, "base"], [lv_color, "color"], @@ -283,7 +287,7 @@ lv_draw_arc_dsc = ct.structure(lv_draw_arc_dsc, "lv_draw_arc_dsc") # uint32_t stride: 16; /*Number of bytes in a row*/ # uint32_t reserved_2: 16; /*Reserved to be used later*/ # } lv_image_header_t; -lv_image_header = [ # valid LVGL91 +lv_image_header = [ # valid LVGL92 [uint8_t, "magic"], [uint8_t, "cf"], [uint16_t, "flags"], @@ -323,7 +327,7 @@ lv_image_header = ct.structure(lv_image_header, "lv_image_header") # lv_area_t original_area; # const lv_image_dsc_t * bitmap_mask_src; # } lv_draw_image_dsc_t; -lv_draw_image_dsc = [ # valid LVGL91 +lv_draw_image_dsc = [ # valid LVGL92 [lv_draw_dsc_base, "base"], [ptr, "src"], @@ -343,8 +347,11 @@ lv_draw_image_dsc = [ # valid LVGL91 [uint8_t_4, "blend_mode"], [uint8_t_1, "antialias"], [uint8_t_1, "tile"], - [lv_area, "original_area"], [ptr, "sup"], + [lv_area, "image_area"], + + [int32_t, "clip_radius"], + [ptr, "bitmap_mask_src"], ] lv_draw_image_dsc = ct.structure(lv_draw_image_dsc, "lv_draw_image_dsc") @@ -374,7 +381,7 @@ lv_draw_image_dsc = ct.structure(lv_draw_image_dsc, "lv_draw_image_dsc") # uint8_t text_local : 1; # lv_draw_label_hint_t * hint; # } lv_draw_label_dsc_t; -lv_draw_label_dsc = [ # valid LVGL91 +lv_draw_label_dsc = [ # valid LVGL92 [lv_draw_dsc_base, "base"], [ptr, "text"], [ptr, "font"], @@ -409,7 +416,7 @@ lv_draw_label_dsc = ct.structure(lv_draw_label_dsc, "lv_draw_label_dsc") # uint32_t x_axis_sec : 1; # uint32_t y_axis_sec : 1; # } lv_chart_series_t; -lv_chart_series = [ # valid LVGL91 +lv_chart_series = [ # valid LVGL92 [ptr, "x_points"], [ptr, "y_points"], [lv_color, "color"], @@ -430,7 +437,7 @@ lv_chart_series = ct.structure(lv_chart_series, "lv_chart_series") # lv_dir_t dir; # uint32_t pos_set: 1; /*1: pos is set; 0: point_id is set*/ # } lv_chart_cursor_t; -lv_chart_cursor = [ # valid LVGL91 +lv_chart_cursor = [ # valid LVGL92 [lv_point, "pos"], [int32_t, "point_id"], [lv_color, "color"], @@ -449,22 +456,16 @@ destructor_cb = ptr # callback event_cb = ptr # callback lv_event_code = ct.i32 -# struct _lv_obj_class_t { + +# struct lv_obj_class_t { # const lv_obj_class_t * base_class; -# /*class_p is the final class while obj->class_p is the class currently being [de]constructed.*/ +# /** class_p is the final class while obj->class_p is the class currently being [de]constructed. */ # void (*constructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); # void (*destructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); - -# /*class_p is the class in which event is being processed.*/ +# +# /** class_p is the class in which event is being processed. */ # void (*event_cb)(const lv_obj_class_t * class_p, lv_event_t * e); /**< Widget type specific event function*/ - -# #if LV_USE_OBJ_PROPERTY -# uint32_t prop_index_start; -# uint32_t prop_index_end; -# const lv_property_ops_t * properties; -# uint32_t properties_count; -# #endif - +# # void * user_data; # const char * name; # int32_t width_def; @@ -474,7 +475,7 @@ lv_event_code = ct.i32 # uint32_t instance_size : 16; # uint32_t theme_inheritable : 1; /**< Value from ::lv_obj_class_theme_inheritable_t*/ # }; -lv_obj_class = [ # valid LVGL91 +lv_obj_class = [ # valid LVGL92 [lv_obj_class_ptr, "base_class"], [constructor_cb, "constructor_cb"], [destructor_cb, "destructor_cb"], @@ -490,7 +491,7 @@ lv_obj_class = [ # valid LVGL91 ] lv_obj_class = ct.structure(lv_obj_class, "lv_obj_class") -# struct _lv_event_t { +# struct lv_event_t { # void * current_target; # void * original_target; # lv_event_code_t code; @@ -501,9 +502,9 @@ lv_obj_class = ct.structure(lv_obj_class, "lv_obj_class") # uint8_t stop_processing : 1; # uint8_t stop_bubbling : 1; # }; -lv_event = [ # valid LVGL91 - [lv_obj_ptr, "target"], +lv_event = [ # valid LVGL92 [lv_obj_ptr, "current_target"], + [lv_obj_ptr, "original_target"], [lv_event_code, "code"], [ptr, "user_data"], [ptr, "param"], @@ -523,7 +524,7 @@ lv_event = ct.structure(lv_event, "lv_event") # const uint8_t * data; /**< Pointer to the data of the image*/ # const void * reserved; /**< A reserved field to make it has same size as lv_draw_buf_t*/ # } lv_image_dsc_t; -lv_image_dsc = [ # valid LVGL91 +lv_image_dsc = [ # valid LVGL92 [lv_image_header, "header"], [uint32_t, "data_size"], [ptr, "data"], @@ -541,7 +542,7 @@ lv_image_dsc = ct.structure(lv_image_dsc, "lv_image_dsc") # uint32_t time; /**< Duration of the transition in [ms]*/ # uint32_t delay; /**< Delay before the transition in [ms]*/ # } lv_style_transition_dsc_t; -lv_style_transition_dsc = [ # valid LVGL91 +lv_style_transition_dsc = [ # valid LVGL92 [ptr, "props"], [ptr, "user_data"], [ptr, "path_xcb"], @@ -550,22 +551,52 @@ lv_style_transition_dsc = [ # valid LVGL91 ] lv_style_transition_dsc = ct.structure(lv_style_transition_dsc, "lv_style_transition_dsc") -# typedef struct { + +# struct lv_layer_t { +# +# /** Target draw buffer of the layer*/ # lv_draw_buf_t * draw_buf; +# +# /** The absolute coordinates of the buffer */ # lv_area_t buf_area; +# +# /** The color format of the layer. LV_COLOR_FORMAT_... */ # lv_color_format_t color_format; +# +# /** +# * NEVER USE IT DRAW UNITS. USED INTERNALLY DURING DRAW TASK CREATION. +# * The current clip area with absolute coordinates, always the same or smaller than `buf_area` +# * Can be set before new draw tasks are added to indicate the clip area of the draw tasks. +# * Therefore `lv_draw_add_task()` always saves it in the new draw task to know the clip area when the draw task was added. +# * During drawing the draw units also sees the saved clip_area and should use it during drawing. +# * During drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks. +# */ # lv_area_t _clip_area; +# +# /** +# * The physical clipping area relative to the display. +# */ +# lv_area_t phy_clip_area; +# +# #if LV_DRAW_TRANSFORM_USE_MATRIX +# /** Transform matrix to be applied when rendering the layer */ +# lv_matrix_t matrix; +# #endif +# +# /** Linked list of draw tasks */ # lv_draw_task_t * draw_task_head; +# # lv_layer_t * parent; # lv_layer_t * next; # bool all_tasks_added; # void * user_data; -# } lv_layer_t; -lv_layer = [ # valid LVGL9 +# }; +lv_layer = [ # valid LVGL92 [ptr, "draw_buf"], [lv_area, "buf_area"], - [uint8_t, "color_format"], + [uint32_t, "color_format"], [lv_area, "_clip_area"], + [lv_area, "phy_clip_area"], [ptr, "draw_task_head"], [ptr, "parent"], [ptr, "next"], @@ -581,7 +612,7 @@ lv_layer = ct.structure(lv_layer, "lv_layer") # lv_color_filter_cb_t filter_cb; # void * user_data; # } lv_color_filter_dsc_t; -lv_color_filter_dsc = [ # valid LVGL91 +lv_color_filter_dsc = [ # valid LVGL92 [ptr, "filter_cb"], [ptr, "user_data"], ] @@ -590,16 +621,16 @@ lv_color_filter_dsc = ct.structure(lv_color_filter_dsc, "lv_color_filter_dsc") ####################################################################### # lv_timer native, superseded by lv_timer -# struct _lv_timer_t { -# uint32_t period; /**< How often the timer should run*/ -# uint32_t last_run; /**< Last time the timer ran*/ -# lv_timer_cb_t timer_cb; /**< Timer function*/ -# void * user_data; /**< Custom user data*/ -# int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times*/ +# struct lv_timer_t { +# uint32_t period; /**< How often the timer should run */ +# uint32_t last_run; /**< Last time the timer ran */ +# lv_timer_cb_t timer_cb; /**< Timer function */ +# void * user_data; /**< Custom user data */ +# int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */ # uint32_t paused : 1; # uint32_t auto_delete : 1; # }; -lv_timer_ntv = [ # valid LVGL91 +lv_timer_ntv = [ # valid LVGL92 [uint32_t, "period"], [uint32_t, "last_run"], [ptr, "timer_cb"], @@ -618,7 +649,7 @@ lv_timer_ntv = ct.structure(lv_timer_ntv, "lv_timer_ntv") # void * user_data; # uint32_t filter; # } lv_event_dsc_t; -lv_event_dsc = [ # valid LVGL91 +lv_event_dsc = [ # valid LVGL92 [ptr, "cb"], [ptr, "user_data"], [uint32_t, "filter"], diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.c b/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.c index 82f1c30c7..54a5d24ea 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.c +++ b/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.c @@ -6,6 +6,7 @@ #include "be_mem.h" #include +#include // Backport configuration from LVGL 8 to LVGL 9 #ifdef BE_LV_WIDGET_BTN @@ -391,16 +392,7 @@ int lv0_constants_as_hash(bvm *vm) { /*********************************************************************************************\ * temporarily fix lv_span_get_style() \*********************************************************************************************/ -lv_style_t * lv_span_get_style(lv_span_t * span) { - return &span->style; -} +#include "widgets/bar/lv_bar_private.h" lv_area_t * lv_bar_get_indic_area(lv_obj_t * bar) { return &((lv_bar_t*)bar)->indic_area; } -// add accessor for lv_line points array -lv_point_t * lv_line_get_points(lv_obj_t * line) { - return &((lv_line_t*)line)->point_array[0]; -} -int lv_line_get_points_num(lv_obj_t * line) { - return ((lv_line_t*)line)->point_num; -} \ No newline at end of file diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.h b/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.h index 369fc5808..285fd6fb0 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.h +++ b/lib/libesp32_lvgl/lv_binding_berry/src/lv_berry.h @@ -25,16 +25,9 @@ typedef struct lv_ts_calibration_t { } lv_ts_calibration_t; extern lv_ts_calibration_t lv_ts_calibration; -// temporarily fix lv_span_get_style() -extern lv_style_t * lv_span_get_style(lv_span_t * span); - // add accessor for lv_bar->indic_area extern lv_area_t * lv_bar_get_indic_area(lv_obj_t * bar); -// add accessor for lv_line points array -extern lv_point_t * lv_line_get_points(lv_obj_t * line); -extern int lv_line_get_points_num(lv_obj_t * line); - #ifdef __cplusplus } #endif diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py index 6955a62da..84b136755 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py @@ -280,6 +280,9 @@ class type_mapper_class: "lv_indev_read_cb_t", "lv_vector_path_t *", "lv_vector_path_quality_t", + "lv_color16_t", + "uint8_t *", + "lv_obj_t **", ] return_types = { @@ -329,6 +332,7 @@ class type_mapper_class: "lv_text_align_t": "i", "lv_arc_mode_t": "i", "lv_bar_mode_t": "i", + "lv_bar_orientation_t": "i", "lv_event_code_t": "i", "lv_obj_flag_t": "i", "lv_slider_mode_t": "i", @@ -356,6 +360,7 @@ class type_mapper_class: "lv_hit_test_info_t *": "c", # treat as opaque pointer "lv_screen_load_anim_t": "i", "lv_display_render_mode_t": "i", + "lv_draw_task_type_t": "i", # "lv_vector_gradient_spread_t": "i", "lv_cover_res_t": "i", # "lv_vector_path_quality_t": "i", @@ -397,6 +402,8 @@ class type_mapper_class: "lv_roller_mode_t": "i", "lv_table_cell_ctrl_t": "i", + "lv_calendar_chinese_t": "c", + # arrays "constchar * []": "str_arr", # "char * []": "str_arr", @@ -416,7 +423,7 @@ class type_mapper_class: "lv_draw_image_dsc_t *": "lv_draw_image_dsc", "lv_event_dsc_t *": "lv_event_dsc", - "_lv_obj_t *": "lv_obj", + # "_lv_obj_t *": "lv_obj", // no more used in LVGL 9.2 "lv_obj_t *": "lv_obj", "lv_event_t *": "lv_event", "lv_color_t": "lv_color", @@ -425,7 +432,7 @@ class type_mapper_class: "lv_font_t *": "lv_font", "lv_theme_t *": "lv_theme", "lv_display_t *": "lv_display", - '_lv_display_t *': "lv_display", + # '_lv_display_t *': "lv_display", // no more used in LVGL 9.2 "lv_indev_t *": "lv_indev", "lv_point_t []": "lv_point_arr", "lv_span_t *": "lv_span", diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py b/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py index a939c296b..66c4794ef 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py @@ -81,10 +81,21 @@ lv_fun_globs = [ # add version information "../lvgl.h", ] +headers_exlude_suffix = [ + "_private.h", + "lv_lottie.h", + "lv_obj_property.h", + "lv_obj_property_names.h", + "lv_style_properties.h", +] + headers_names = list_files(lv_src_prefix, lv_fun_globs) headers_names += list_files("../../LVGL_assets/src/", ["lv_theme_haspmota.h"]) headers_names += list_files("../src/", ["lv_berry.h"]) +# filter out from headers_exlude_suffix +headers_names = [x for x in headers_names if not any(x.endswith(suffix) for suffix in headers_exlude_suffix)] + output_filename = "../mapping/lv_funcs.h" sys.stdout = open(output_filename, 'w', encoding='utf-8') @@ -110,7 +121,7 @@ lv_coord_t lv_get_ver_res(void); """) for header_name in headers_names: - with open(header_name, encoding='utf-8') as f: + with open(header_name, encoding='utf-8-sig') as f: print("// " + header_name) raw = clean_source(f.read()) @@ -191,8 +202,19 @@ lv_fun_globs = [ "display/lv_display.h", "layouts/**/*.h", ] + +headers_exlude_suffix = [ + "_private.h", + "lv_lottie.h", + "lv_obj_property.h", + "lv_obj_property_names.h", + "lv_style_properties.h", +] headers_names = list_files(lv_src_prefix, lv_fun_globs) +# filter out from headers_exlude_suffix +headers_names = [x for x in headers_names if not any(x.endswith(suffix) for suffix in headers_exlude_suffix)] + output_filename = "../mapping/lv_enum.h" sys.stdout = open(output_filename, 'w', encoding='utf-8') print("""// ====================================================================== diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be index d0822dbeb..2089fbfff 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_haspmota.be @@ -1578,7 +1578,7 @@ class lvh_line : lvh_obj end var pt_arr = lv.point_arr(pts) self._lv_points = pt_arr - self._lv_obj.set_points(pt_arr, size(pts)) + self._lv_obj.set_points_mutable(pt_arr, size(pts)) else print(f"HSP: 'line' wrong format for 'points' {t}") end @@ -1792,11 +1792,11 @@ class lvh_scale_line : lvh_line super(self).set_val(t) self._parent_lvh._lv_obj.set_line_needle_value(self._lv_obj, self._needle_length, self._val) # work-around for points being global static - if (self._lv_obj.get_points_num() == 2) # check that there are only 2 points + if (self._lv_obj.get_point_count() == 2) # check that there are only 2 points # read back the computed points var p_arr = bytes(self._lv_obj.get_points(), size(self._lv_points)) self._lv_points.setbytes(0, p_arr) - self._lv_obj.set_points(self._lv_points, 2) + self._lv_obj.set_points_mutable(self._lv_points, 2) end end end diff --git a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h index 6ec64d494..ecf4ac7b9 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h +++ b/lib/libesp32_lvgl/lv_haspmota/src/solidify/solidified_lv_haspmota.h @@ -7067,7 +7067,7 @@ be_local_closure(class_lvh_line_set_points, /* name */ /* K9 */ be_nested_str_weak(point_arr), /* K10 */ be_nested_str_weak(_lv_points), /* K11 */ be_nested_str_weak(_lv_obj), - /* K12 */ be_nested_str_weak(set_points), + /* K12 */ be_nested_str_weak(set_points_mutable), /* K13 */ be_nested_str_weak(HSP_X3A_X20_X27line_X27_X20wrong_X20format_X20for_X20_X27points_X27_X20_X25s), }), be_str_weak(set_points), @@ -7857,13 +7857,13 @@ static const bvalue be_ktab_class_lvh_scale_line[21] = { /* K3 */ be_nested_str_weak(set_line_needle_value), /* K4 */ be_nested_str_weak(_needle_length), /* K5 */ be_nested_str_weak(_val), - /* K6 */ be_nested_str_weak(get_points_num), + /* K6 */ be_nested_str_weak(get_point_count), /* K7 */ be_const_int(2), /* K8 */ be_nested_str_weak(get_points), /* K9 */ be_nested_str_weak(_lv_points), /* K10 */ be_nested_str_weak(setbytes), /* K11 */ be_const_int(0), - /* K12 */ be_nested_str_weak(set_points), + /* K12 */ be_nested_str_weak(set_points_mutable), /* K13 */ be_nested_str_weak(_page), /* K14 */ be_nested_str_weak(_oh), /* K15 */ be_nested_str_weak(lvh_scale), diff --git a/lib/libesp32_lvgl/lvgl/README.md b/lib/libesp32_lvgl/lvgl/README.md index dcafb8e18..aa42b9145 100644 --- a/lib/libesp32_lvgl/lvgl/README.md +++ b/lib/libesp32_lvgl/lvgl/README.md @@ -1,5 +1,5 @@ - +

English | 中文 | Português do Brasil | 日本語 @@ -8,15 +8,15 @@

 

Light and Versatile Graphics Library

 
- +   - 

@@ -24,7 +24,7 @@ Docs | Forum | Demos | -Services +Services


@@ -57,14 +57,14 @@ Our team is ready to help you with graphics design, UI implementation and consul - Word wrapping, kerning, text scrolling, sub-pixel rendering, Pinyin-IME Chinese input, Emojis in texts. - Rendering engine supporting animations, anti-aliasing, opacity, smooth scrolling, shadows, image transformation, etc   - Supports Mouse, Touchpad, Keypad, Keyboard, External buttons, Encoder [Input devices](https://docs.lvgl.io/master/porting/indev.html). - - [Multiple display](https://docs.lvgl.io/master/overview/disp.html#multiple-display-support) support. + - [Multiple display](https://docs.lvgl.io/master/overview/display.html#multiple-display-support) support. **Binding and Build Support** - - [Micropython Binding](https://blog.lvgl.io/2019-02-20/micropython-bindings) exposes LVGL API + - [MicroPython Binding](https://blog.lvgl.io/2019-02-20/micropython-bindings) exposes LVGL API - [PikaScript Binding](https://blog.lvgl.io/2022-08-24/pikascript-and-lvgl) python on MCU lighter and easier. - No custom build system is used. You can build LVGL as you build the other files of your project. - - Support for Make and [CMake](https://docs.lvgl.io/master/get-started/platforms/cmake.html) is included out of the box. - - [Develop on PC](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html) and use the same UI code on embedded hardware. + - Support for Make and [CMake](https://docs.lvgl.io/master/integration/building/cmake.html) is included out of the box. + - [Develop on PC](https://docs.lvgl.io/master/integration/ide/pc-simulator.html) and use the same UI code on embedded hardware. - Convert the C UI code to HTML file with our [Emscripten port](https://github.com/lvgl/lv_web_emscripten). **Docs, Tools, and Services** @@ -124,7 +124,7 @@ lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MA /*Create a white label, set its text and align it to the center*/ lv_obj_t * label = lv_label_create(lv_screen_active()); lv_label_set_text(label, "Hello world"); -lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN); +lv_obj_set_style_text_color(label, lv_color_hex(0xffffff), LV_PART_MAIN); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); ``` diff --git a/lib/libesp32_lvgl/lvgl/README_Tasmota.md b/lib/libesp32_lvgl/lvgl/README_Tasmota.md deleted file mode 100644 index 623deb724..000000000 --- a/lib/libesp32_lvgl/lvgl/README_Tasmota.md +++ /dev/null @@ -1,28 +0,0 @@ -# Tasmota patches - -Following patches need to be applied when updating LVGL: - -`src/extra/libs/lv_extra.c` - -Comment the `lv_freetype_init()` portion. The actual initializatio is done in Tasmota code -because parameters depend on Tasmota defines and presence of PSRAM. - -``` C -// TASMOTA Specific, the initialization is done in Tasmota code to adjust with PSRAM -// #if LV_USE_FREETYPE -// /*Init freetype library*/ -// # if LV_FREETYPE_CACHE_SIZE >= 0 -// lv_freetype_init(LV_FREETYPE_CACHE_FT_FACES, LV_FREETYPE_CACHE_FT_SIZES, LV_FREETYPE_CACHE_SIZE); -// # else -// lv_freetype_init(0, 0, 0); -// # endif -// #endif -``` - -## lv_spinner - -Both function `arc_anim_start_angle()` and `arc_anim_end_angle()` are made non-static. This allows to search for `lv_anim` object based on their `exec_cb` callbacks and change properties on-the-fly. - -## LVGL 9 - -Temporarily rename `lv_image_set_inner_align` to `lv_image_set_inner_align` until solved in LVGL repo. diff --git a/lib/libesp32_lvgl/lvgl/library.json b/lib/libesp32_lvgl/lvgl/library.json index 5e9d5f8b3..370c00a6d 100644 --- a/lib/libesp32_lvgl/lvgl/library.json +++ b/lib/libesp32_lvgl/lvgl/library.json @@ -1,6 +1,6 @@ { "name": "lvgl", - "version": "9.1.0", + "version": "9.2.0", "keywords": "graphics, gui, embedded, tft, lvgl", "description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.", "repository": { diff --git a/lib/libesp32_lvgl/lvgl/library.properties b/lib/libesp32_lvgl/lvgl/library.properties index d80cdf791..7dbe2228e 100644 --- a/lib/libesp32_lvgl/lvgl/library.properties +++ b/lib/libesp32_lvgl/lvgl/library.properties @@ -1,5 +1,5 @@ name=lvgl -version=9.1.0 +version=9.2.0 author=kisvegabor maintainer=kisvegabor,embeddedt,pete-pjb sentence=Full-featured Graphics Library for Embedded Systems diff --git a/lib/libesp32_lvgl/lvgl/lv_conf_template.h b/lib/libesp32_lvgl/lvgl/lv_conf_template.h index 64dcc9eaf..ab886a96b 100644 --- a/lib/libesp32_lvgl/lvgl/lv_conf_template.h +++ b/lib/libesp32_lvgl/lvgl/lv_conf_template.h @@ -1,6 +1,6 @@ -/** +/** * @file lv_conf.h - * Configuration file for v9.1.0 + * Configuration file for v9.2.0 */ /* @@ -26,7 +26,7 @@ COLOR SETTINGS *====================*/ -/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ #define LV_COLOR_DEPTH 16 /*========================= @@ -44,6 +44,12 @@ #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN +#define LV_STDINT_INCLUDE +#define LV_STDDEF_INCLUDE +#define LV_STDBOOL_INCLUDE +#define LV_INTTYPES_INCLUDE +#define LV_LIMITS_INCLUDE +#define LV_STDARG_INCLUDE #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ @@ -82,6 +88,7 @@ * - LV_OS_CMSIS_RTOS2 * - LV_OS_RTTHREAD * - LV_OS_WINDOWS + * - LV_OS_MQX * - LV_OS_CUSTOM */ #define LV_USE_OS LV_OS_NONE @@ -99,6 +106,12 @@ /*Align the start address of draw_buf addresses to this bytes*/ #define LV_DRAW_BUF_ALIGN 4 +/*Using matrix for transformations. + *Requirements: + `LV_USE_MATRIX = 1`. + The rendering engine needs to support 3x3 matrix transformations.*/ +#define LV_DRAW_TRANSFORM_USE_MATRIX 0 + /* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers @@ -107,11 +120,34 @@ /*The target buffer size for simple layer chunks.*/ #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ +/* The stack size of the drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /*[bytes]*/ + #define LV_USE_DRAW_SW 1 #if LV_USE_DRAW_SW == 1 - /* Set the number of draw unit. + + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ + + #define LV_DRAW_SW_SUPPORT_RGB565 1 + #define LV_DRAW_SW_SUPPORT_RGB565A8 1 + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #define LV_DRAW_SW_SUPPORT_XRGB8888 1 + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #define LV_DRAW_SW_SUPPORT_L8 1 + #define LV_DRAW_SW_SUPPORT_AL88 1 + #define LV_DRAW_SW_SUPPORT_A8 1 + #define LV_DRAW_SW_SUPPORT_I1 1 + + /* Set the number of draw unit. * > 1 requires an operating system enabled in `LV_USE_OS` - * > 1 means multiply threads will render the screen in parallel */ + * > 1 means multiple threads will render the screen in parallel */ #define LV_DRAW_SW_DRAW_UNIT_CNT 1 /* Use Arm-2D to accelerate the sw render */ @@ -119,7 +155,7 @@ /* Enable native helium assembly to be compiled */ #define LV_USE_NATIVE_HELIUM_ASM 0 - + /* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only * 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */ #define LV_DRAW_SW_COMPLEX 1 @@ -142,6 +178,9 @@ #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" #endif + + /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 #endif /* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ @@ -152,8 +191,13 @@ #define LV_USE_VGLITE_BLIT_SPLIT 0 #if LV_USE_OS - /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ - #define LV_USE_VGLITE_DRAW_ASYNC 1 + /* Use additional draw thread for VG-Lite processing.*/ + #define LV_USE_VGLITE_DRAW_THREAD 1 + + #if LV_USE_VGLITE_DRAW_THREAD + /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ + #define LV_USE_VGLITE_DRAW_ASYNC 1 + #endif #endif /* Enable VGLite asserts. */ @@ -164,6 +208,11 @@ #define LV_USE_DRAW_PXP 0 #if LV_USE_DRAW_PXP + #if LV_USE_OS + /* Use additional draw thread for PXP processing.*/ + #define LV_USE_PXP_DRAW_THREAD 1 + #endif + /* Enable PXP asserts. */ #define LV_USE_PXP_ASSERT 0 #endif @@ -178,24 +227,28 @@ #define LV_USE_DRAW_VG_LITE 0 #if LV_USE_DRAW_VG_LITE -/* Enable VG-Lite custom external 'gpu_init()' function */ -#define LV_VG_LITE_USE_GPU_INIT 0 + /* Enable VG-Lite custom external 'gpu_init()' function */ + #define LV_VG_LITE_USE_GPU_INIT 0 -/* Enable VG-Lite assert. */ -#define LV_VG_LITE_USE_ASSERT 0 + /* Enable VG-Lite assert. */ + #define LV_VG_LITE_USE_ASSERT 0 -/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ -#define LV_VG_LITE_FLUSH_MAX_COUNT 8 + /* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ + #define LV_VG_LITE_FLUSH_MAX_COUNT 8 -/* Enable border to simulate shadow - * NOTE: which usually improves performance, - * but does not guarantee the same rendering quality as the software. */ -#define LV_VG_LITE_USE_BOX_SHADOW 0 + /* Enable border to simulate shadow + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ + #define LV_VG_LITE_USE_BOX_SHADOW 0 -/* VG-Lite gradient image maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ -#define LV_VG_LITE_GRAD_CACHE_SIZE 32 + /* VG-Lite gradient maximum cache number. + * NOTE: The memory usage of a single gradient image is 4K bytes. + */ + #define LV_VG_LITE_GRAD_CACHE_CNT 32 + + /* VG-Lite stroke maximum cache number. + */ + #define LV_VG_LITE_STROKE_CACHE_CNT 32 #endif @@ -224,6 +277,11 @@ *0: User need to register a callback with `lv_log_register_print_cb()`*/ #define LV_LOG_PRINTF 0 + /*Set callback to print the logs. + *E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)` + *Can be overwritten by `lv_log_register_print_cb`*/ + //#define LV_LOG_PRINT_CB + /*1: Enable print timestamp; *0: Disable print timestamp*/ #define LV_LOG_USE_TIMESTAMP 1 @@ -232,6 +290,7 @@ *0: Do not print file and line number of the log*/ #define LV_LOG_USE_FILE_LINE 1 + /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ #define LV_LOG_TRACE_MEM 1 #define LV_LOG_TRACE_TIMER 1 @@ -310,12 +369,23 @@ /* Add `id` field to `lv_obj_t` */ #define LV_USE_OBJ_ID 0 -/* Use lvgl builtin method for obj ID */ -#define LV_USE_OBJ_ID_BUILTIN 0 +/* Automatically assign an ID when obj is created */ +#define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + +/*Use the builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return e.g. "button3" +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#define LV_USE_OBJ_ID_BUILTIN 1 /*Use obj property set/get API*/ #define LV_USE_OBJ_PROPERTY 0 +/*Enable property name support*/ +#define LV_USE_OBJ_PROPERTY_NAME 1 + /* VG-Lite Simulator */ /*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ #define LV_USE_VG_LITE_THORVG 0 @@ -328,6 +398,9 @@ /*Enable YUV color format support*/ #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + /*Enable Linear gradient extension support*/ + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + /*Enable 16 pixels alignment*/ #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 @@ -372,7 +445,7 @@ #define LV_ATTRIBUTE_FAST_MEM /*Export integer constant to binding. This macro is used with constants in the form of LV_ that - *should also appear on LVGL binding API such as Micropython.*/ + *should also appear on LVGL binding API such as MicroPython.*/ #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ /*Prefix all global extern data with this*/ @@ -381,6 +454,13 @@ /* Use `float` as `lv_value_precise_t` */ #define LV_USE_FLOAT 0 +/*Enable matrix support + *Requires `LV_USE_FLOAT = 1`*/ +#define LV_USE_MATRIX 0 + +/*Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default*/ +#define LV_USE_PRIVATE_API 0 + /*================== * FONT USAGE *===================*/ @@ -412,6 +492,7 @@ /*Demonstrate special features*/ #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ +#define LV_FONT_SIMSUN_14_CJK 0 /*1000 most common CJK radicals*/ #define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ /*Pixel perfect monospace fonts*/ @@ -477,7 +558,7 @@ #endif /*Enable Arabic/Persian processing - *In these languages characters should be replaced with an other form based on their position in the text*/ + *In these languages characters should be replaced with another form based on their position in the text*/ #define LV_USE_ARABIC_PERSIAN_CHARS 0 /*================== @@ -510,6 +591,7 @@ #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} #define LV_USE_CALENDAR_HEADER_ARROW 1 #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + #define LV_USE_CALENDAR_CHINESE 0 #endif /*LV_USE_CALENDAR*/ #define LV_USE_CANVAS 1 @@ -539,6 +621,8 @@ #define LV_USE_LIST 1 +#define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ + #define LV_USE_MENU 1 #define LV_USE_MSGBOX 1 @@ -614,6 +698,9 @@ /*File system interfaces for common APIs */ +/*Setting a default driver letter allows skipping the driver prefix in filepaths*/ +#define LV_FS_DEFAULT_DRIVE_LETTER '\0' + /*API for fopen, fread, etc*/ #define LV_USE_FS_STDIO 0 #if LV_USE_FS_STDIO @@ -657,6 +744,18 @@ #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ #endif +/*API for Arduino LittleFs. */ +#define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + +/*API for Arduino Sd. */ +#define LV_USE_FS_ARDUINO_SD 0 +#if LV_USE_FS_ARDUINO_SD + #define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + /*LODEPNG decoder library*/ #define LV_USE_LODEPNG 0 @@ -677,8 +776,8 @@ /*GIF decoder library*/ #define LV_USE_GIF 0 #if LV_USE_GIF -/*GIF decoder accelerate*/ -#define LV_GIF_CACHE_DECODE_DATA 0 + /*GIF decoder accelerate*/ + #define LV_GIF_CACHE_DECODE_DATA 0 #endif @@ -710,12 +809,14 @@ #if LV_USE_TINY_TTF /* Enable loading TTF data from files */ #define LV_TINY_TTF_FILE_SUPPORT 0 + #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 #endif /*Rlottie library*/ #define LV_USE_RLOTTIE 0 -/*Enable Vector Graphic APIs*/ +/*Enable Vector Graphic APIs + *Requires `LV_USE_MATRIX = 1`*/ #define LV_USE_VECTOR_GRAPHIC 0 /* Enable ThorVG (vector graphics library) from the src/libs folder */ @@ -817,7 +918,7 @@ #define LV_USE_IME_PINYIN 0 #if LV_USE_IME_PINYIN /*1: Use default thesaurus*/ - /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ + /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus*/ #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 /*Set the maximum number of candidate panels that can be displayed*/ /*This needs to be adjusted according to the size of the screen*/ @@ -851,6 +952,7 @@ #define LV_SDL_INCLUDE_PATH #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ + #define LV_SDL_ACCELERATED 1 /*1: Use hardware acceleration*/ #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ @@ -860,13 +962,20 @@ #define LV_USE_X11 0 #if LV_USE_X11 #define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/ - #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/ + #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for rendering*/ /*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/ #define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/ #define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/ #define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/ #endif +/*Use Wayland to open a window and handle input on Linux or BSD desktops */ +#define LV_USE_WAYLAND 0 +#if LV_USE_WAYLAND + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /*Draw client side window decorations only necessary on Mutter/GNOME*/ + #define LV_WAYLAND_WL_SHELL 0 /*Use the legacy wl_shell protocol instead of the default XDG shell*/ +#endif + /*Driver for /dev/fb*/ #define LV_USE_LINUX_FBDEV 0 #if LV_USE_LINUX_FBDEV @@ -921,16 +1030,31 @@ #endif /*Drivers for LCD devices connected via SPI/parallel port*/ -#define LV_USE_ST7735 0 -#define LV_USE_ST7789 0 -#define LV_USE_ST7796 0 -#define LV_USE_ILI9341 0 +#define LV_USE_ST7735 0 +#define LV_USE_ST7789 0 +#define LV_USE_ST7796 0 +#define LV_USE_ILI9341 0 #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) +/*Driver for Renesas GLCD*/ +#define LV_USE_RENESAS_GLCDC 0 + /* LVGL Windows backend */ #define LV_USE_WINDOWS 0 +/* Use OpenGL to open window on PC and handle mouse and keyboard */ +#define LV_USE_OPENGLES 0 +#if LV_USE_OPENGLES + #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ +#endif + +/* QNX Screen display and input drivers */ +#define LV_USE_QNX 0 +#if LV_USE_QNX + #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ +#endif + /*================== * EXAMPLES *==================*/ @@ -981,6 +1105,7 @@ /*Vector graphic demo*/ #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + /*--END OF LV_CONF_H--*/ #endif /*LV_CONF_H*/ diff --git a/lib/libesp32_lvgl/lvgl/lv_version.h b/lib/libesp32_lvgl/lvgl/lv_version.h new file mode 100644 index 000000000..7e6356a66 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/lv_version.h @@ -0,0 +1,14 @@ +/** + * @file lv_version.h + * The current version of LVGL + */ + +#ifndef LVGL_VERSION_H +#define LVGL_VERSION_H + +#define LVGL_VERSION_MAJOR 9 +#define LVGL_VERSION_MINOR 2 +#define LVGL_VERSION_PATCH 0 +#define LVGL_VERSION_INFO "" + +#endif /* LVGL_VERSION_H */ diff --git a/lib/libesp32_lvgl/lvgl/lvgl.h b/lib/libesp32_lvgl/lvgl/lvgl.h index ba10357da..df6140e29 100644 --- a/lib/libesp32_lvgl/lvgl/lvgl.h +++ b/lib/libesp32_lvgl/lvgl/lvgl.h @@ -13,10 +13,7 @@ extern "C" { /*************************** * CURRENT VERSION OF LVGL ***************************/ -#define LVGL_VERSION_MAJOR 9 -#define LVGL_VERSION_MINOR 1 -#define LVGL_VERSION_PATCH 0 -#define LVGL_VERSION_INFO "" +#include "lv_version.h" /********************* * INCLUDES @@ -35,6 +32,7 @@ extern "C" { #include "src/misc/lv_anim_timeline.h" #include "src/misc/lv_profiler_builtin.h" #include "src/misc/lv_rb.h" +#include "src/misc/lv_utils.h" #include "src/tick/lv_tick.h" @@ -65,6 +63,7 @@ extern "C" { #include "src/widgets/led/lv_led.h" #include "src/widgets/line/lv_line.h" #include "src/widgets/list/lv_list.h" +#include "src/widgets/lottie/lv_lottie.h" #include "src/widgets/menu/lv_menu.h" #include "src/widgets/msgbox/lv_msgbox.h" #include "src/widgets/roller/lv_roller.h" @@ -111,6 +110,7 @@ extern "C" { #include "src/draw/lv_draw.h" #include "src/draw/lv_draw_buf.h" #include "src/draw/lv_draw_vector.h" +#include "src/draw/sw/lv_draw_sw.h" #include "src/themes/lv_theme.h" @@ -118,8 +118,12 @@ extern "C" { #include "src/lv_api_map_v8.h" #include "src/lv_api_map_v9_0.h" +#include "src/lv_api_map_v9_1.h" + +#if LV_USE_PRIVATE_API +#include "src/lvgl_private.h" +#endif -#include "src/core/lv_global.h" /********************* * DEFINES *********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_global.h b/lib/libesp32_lvgl/lvgl/src/core/lv_global.h index 3fa568f28..c106e4f50 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_global.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_global.h @@ -15,8 +15,6 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" -#include - #include "../misc/lv_types.h" #include "../draw/lv_draw.h" #if LV_USE_DRAW_SW @@ -29,16 +27,30 @@ extern "C" { #include "../misc/lv_log.h" #include "../misc/lv_style.h" #include "../misc/lv_timer.h" +#include "../osal/lv_os.h" #include "../others/sysmon/lv_sysmon.h" #include "../stdlib/builtin/lv_tlsf.h" #if LV_USE_FONT_COMPRESSED -#include "../font/lv_font_fmt_txt.h" +#include "../font/lv_font_fmt_txt_private.h" #endif #include "../tick/lv_tick.h" #include "../layouts/lv_layout.h" +#include "../misc/lv_types.h" + +#include "../misc/lv_timer_private.h" +#include "../misc/lv_anim_private.h" +#include "../tick/lv_tick_private.h" +#include "../draw/lv_draw_buf_private.h" +#include "../draw/lv_draw_private.h" +#include "../draw/sw/lv_draw_sw_private.h" +#include "../draw/sw/lv_draw_sw_mask_private.h" +#include "../stdlib/builtin/lv_tlsf_private.h" +#include "../others/sysmon/lv_sysmon_private.h" +#include "../layouts/lv_layout_private.h" + /********************* * DEFINES *********************/ @@ -53,18 +65,18 @@ struct _snippet_stack; #endif #if LV_USE_FREETYPE -struct _lv_freetype_context_t; +struct lv_freetype_context_t; #endif #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN -struct _lv_profiler_builtin_ctx_t; +struct lv_profiler_builtin_ctx_t; #endif #if LV_USE_NUTTX -struct _lv_nuttx_ctx_t; +struct lv_nuttx_ctx_t; #endif -typedef struct _lv_global_t { +typedef struct lv_global_t { bool inited; bool deinit_in_progress; /**< Can be used e.g. in the LV_EVENT_DELETE to deinit the drivers too */ @@ -100,23 +112,21 @@ typedef struct _lv_global_t { lv_tick_state_t tick_state; lv_draw_buf_handlers_t draw_buf_handlers; + lv_draw_buf_handlers_t font_draw_buf_handlers; + lv_draw_buf_handlers_t image_cache_draw_buf_handlers; /**< Ensure that all assigned draw buffers + * can be managed by image cache. */ lv_ll_t img_decoder_ll; -#if LV_CACHE_DEF_SIZE > 0 lv_cache_t * img_cache; -#endif - -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 lv_cache_t * img_header_cache; -#endif lv_draw_global_info_t draw_info; #if defined(LV_DRAW_SW_SHADOW_CACHE_SIZE) && LV_DRAW_SW_SHADOW_CACHE_SIZE > 0 lv_draw_sw_shadow_cache_t sw_shadow_cache; #endif #if LV_DRAW_SW_COMPLEX - _lv_draw_sw_mask_radius_circle_dsc_arr_t sw_circle_cache; + lv_draw_sw_mask_radius_circle_dsc_arr_t sw_circle_cache; #endif #if LV_USE_LOG @@ -163,12 +173,16 @@ typedef struct _lv_global_t { lv_fs_drv_t littlefs_fs_drv; #endif -#if LV_USE_FREETYPE - struct _lv_freetype_context_t * ft_context; +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + lv_fs_drv_t arduino_esp_littlefs_fs_drv; #endif -#if LV_USE_TINY_TTF - lv_cache_t * tiny_ttf_cache; +#if LV_USE_FS_ARDUINO_SD + lv_fs_drv_t arduino_sd_fs_drv; +#endif + +#if LV_USE_FREETYPE + struct lv_freetype_context_t * ft_context; #endif #if LV_USE_FONT_COMPRESSED @@ -180,18 +194,14 @@ typedef struct _lv_global_t { #endif #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN - struct _lv_profiler_builtin_ctx_t * profiler_context; + struct lv_profiler_builtin_ctx_t * profiler_context; #endif #if LV_USE_FILE_EXPLORER != 0 lv_style_t fe_list_button_style; #endif -#if LV_USE_SYSMON && LV_USE_PERF_MONITOR - lv_sysmon_backend_data_t sysmon_perf; -#endif - -#if LV_USE_SYSMON && LV_USE_MEM_MONITOR +#if LV_USE_MEM_MONITOR lv_sysmon_backend_data_t sysmon_mem; #endif @@ -205,9 +215,21 @@ typedef struct _lv_global_t { #endif #if LV_USE_NUTTX - struct _lv_nuttx_ctx_t * nuttx_ctx; + struct lv_nuttx_ctx_t * nuttx_ctx; #endif +#if LV_USE_OS != LV_OS_NONE + lv_mutex_t lv_general_mutex; +#endif + +#if LV_USE_OS == LV_OS_FREERTOS + uint32_t freertos_idle_time_sum; + uint32_t freertos_non_idle_time_sum; + uint32_t freertos_task_switch_timestamp; + bool freertos_idle_task_running; +#endif + + void * user_data; } lv_global_t; diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_group.c b/lib/libesp32_lvgl/lvgl/src/core/lv_group.c index 44b41d8b2..d1cdb3176 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_group.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_group.c @@ -6,12 +6,11 @@ /********************* * INCLUDES *********************/ -#include - -#include "lv_group.h" -#include "../core/lv_obj.h" +#include "lv_group_private.h" +#include "../core/lv_obj_private.h" #include "../core/lv_global.h" #include "../indev/lv_indev.h" +#include "../misc/lv_types.h" /********************* * DEFINES @@ -43,22 +42,22 @@ static lv_indev_t * get_indev(const lv_group_t * g); * GLOBAL FUNCTIONS **********************/ -void _lv_group_init(void) +void lv_group_init(void) { - _lv_ll_init(group_ll_p, sizeof(lv_group_t)); + lv_ll_init(group_ll_p, sizeof(lv_group_t)); } -void _lv_group_deinit(void) +void lv_group_deinit(void) { - _lv_ll_clear(group_ll_p); + lv_ll_clear(group_ll_p); } lv_group_t * lv_group_create(void) { - lv_group_t * group = _lv_ll_ins_head(group_ll_p); + lv_group_t * group = lv_ll_ins_head(group_ll_p); LV_ASSERT_MALLOC(group); if(group == NULL) return NULL; - _lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *)); + lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *)); group->obj_focus = NULL; group->frozen = 0; @@ -83,7 +82,7 @@ void lv_group_delete(lv_group_t * group) /*Remove the objects from the group*/ lv_obj_t ** obj; - _LV_LL_READ(&group->obj_ll, obj) { + LV_LL_READ(&group->obj_ll, obj) { if((*obj)->spec_attr)(*obj)->spec_attr->group_p = NULL; } @@ -99,8 +98,8 @@ void lv_group_delete(lv_group_t * group) /*If the group is the default group, set the default group as NULL*/ if(group == lv_group_get_default()) lv_group_set_default(NULL); - _lv_ll_clear(&(group->obj_ll)); - _lv_ll_remove(group_ll_p, group); + lv_ll_clear(&(group->obj_ll)); + lv_ll_remove(group_ll_p, group); lv_free(group); } @@ -123,36 +122,17 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) /*Be sure the object is removed from its current group*/ lv_group_remove_obj(obj); - /*Do not add the object twice*/ - lv_obj_t ** obj_i; - _LV_LL_READ(&group->obj_ll, obj_i) { - if((*obj_i) == obj) { - LV_LOG_INFO("the object is already added to this group"); - return; - } - } - - /*If the object is already in a group and focused then refocus it*/ - lv_group_t * group_cur = lv_obj_get_group(obj); - if(group_cur) { - if(obj->spec_attr->group_p && *(obj->spec_attr->group_p->obj_focus) == obj) { - lv_group_refocus(group_cur); - - LV_LOG_INFO("changing object's group"); - } - } - if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj); obj->spec_attr->group_p = group; - lv_obj_t ** next = _lv_ll_ins_tail(&group->obj_ll); + lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll); LV_ASSERT_MALLOC(next); if(next == NULL) return; *next = obj; /*If the head and the tail is equal then there is only one object in the linked list. *In this case automatically activate it*/ - if(_lv_ll_get_head(&group->obj_ll) == next) { + if(lv_ll_get_head(&group->obj_ll) == next) { lv_group_refocus(group); } @@ -168,7 +148,7 @@ void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2) /*Do not add the object twice*/ lv_obj_t ** obj_i; - _LV_LL_READ(&g1->obj_ll, obj_i) { + LV_LL_READ(&g1->obj_ll, obj_i) { if((*obj_i) == obj1)(*obj_i) = obj2; else if((*obj_i) == obj2)(*obj_i) = obj1; } @@ -191,7 +171,7 @@ void lv_group_remove_obj(lv_obj_t * obj) if(g->frozen) g->frozen = 0; /*If this is the only object in the group then focus to nothing.*/ - if(_lv_ll_get_head(&g->obj_ll) == g->obj_focus && _lv_ll_get_tail(&g->obj_ll) == g->obj_focus) { + if(lv_ll_get_head(&g->obj_ll) == g->obj_focus && lv_ll_get_tail(&g->obj_ll) == g->obj_focus) { lv_obj_send_event(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g)); } /*If there more objects in the group then focus to the next/prev object*/ @@ -209,9 +189,9 @@ void lv_group_remove_obj(lv_obj_t * obj) /*Search the object and remove it from its group*/ lv_obj_t ** i; - _LV_LL_READ(&g->obj_ll, i) { + LV_LL_READ(&g->obj_ll, i) { if(*i == obj) { - _lv_ll_remove(&g->obj_ll, i); + lv_ll_remove(&g->obj_ll, i); lv_free(i); if(obj->spec_attr) obj->spec_attr->group_p = NULL; break; @@ -233,11 +213,11 @@ void lv_group_remove_all_objs(lv_group_t * group) /*Remove the objects from the group*/ lv_obj_t ** obj; - _LV_LL_READ(&group->obj_ll, obj) { + LV_LL_READ(&group->obj_ll, obj) { if((*obj)->spec_attr)(*obj)->spec_attr->group_p = NULL; } - _lv_ll_clear(&(group->obj_ll)); + lv_ll_clear(&(group->obj_ll)); } void lv_group_focus_obj(lv_obj_t * obj) @@ -252,7 +232,7 @@ void lv_group_focus_obj(lv_obj_t * obj) lv_group_set_editing(g, false); lv_obj_t ** i; - _LV_LL_READ(&g->obj_ll, i) { + LV_LL_READ(&g->obj_ll, i) { if(*i == obj) { if(g->obj_focus != NULL && obj != *g->obj_focus) { /*Do not defocus if the same object needs to be focused again*/ lv_result_t res = lv_obj_send_event(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g)); @@ -277,7 +257,7 @@ void lv_group_focus_next(lv_group_t * group) { LV_ASSERT_NULL(group); - bool focus_changed = focus_next_core(group, _lv_ll_get_head, _lv_ll_get_next); + bool focus_changed = focus_next_core(group, lv_ll_get_head, lv_ll_get_next); if(group->edge_cb) { if(!focus_changed) group->edge_cb(group, true); @@ -288,7 +268,7 @@ void lv_group_focus_prev(lv_group_t * group) { LV_ASSERT_NULL(group); - bool focus_changed = focus_next_core(group, _lv_ll_get_tail, _lv_ll_get_prev); + bool focus_changed = focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev); if(group->edge_cb) { if(!focus_changed) group->edge_cb(group, false); @@ -394,22 +374,36 @@ bool lv_group_get_wrap(lv_group_t * group) uint32_t lv_group_get_obj_count(lv_group_t * group) { LV_ASSERT_NULL(group); - return _lv_ll_get_len(&group->obj_ll); + return lv_ll_get_len(&group->obj_ll); +} + +lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index) +{ + uint32_t len = 0; + lv_obj_t ** obj; + + LV_LL_READ(&group->obj_ll, obj) { + if(len == index) { + return *obj; + } + len++; + } + return NULL; } uint32_t lv_group_get_count(void) { - return _lv_ll_get_len(group_ll_p); + return lv_ll_get_len(group_ll_p); } lv_group_t * lv_group_by_index(uint32_t index) { uint32_t len = 0; - void * node; + lv_group_t * group; - for(node = _lv_ll_get_tail(group_ll_p); node != NULL; node = _lv_ll_get_prev(group_ll_p, node)) { + LV_LL_READ_BACK(group_ll_p, group) { if(len == index) { - return (lv_group_t *) node; + return group; } len++; } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_group.h b/lib/libesp32_lvgl/lvgl/src/core/lv_group.h index ca60edb12..e5f267d00 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_group.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_group.h @@ -13,19 +13,16 @@ extern "C" { /********************* * INCLUDES *********************/ - #include "../lv_conf_internal.h" -#include -#include #include "../misc/lv_types.h" #include "../misc/lv_ll.h" /********************* * DEFINES *********************/ -/*Predefined keys to control the focused object via lv_group_send(group, c)*/ -enum _lv_key_t { +/** Predefined keys to control focused object via lv_group_send(group, c) */ +typedef enum { LV_KEY_UP = 17, /*0x11*/ LV_KEY_DOWN = 18, /*0x12*/ LV_KEY_RIGHT = 19, /*0x13*/ @@ -38,7 +35,7 @@ enum _lv_key_t { LV_KEY_PREV = 11, /*0x0B, '*/ LV_KEY_HOME = 2, /*0x02, STX*/ LV_KEY_END = 3, /*0x03, ETX*/ -}; +} lv_key_t; /********************** * TYPEDEFS @@ -47,29 +44,6 @@ enum _lv_key_t { typedef void (*lv_group_focus_cb_t)(lv_group_t *); typedef void (*lv_group_edge_cb_t)(lv_group_t *, bool); -/** - * Groups can be used to logically hold objects so that they can be individually focused. - * They are NOT for laying out objects on a screen (try layouts for that). - */ -struct _lv_group_t { - lv_ll_t obj_ll; /**< Linked list to store the objects in the group*/ - lv_obj_t ** obj_focus; /**< The object in focus*/ - - lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/ - lv_group_edge_cb_t edge_cb; /**< A function to call when an edge is reached, no more focus - targets are available in this direction (to allow edge feedback - like a sound or a scroll bounce) */ - - void * user_data; - - uint8_t frozen : 1; /**< 1: can't focus to new object*/ - uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/ - uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on - deletion.*/ - uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end - of list.*/ -}; - typedef enum { LV_GROUP_REFOCUS_POLICY_NEXT = 0, LV_GROUP_REFOCUS_POLICY_PREV = 1 @@ -79,18 +53,6 @@ typedef enum { * GLOBAL PROTOTYPES **********************/ -/** - * Init the group module - * @remarks Internal function, do not call directly. - */ -void _lv_group_init(void); - -/** - * Deinit the group module - * @remarks Internal function, do not call directly. - */ -void _lv_group_deinit(void); - /** * Create a new object group * @return pointer to the new object group @@ -125,7 +87,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj); /** * Swap 2 object in a group. The object must be in the same group * @param obj1 pointer to an object - * @param obj2 pointer to an other object + * @param obj2 pointer to another object */ void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2); @@ -241,7 +203,6 @@ bool lv_group_get_editing(const lv_group_t * group); /** * Get whether focus next/prev will allow wrapping from first->last or last->first object. * @param group pointer to group - * @param en true: wrapping enabled; false: wrapping disabled */ bool lv_group_get_wrap(lv_group_t * group); @@ -252,6 +213,14 @@ bool lv_group_get_wrap(lv_group_t * group); */ uint32_t lv_group_get_obj_count(lv_group_t * group); +/** + * Get the nth object within a group + * @param group pointer to a group + * @param index index of object within the group + * @return pointer to the object + */ +lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index); + /** * Get the number of groups * @return number of groups @@ -260,6 +229,7 @@ uint32_t lv_group_get_count(void); /** * Get a group by its index + * @param index index of the group * @return pointer to the group */ lv_group_t * lv_group_by_index(uint32_t index); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h new file mode 100644 index 000000000..33b7640c7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h @@ -0,0 +1,75 @@ +/** + * @file lv_group_private.h + * + */ + +#ifndef LV_GROUP_PRIVATE_H +#define LV_GROUP_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_group.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Groups can be used to logically hold objects so that they can be individually focused. + * They are NOT for laying out objects on a screen (try layouts for that). + */ +struct lv_group_t { + lv_ll_t obj_ll; /**< Linked list to store the objects in the group*/ + lv_obj_t ** obj_focus; /**< The object in focus*/ + + lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/ + lv_group_edge_cb_t edge_cb; /**< A function to call when an edge is reached, no more focus + targets are available in this direction (to allow edge feedback + like a sound or a scroll bounce) */ + + void * user_data; + + uint8_t frozen : 1; /**< 1: can't focus to new object*/ + uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/ + uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on + deletion.*/ + uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end + of list.*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init the group module + * @remarks Internal function, do not call directly. + */ +void lv_group_init(void); + +/** + * Deinit the group module + * @remarks Internal function, do not call directly. + */ +void lv_group_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GROUP_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c index f05b53854..9b9f56d3f 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c @@ -6,7 +6,12 @@ /********************* * INCLUDES *********************/ -#include "lv_obj.h" +#include "lv_obj_private.h" +#include "../misc/lv_event_private.h" +#include "../misc/lv_area_private.h" +#include "lv_obj_style_private.h" +#include "lv_obj_event_private.h" +#include "lv_obj_class_private.h" #include "../indev/lv_indev.h" #include "../indev/lv_indev_private.h" #include "lv_refr.h" @@ -17,10 +22,10 @@ #include "../misc/lv_assert.h" #include "../misc/lv_math.h" #include "../misc/lv_log.h" +#include "../misc/lv_types.h" #include "../tick/lv_tick.h" #include "../stdlib/lv_string.h" -#include -#include +#include "lv_obj_draw_private.h" /********************* * DEFINES @@ -45,6 +50,8 @@ static void draw_scrollbar(lv_obj_t * obj, lv_layer_t * layer); static lv_result_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc); static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find); static void update_obj_state(lv_obj_t * obj, lv_state_t new_state); +static void null_on_delete_cb(lv_event_t * e); + #if LV_USE_OBJ_PROPERTY static lv_result_t lv_obj_set_any(lv_obj_t *, lv_prop_id_t, const lv_property_t *); static lv_result_t lv_obj_get_any(const lv_obj_t *, lv_prop_id_t, lv_property_t *); @@ -60,6 +67,108 @@ static const lv_property_ops_t properties[] = { .setter = lv_obj_set_parent, .getter = lv_obj_get_parent, }, + { + .id = LV_PROPERTY_OBJ_X, + .setter = lv_obj_set_x, + .getter = lv_obj_get_x, + }, + { + .id = LV_PROPERTY_OBJ_Y, + .setter = lv_obj_set_y, + .getter = lv_obj_get_y, + }, + { + .id = LV_PROPERTY_OBJ_W, + .setter = lv_obj_set_width, + .getter = lv_obj_get_width, + }, + { + .id = LV_PROPERTY_OBJ_H, + .setter = lv_obj_set_height, + .getter = lv_obj_get_height, + }, + { + .id = LV_PROPERTY_OBJ_CONTENT_WIDTH, + .setter = lv_obj_set_content_width, + .getter = lv_obj_get_content_width, + }, + { + .id = LV_PROPERTY_OBJ_CONTENT_HEIGHT, + .setter = lv_obj_set_content_height, + .getter = lv_obj_get_content_height, + }, + { + .id = LV_PROPERTY_OBJ_LAYOUT, + .setter = lv_obj_set_layout, + }, + { + .id = LV_PROPERTY_OBJ_ALIGN, + .setter = lv_obj_set_align, + }, + { + .id = LV_PROPERTY_OBJ_SCROLLBAR_MODE, + .setter = lv_obj_set_scrollbar_mode, + .getter = lv_obj_get_scrollbar_mode, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_DIR, + .setter = lv_obj_set_scroll_dir, + .getter = lv_obj_get_scroll_dir, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_SNAP_X, + .setter = lv_obj_set_scroll_snap_x, + .getter = lv_obj_get_scroll_snap_x, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_SNAP_Y, + .setter = lv_obj_set_scroll_snap_y, + .getter = lv_obj_get_scroll_snap_y, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_TOP, + .getter = lv_obj_get_scroll_top, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_BOTTOM, + .getter = lv_obj_get_scroll_bottom, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_LEFT, + .getter = lv_obj_get_scroll_left, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_RIGHT, + .getter = lv_obj_get_scroll_right, + }, + { + .id = LV_PROPERTY_OBJ_SCROLL_END, + .getter = lv_obj_get_scroll_end, + }, + { + .id = LV_PROPERTY_OBJ_EXT_DRAW_SIZE, + .getter = lv_obj_get_ext_draw_size, + }, + { + .id = LV_PROPERTY_OBJ_EVENT_COUNT, + .getter = lv_obj_get_event_count, + }, + { + .id = LV_PROPERTY_OBJ_SCREEN, + .getter = lv_obj_get_screen, + }, + { + .id = LV_PROPERTY_OBJ_DISPLAY, + .getter = lv_obj_get_display, + }, + { + .id = LV_PROPERTY_OBJ_CHILD_COUNT, + .getter = lv_obj_get_child_count, + }, + { + .id = LV_PROPERTY_OBJ_INDEX, + .getter = lv_obj_get_index, + }, { .id = LV_PROPERTY_ID_ANY, .setter = lv_obj_set_any, @@ -84,6 +193,12 @@ const lv_obj_class_t lv_obj_class = { .prop_index_end = LV_PROPERTY_OBJ_END, .properties = properties, .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_obj_property_names, + .names_count = sizeof(lv_obj_property_names) / sizeof(lv_property_name_t), +#endif + #endif }; @@ -99,6 +214,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent) { LV_LOG_INFO("begin"); lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + LV_ASSERT_NULL(obj); + if(obj == NULL) return NULL; lv_obj_class_init_obj(obj); return obj; } @@ -262,7 +379,7 @@ void lv_obj_allocate_spec_attr(lv_obj_t * obj) LV_ASSERT_OBJ(obj, MY_CLASS); if(obj->spec_attr == NULL) { - obj->spec_attr = lv_malloc_zeroed(sizeof(_lv_obj_spec_attr_t)); + obj->spec_attr = lv_malloc_zeroed(sizeof(lv_obj_spec_attr_t)); LV_ASSERT_MALLOC(obj->spec_attr); if(obj->spec_attr == NULL) return; @@ -310,6 +427,51 @@ bool lv_obj_is_valid(const lv_obj_t * obj) return false; } +void lv_obj_null_on_delete(lv_obj_t ** obj_ptr) +{ + lv_obj_add_event_cb(*obj_ptr, null_on_delete_cb, LV_EVENT_DELETE, obj_ptr); +} + +#if LV_USE_OBJ_ID +void * lv_obj_get_id(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + return obj->id; +} + +lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id) +{ + if(obj == NULL) obj = lv_display_get_screen_active(NULL); + if(obj == NULL) return NULL; + + uint32_t i; + uint32_t child_cnt = lv_obj_get_child_count(obj); + for(i = 0; i < child_cnt; i++) { + lv_obj_t * child = obj->spec_attr->children[i]; + if(lv_obj_id_compare(child->id, id) == 0) return child; + } + + /*Search children*/ + for(i = 0; i < child_cnt; i++) { + lv_obj_t * child = obj->spec_attr->children[i]; + lv_obj_t * found = lv_obj_get_child_by_id(child, id); + if(found != NULL) return found; + } + + return NULL; +} +#endif + +void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) +{ + obj->user_data = user_data; +} + +void * lv_obj_get_user_data(lv_obj_t * obj) +{ + return obj->user_data; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -342,7 +504,7 @@ static void lv_obj_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) obj->flags |= LV_OBJ_FLAG_SCROLL_WITH_ARROW; if(parent) obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE; -#if LV_USE_OBJ_ID +#if LV_OBJ_ID_AUTO_ASSIGN lv_obj_assign_id(class_p, obj); #endif @@ -353,7 +515,7 @@ static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) { LV_UNUSED(class_p); - _lv_event_mark_deleted(obj); + lv_event_mark_deleted(obj); /*Remove all style*/ lv_obj_enable_style_refresh(false); /*No need to refresh the style because the object will be deleted*/ @@ -379,7 +541,7 @@ static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) obj->spec_attr = NULL; } -#if LV_USE_OBJ_ID +#if LV_OBJ_ID_AUTO_ASSIGN lv_obj_free_id(obj); #endif } @@ -404,7 +566,7 @@ static void lv_obj_draw(lv_event_t * e) lv_area_copy(&coords, &obj->coords); lv_area_increase(&coords, w, h); - if(_lv_area_is_in(info->area, &coords, r) == false) { + if(lv_area_is_in(info->area, &coords, r) == false) { info->res = LV_COVER_RES_NOT_COVER; return; } @@ -713,6 +875,12 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_obj_remove_state(obj, LV_STATE_PRESSED); lv_obj_remove_state(obj, LV_STATE_SCROLLED); } + else if(code == LV_EVENT_HOVER_OVER) { + lv_obj_add_state(obj, LV_STATE_HOVERED); + } + else if(code == LV_EVENT_HOVER_LEAVE) { + lv_obj_remove_state(obj, LV_STATE_HOVERED); + } } /** @@ -729,9 +897,9 @@ static void update_obj_state(lv_obj_t * obj, lv_state_t new_state) lv_state_t prev_state = obj->state; - _lv_style_state_cmp_t cmp_res = _lv_obj_style_state_compare(obj, prev_state, new_state); + lv_style_state_cmp_t cmp_res = lv_obj_style_state_compare(obj, prev_state, new_state); /*If there is no difference in styles there is nothing else to do*/ - if(cmp_res == _LV_STYLE_STATE_CMP_SAME) { + if(cmp_res == LV_STYLE_STATE_CMP_SAME) { obj->state = new_state; return; } @@ -740,12 +908,12 @@ static void update_obj_state(lv_obj_t * obj, lv_state_t new_state) lv_obj_invalidate(obj); obj->state = new_state; - _lv_obj_update_layer_type(obj); - _lv_obj_style_transition_dsc_t * ts = lv_malloc_zeroed(sizeof(_lv_obj_style_transition_dsc_t) * STYLE_TRANSITION_MAX); + lv_obj_update_layer_type(obj); + lv_obj_style_transition_dsc_t * ts = lv_malloc_zeroed(sizeof(lv_obj_style_transition_dsc_t) * STYLE_TRANSITION_MAX); uint32_t tsi = 0; uint32_t i; for(i = 0; i < obj->style_cnt && tsi < STYLE_TRANSITION_MAX; i++) { - _lv_obj_style_t * obj_style = &obj->styles[i]; + lv_obj_style_t * obj_style = &obj->styles[i]; lv_state_t state_act = lv_obj_style_get_selector_state(obj->styles[i].selector); lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector); if(state_act & (~new_state)) continue; /*Skip unrelated styles*/ @@ -781,19 +949,19 @@ static void update_obj_state(lv_obj_t * obj, lv_state_t new_state) for(i = 0; i < tsi; i++) { lv_part_t part_act = lv_obj_style_get_selector_part(ts[i].selector); - _lv_obj_style_create_transition(obj, part_act, prev_state, new_state, &ts[i]); + lv_obj_style_create_transition(obj, part_act, prev_state, new_state, &ts[i]); } lv_free(ts); - if(cmp_res == _LV_STYLE_STATE_CMP_DIFF_REDRAW) { + if(cmp_res == LV_STYLE_STATE_CMP_DIFF_REDRAW) { /*Invalidation is not enough, e.g. layer type needs to be updated too*/ lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY); } - else if(cmp_res == _LV_STYLE_STATE_CMP_DIFF_LAYOUT) { + else if(cmp_res == LV_STYLE_STATE_CMP_DIFF_LAYOUT) { lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY); } - else if(cmp_res == _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD) { + else if(cmp_res == LV_STYLE_STATE_CMP_DIFF_DRAW_PAD) { lv_obj_invalidate(obj); lv_obj_refresh_ext_draw_size(obj); } @@ -820,6 +988,12 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin return false; } +static void null_on_delete_cb(lv_event_t * e) +{ + lv_obj_t ** obj_ptr = lv_event_get_user_data(e); + *obj_ptr = NULL; +} + #if LV_USE_OBJ_PROPERTY static lv_result_t lv_obj_set_any(lv_obj_t * obj, lv_prop_id_t id, const lv_property_t * prop) { diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h index b67684f32..4ae648ffc 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h @@ -15,8 +15,6 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" -#include -#include #include "../misc/lv_types.h" #include "../misc/lv_style.h" #include "../misc/lv_area.h" @@ -45,7 +43,7 @@ extern "C" { * Possible states of a widget. * OR-ed values are possible */ -enum _lv_state_t { +enum { LV_STATE_DEFAULT = 0x0000, LV_STATE_CHECKED = 0x0001, LV_STATE_FOCUSED = 0x0002, @@ -70,7 +68,7 @@ enum _lv_state_t { * Not all parts are used by every widget */ -enum _lv_part_t { +enum { LV_PART_MAIN = 0x000000, /**< A background like rectangle*/ LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/ LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/ @@ -110,7 +108,7 @@ typedef enum { LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/ LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/ LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/ - LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object position-able by the layouts*/ + LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object not positioned by the layouts*/ LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/ LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/ LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/ @@ -127,7 +125,7 @@ typedef enum { LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/ LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/ LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/ -} _lv_obj_flag_t; +} lv_obj_flag_t; #if LV_USE_OBJ_PROPERTY enum { @@ -183,7 +181,32 @@ enum { LV_PROPERTY_ID(OBJ, STATE_END, LV_PROPERTY_TYPE_INT, 47), /*OBJ normal properties*/ - LV_PROPERTY_ID(OBJ, PARENT, LV_PROPERTY_TYPE_POINTER, 31), + LV_PROPERTY_ID(OBJ, PARENT, LV_PROPERTY_TYPE_OBJ, 48), + LV_PROPERTY_ID(OBJ, X, LV_PROPERTY_TYPE_INT, 49), + LV_PROPERTY_ID(OBJ, Y, LV_PROPERTY_TYPE_INT, 50), + LV_PROPERTY_ID(OBJ, W, LV_PROPERTY_TYPE_INT, 51), + LV_PROPERTY_ID(OBJ, H, LV_PROPERTY_TYPE_INT, 52), + LV_PROPERTY_ID(OBJ, CONTENT_WIDTH, LV_PROPERTY_TYPE_INT, 53), + LV_PROPERTY_ID(OBJ, CONTENT_HEIGHT, LV_PROPERTY_TYPE_INT, 54), + LV_PROPERTY_ID(OBJ, LAYOUT, LV_PROPERTY_TYPE_INT, 55), + LV_PROPERTY_ID(OBJ, ALIGN, LV_PROPERTY_TYPE_INT, 56), + LV_PROPERTY_ID(OBJ, SCROLLBAR_MODE, LV_PROPERTY_TYPE_INT, 57), + LV_PROPERTY_ID(OBJ, SCROLL_DIR, LV_PROPERTY_TYPE_INT, 58), + LV_PROPERTY_ID(OBJ, SCROLL_SNAP_X, LV_PROPERTY_TYPE_INT, 59), + LV_PROPERTY_ID(OBJ, SCROLL_SNAP_Y, LV_PROPERTY_TYPE_INT, 60), + LV_PROPERTY_ID(OBJ, SCROLL_X, LV_PROPERTY_TYPE_INT, 61), + LV_PROPERTY_ID(OBJ, SCROLL_Y, LV_PROPERTY_TYPE_INT, 62), + LV_PROPERTY_ID(OBJ, SCROLL_TOP, LV_PROPERTY_TYPE_INT, 63), + LV_PROPERTY_ID(OBJ, SCROLL_BOTTOM, LV_PROPERTY_TYPE_INT, 64), + LV_PROPERTY_ID(OBJ, SCROLL_LEFT, LV_PROPERTY_TYPE_INT, 65), + LV_PROPERTY_ID(OBJ, SCROLL_RIGHT, LV_PROPERTY_TYPE_INT, 66), + LV_PROPERTY_ID(OBJ, SCROLL_END, LV_PROPERTY_TYPE_INT, 67), + LV_PROPERTY_ID(OBJ, EXT_DRAW_SIZE, LV_PROPERTY_TYPE_INT, 68), + LV_PROPERTY_ID(OBJ, EVENT_COUNT, LV_PROPERTY_TYPE_INT, 69), + LV_PROPERTY_ID(OBJ, SCREEN, LV_PROPERTY_TYPE_OBJ, 70), + LV_PROPERTY_ID(OBJ, DISPLAY, LV_PROPERTY_TYPE_POINTER, 71), + LV_PROPERTY_ID(OBJ, CHILD_COUNT, LV_PROPERTY_TYPE_INT, 72), + LV_PROPERTY_ID(OBJ, INDEX, LV_PROPERTY_TYPE_INT, 73), LV_PROPERTY_OBJ_END, }; @@ -194,54 +217,6 @@ enum { */ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_obj_class; -/** - * Special, rarely used attributes. - * They are allocated automatically if any elements is set. - */ -typedef struct { - lv_obj_t ** children; /**< Store the pointer of the children in an array.*/ - lv_group_t * group_p; - lv_event_list_t event_list; - - lv_point_t scroll; /**< The current X/Y scroll offset*/ - - int32_t ext_click_pad; /**< Extra click padding in all direction*/ - int32_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/ - - uint16_t child_cnt; /**< Number of children*/ - uint16_t scrollbar_mode : 2; /**< How to display scrollbars, see `lv_scrollbar_mode_t`*/ - uint16_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally, see `lv_scroll_snap_t`*/ - uint16_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/ - uint16_t scroll_dir : 4; /**< The allowed scroll direction(s), see `lv_dir_t`*/ - uint16_t layer_type : 2; /**< Cache the layer type here. Element of @lv_intermediate_layer_type_t */ -} _lv_obj_spec_attr_t; - -struct _lv_obj_t { - const lv_obj_class_t * class_p; - lv_obj_t * parent; - _lv_obj_spec_attr_t * spec_attr; - _lv_obj_style_t * styles; -#if LV_OBJ_STYLE_CACHE - uint32_t style_main_prop_is_set; - uint32_t style_other_prop_is_set; -#endif - void * user_data; -#if LV_USE_OBJ_ID - void * id; -#endif - lv_area_t coords; - lv_obj_flag_t flags; - lv_state_t state; - uint16_t layout_inv : 1; - uint16_t readjust_scroll_after_layout : 1; - uint16_t scr_layout_inv : 1; - uint16_t skip_trans : 1; - uint16_t style_cnt : 6; - uint16_t h_layout : 1; - uint16_t w_layout : 1; - uint16_t is_deleting : 1; -}; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -260,14 +235,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent); /** * Set one or more flags * @param obj pointer to an object - * @param f R-ed values from `lv_obj_flag_t` to set. + * @param f OR-ed values from `lv_obj_flag_t` to set. */ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f); /** * Remove one or more flags * @param obj pointer to an object - * @param f OR-ed values from `lv_obj_flag_t` to set. + * @param f OR-ed values from `lv_obj_flag_t` to clear. */ void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f); @@ -308,10 +283,7 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t state, bool v); * @param obj pointer to an object * @param user_data pointer to the new user_data. */ -static inline void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) -{ - obj->user_data = user_data; -} +void lv_obj_set_user_data(lv_obj_t * obj, void * user_data); /*======================= * Getter functions @@ -329,7 +301,7 @@ bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f); * Check if a given flag or any of the flags are set on an object. * @param obj pointer to an object * @param f the flag(s) to check (OR-ed values can be used) - * @return true: at lest one flag flag is set; false: none of the flags are set + * @return true: at least one flag is set; false: none of the flags are set */ bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f); @@ -360,10 +332,7 @@ lv_group_t * lv_obj_get_group(const lv_obj_t * obj); * @param obj pointer to an object * @return the pointer to the user_data of the object */ -static inline void * lv_obj_get_user_data(lv_obj_t * obj) -{ - return obj->user_data; -} +void * lv_obj_get_user_data(lv_obj_t * obj); /*======================= * Other functions @@ -406,12 +375,47 @@ const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj); */ bool lv_obj_is_valid(const lv_obj_t * obj); +/** + * Utility to set an object reference to NULL when it gets deleted. + * The reference should be in a location that will not become invalid + * during the object's lifetime, i.e. static or allocated. + * @param obj_ptr a pointer to a pointer to an object + */ +void lv_obj_null_on_delete(lv_obj_t ** obj_ptr); + #if LV_USE_OBJ_ID +/** + * Set an id for an object. + * @param obj pointer to an object + * @param id the id of the object + */ +void lv_obj_set_id(lv_obj_t * obj, void * id); /** - * Assign an id to an object if not previously assigned - * Set `LV_USE_OBJ_ID_BUILTIN` to 1 to use builtin method to generate object ID. - * Otherwise, these functions including `lv_obj_[assign|free|stringify]_id` should be implemented externally. + * Get the id of an object. + * @param obj pointer to an object + * @return the id of the object + */ +void * lv_obj_get_id(const lv_obj_t * obj); + +/** + * Get the child object by its id. + * It will check children and grandchildren recursively. + * Function `lv_obj_id_compare` is used to matched obj id with given id. + * + * @param obj pointer to an object + * @param id the id of the child object + * @return pointer to the child object or NULL if not found + */ +lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id); + +/** + * Assign id to object if not previously assigned. + * This function gets called automatically when LV_OBJ_ID_AUTO_ASSIGN is enabled. + * + * Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method to generate object ID. + * Otherwise, these functions including `lv_obj_[set|assign|free|stringify]_id` and + * `lv_obj_id_compare`should be implemented externally. * * @param class_p the class this obj belongs to. Note obj->class_p is the class currently being constructed. * @param obj pointer to an object @@ -419,11 +423,24 @@ bool lv_obj_is_valid(const lv_obj_t * obj); void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj); /** - * Free resources allocated by `lv_obj_assign_id` + * Free resources allocated by `lv_obj_assign_id` or `lv_obj_set_id`. + * This function is also called automatically when object is deleted. * @param obj pointer to an object */ void lv_obj_free_id(lv_obj_t * obj); +/** + * Compare two obj id, return 0 if they are equal. + * + * Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method for compare. + * Otherwise, it must be implemented externally. + * + * @param id1: the first id + * @param id2: the second id + * @return 0 if they are equal, non-zero otherwise. + */ +int lv_obj_id_compare(const void * id1, const void * id2); + /** * Format an object's id into a string. * @param obj pointer to an object @@ -437,7 +454,6 @@ const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len); * Free resources used by builtin ID generator. */ void lv_objid_builtin_destroy(void); - #endif #endif /*LV_USE_OBJ_ID*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.c index 1d7b932f5..cb5a396b0 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_obj.h" +#include "lv_obj_class_private.h" +#include "lv_obj_private.h" #include "../themes/lv_theme.h" #include "../display/lv_display.h" #include "../display/lv_display_private.h" @@ -66,8 +67,15 @@ lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * pa disp->screen_cnt = 0; } + lv_obj_t ** screens = lv_realloc(disp->screens, sizeof(lv_obj_t *) * (disp->screen_cnt + 1)); + LV_ASSERT_MALLOC(screens); + if(screens == NULL) { + lv_free(obj); + return NULL; + } + disp->screen_cnt++; - disp->screens = lv_realloc(disp->screens, sizeof(lv_obj_t *) * disp->screen_cnt); + disp->screens = screens; disp->screens[disp->screen_cnt - 1] = obj; /*Set coordinates to full screen size*/ @@ -95,6 +103,8 @@ lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * pa void lv_obj_class_init_obj(lv_obj_t * obj) { + if(obj == NULL) return; + lv_obj_mark_layout_as_dirty(obj); lv_obj_enable_style_refresh(false); @@ -123,7 +133,7 @@ void lv_obj_class_init_obj(lv_obj_t * obj) } } -void _lv_obj_destruct(lv_obj_t * obj) +void lv_obj_destruct(lv_obj_t * obj) { if(obj->class_p->destructor_cb) obj->class_p->destructor_cb(obj->class_p, obj); @@ -132,7 +142,7 @@ void _lv_obj_destruct(lv_obj_t * obj) obj->class_p = obj->class_p->base_class; /*Call the base class's destructor too*/ - _lv_obj_destruct(obj); + lv_obj_destruct(obj); } } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.h index 729229224..4c3bdcb24 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class.h @@ -13,8 +13,6 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include #include "../misc/lv_types.h" #include "../misc/lv_area.h" #include "lv_obj_property.h" @@ -45,36 +43,6 @@ typedef enum { } lv_obj_class_theme_inheritable_t; typedef void (*lv_obj_class_event_cb_t)(lv_obj_class_t * class_p, lv_event_t * e); -/** - * Describe the common methods of every object. - * Similar to a C++ class. - */ -struct _lv_obj_class_t { - const lv_obj_class_t * base_class; - /*class_p is the final class while obj->class_p is the class currently being [de]constructed.*/ - void (*constructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); - void (*destructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); - - /*class_p is the class in which event is being processed.*/ - void (*event_cb)(const lv_obj_class_t * class_p, lv_event_t * e); /**< Widget type specific event function*/ - -#if LV_USE_OBJ_PROPERTY - uint32_t prop_index_start; - uint32_t prop_index_end; - const lv_property_ops_t * properties; - uint32_t properties_count; -#endif - - void * user_data; - const char * name; - int32_t width_def; - int32_t height_def; - uint32_t editable : 2; /**< Value from ::lv_obj_class_editable_t*/ - uint32_t group_def : 2; /**< Value from ::lv_obj_class_group_def_t*/ - uint32_t instance_size : 16; - uint32_t theme_inheritable : 1; /**< Value from ::lv_obj_class_theme_inheritable_t*/ -}; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -89,8 +57,6 @@ lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * pa void lv_obj_class_init_obj(lv_obj_t * obj); -void _lv_obj_destruct(lv_obj_t * obj); - bool lv_obj_is_editable(lv_obj_t * obj); bool lv_obj_is_group_def(lv_obj_t * obj); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class_private.h new file mode 100644 index 000000000..1279b9caf --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class_private.h @@ -0,0 +1,78 @@ +/** + * @file lv_obj_class_private.h + * + */ + +#ifndef LV_OBJ_CLASS_PRIVATE_H +#define LV_OBJ_CLASS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_class.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Describe the common methods of every object. + * Similar to a C++ class. + */ +struct lv_obj_class_t { + const lv_obj_class_t * base_class; + /** class_p is the final class while obj->class_p is the class currently being [de]constructed. */ + void (*constructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); + void (*destructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); + + /** class_p is the class in which event is being processed. */ + void (*event_cb)(const lv_obj_class_t * class_p, lv_event_t * e); /**< Widget type specific event function*/ + +#if LV_USE_OBJ_PROPERTY + uint32_t prop_index_start; + uint32_t prop_index_end; + const lv_property_ops_t * properties; + uint32_t properties_count; + +#if LV_USE_OBJ_PROPERTY_NAME + /* An array of property ID and name */ + const lv_property_name_t * property_names; + uint32_t names_count; +#endif +#endif + + void * user_data; + const char * name; + int32_t width_def; + int32_t height_def; + uint32_t editable : 2; /**< Value from ::lv_obj_class_editable_t*/ + uint32_t group_def : 2; /**< Value from ::lv_obj_class_group_def_t*/ + uint32_t instance_size : 16; + uint32_t theme_inheritable : 1; /**< Value from ::lv_obj_class_theme_inheritable_t*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_obj_destruct(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_CLASS_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c index 7587e7164..b3694b9e5 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c @@ -6,11 +6,13 @@ /********************* * INCLUDES *********************/ -#include "lv_obj_draw.h" -#include "lv_obj.h" +#include "lv_obj_draw_private.h" +#include "lv_obj_private.h" +#include "lv_obj_style.h" #include "../display/lv_display.h" #include "../indev/lv_indev.h" #include "../stdlib/lv_string.h" +#include "../draw/lv_draw_arc.h" /********************* * DEFINES @@ -37,7 +39,7 @@ * GLOBAL FUNCTIONS **********************/ -void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc) +void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc) { draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -142,7 +144,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t } } -void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc) +void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc) { draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -171,7 +173,7 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc draw_dsc->align = lv_obj_get_style_text_align(obj, part); } -void lv_obj_init_draw_image_dsc(lv_obj_t * obj, uint32_t part, lv_draw_image_dsc_t * draw_dsc) +void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc) { draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -197,7 +199,7 @@ void lv_obj_init_draw_image_dsc(lv_obj_t * obj, uint32_t part, lv_draw_image_dsc if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); } -void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc) +void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc) { draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -227,7 +229,7 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); } -void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc) +void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc) { draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -250,7 +252,7 @@ void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part); } -int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part) +int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part) { int32_t s = 0; @@ -288,7 +290,7 @@ void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); - int32_t s_old = _lv_obj_get_ext_draw_size(obj); + int32_t s_old = lv_obj_get_ext_draw_size(obj); int32_t s_new = 0; lv_obj_send_event(obj, LV_EVENT_REFR_EXT_DRAW_SIZE, &s_new); @@ -306,13 +308,13 @@ void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) if(s_new != s_old) lv_obj_invalidate(obj); } -int32_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj) +int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj) { if(obj->spec_attr) return obj->spec_attr->ext_draw_size; else return 0; } -lv_layer_type_t _lv_obj_get_layer_type(const lv_obj_t * obj) +lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj) { if(obj->spec_attr) return (lv_layer_type_t)obj->spec_attr->layer_type; diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h index ad4f08721..c0dbee431 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h @@ -14,7 +14,11 @@ extern "C" { * INCLUDES *********************/ #include "../misc/lv_types.h" -#include "../draw/lv_draw.h" +#include "../draw/lv_draw_rect.h" +#include "../draw/lv_draw_label.h" +#include "../draw/lv_draw_image.h" +#include "../draw/lv_draw_line.h" +#include "../draw/lv_draw_arc.h" /********************* * DEFINES @@ -44,7 +48,7 @@ typedef enum { * @note Only the relevant fields will be set. * E.g. if `border width == 0` the other border properties won't be evaluated. */ -void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc); +void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc); /** * Initialize a label draw descriptor from an object's styles in its current state @@ -54,7 +58,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * If the `opa` field is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized. * Should be initialized with `lv_draw_label_dsc_init(draw_dsc)`. */ -void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc); +void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc); /** * Initialize an image draw descriptor from an object's styles in its current state @@ -63,7 +67,7 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc * @param draw_dsc the descriptor to initialize. * Should be initialized with `lv_draw_image_dsc_init(draw_dsc)`. */ -void lv_obj_init_draw_image_dsc(lv_obj_t * obj, uint32_t part, lv_draw_image_dsc_t * draw_dsc); +void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc); /** * Initialize a line draw descriptor from an object's styles in its current state @@ -72,7 +76,7 @@ void lv_obj_init_draw_image_dsc(lv_obj_t * obj, uint32_t part, lv_draw_image_dsc * @param draw_dsc the descriptor to initialize. * Should be initialized with `lv_draw_line_dsc_init(draw_dsc)`. */ -void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc); +void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc); /** * Initialize an arc draw descriptor from an object's styles in its current state @@ -81,7 +85,7 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * @param draw_dsc the descriptor to initialize. * Should be initialized with `lv_draw_arc_dsc_init(draw_dsc)`. */ -void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc); +void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc); /** * Get the required extra size (around the object's part) to draw shadow, outline, value etc. @@ -89,7 +93,7 @@ void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * * @param part part of the object * @return the extra size required around the object */ -int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part); +int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part); /** * Send a 'LV_EVENT_REFR_EXT_DRAW_SIZE' Call the ancestor's event handler to the object to refresh the value of the extended draw size. @@ -98,15 +102,6 @@ int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part); */ void lv_obj_refresh_ext_draw_size(lv_obj_t * obj); -/** - * Get the extended draw area of an object. - * @param obj pointer to an object - * @return the size extended draw area around the real coordinates - */ -int32_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj); - -lv_layer_type_t _lv_obj_get_layer_type(const lv_obj_t * obj); - /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw_private.h new file mode 100644 index 000000000..36c8bff96 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw_private.h @@ -0,0 +1,48 @@ +/** + * @file lv_obj_draw_private.h + * + */ + +#ifndef LV_OBJ_DRAW_PRIVATE_H +#define LV_OBJ_DRAW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the extended draw area of an object. + * @param obj pointer to an object + * @return the size extended draw area around the real coordinates + */ +int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj); + +lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_DRAW_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.c index 0553f3d77..3831feeb5 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.c @@ -6,7 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_obj.h" +#include "../misc/lv_event_private.h" +#include "lv_obj_event_private.h" +#include "lv_obj_class_private.h" +#include "lv_obj_private.h" #include "../indev/lv_indev.h" #include "../indev/lv_indev_private.h" @@ -58,13 +61,13 @@ lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * e.stop_bubbling = 0; e.stop_processing = 0; - _lv_event_push(&e); + lv_event_push(&e); /*Send the event*/ lv_result_t res = event_send_core(&e); /*Remove this element from the list*/ - _lv_event_pop(&e); + lv_event_pop(&e); return res; } @@ -193,7 +196,9 @@ lv_indev_t * lv_event_get_indev(lv_event_t * e) e->code == LV_EVENT_KEY || e->code == LV_EVENT_FOCUSED || e->code == LV_EVENT_DEFOCUSED || - e->code == LV_EVENT_LEAVE) { + e->code == LV_EVENT_LEAVE || + e->code == LV_EVENT_HOVER_OVER || + e->code == LV_EVENT_HOVER_LEAVE) { return lv_event_get_param(e); } else { @@ -354,19 +359,19 @@ static lv_result_t event_send_core(lv_event_t * e) lv_event_list_t * list = target->spec_attr ? &target->spec_attr->event_list : NULL; res = lv_event_send(list, e, true); - if(res != LV_RESULT_OK) return res; + if(res != LV_RESULT_OK || e->stop_processing) return res; res = lv_obj_event_base(NULL, e); - if(res != LV_RESULT_OK) return res; + if(res != LV_RESULT_OK || e->stop_processing) return res; res = lv_event_send(list, e, false); - if(res != LV_RESULT_OK) return res; + if(res != LV_RESULT_OK || e->stop_processing) return res; lv_obj_t * parent = lv_obj_get_parent(e->current_target); if(parent && event_is_bubbled(e)) { e->current_target = parent; res = event_send_core(e); - if(res != LV_RESULT_OK) return res; + if(res != LV_RESULT_OK || e->stop_processing || e->stop_bubbling) return res; } return res; diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.h index 40a002d8a..2035f1765 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.h @@ -13,7 +13,6 @@ extern "C" { /********************* * INCLUDES *********************/ -#include #include "../misc/lv_types.h" #include "../misc/lv_event.h" #include "../indev/lv_indev.h" @@ -26,18 +25,6 @@ extern "C" { * TYPEDEFS **********************/ -/** - * Used as the event parameter of ::LV_EVENT_HIT_TEST to check if an `point` can click the object or not. - * `res` should be set like this: - * - If already set to `false` an other event wants that point non clickable. If you want to respect it leave it as `false` or set `true` to overwrite it. - * - If already set `true` and `point` shouldn't be clickable set to `false` - * - If already set to `true` you agree that `point` can click the object leave it as `true` - */ -typedef struct { - const lv_point_t * point; /**< A point relative to screen to check if it can click the object or not*/ - bool res; /**< true: `point` can click the object; false: it cannot*/ -} lv_hit_test_info_t; - /** Cover check results.*/ typedef enum { LV_COVER_RES_COVER = 0, @@ -45,16 +32,6 @@ typedef enum { LV_COVER_RES_MASKED = 2, } lv_cover_res_t; -/** - * Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not. - * In the event use `const lv_area_t * area = lv_event_get_cover_area(e)` to get the area to check - * and `lv_event_set_cover_res(e, res)` to set the result. - */ -typedef struct { - lv_cover_res_t res; - const lv_area_t * area; -} lv_cover_check_info_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -98,7 +75,7 @@ lv_obj_t * lv_event_get_target_obj(lv_event_t * e); * @param obj pointer to an object * @param filter an event code (e.g. `LV_EVENT_CLICKED`) on which the event should be called. `LV_EVENT_ALL` can be used to receive all the events. * @param event_cb the new event function - * @param user_data custom data data will be available in `event_cb` + * @param user_data custom data will be available in `event_cb` * @return handler to the event. It can be used in `lv_obj_remove_event_dsc`. */ lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event_private.h new file mode 100644 index 000000000..731d33248 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event_private.h @@ -0,0 +1,62 @@ +/** + * @file lv_obj_event_private.h + * + */ + +#ifndef LV_OBJ_EVENT_PRIVATE_H +#define LV_OBJ_EVENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_event.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Used as the event parameter of ::LV_EVENT_HIT_TEST to check if an `point` can click the object or not. + * `res` should be set like this: + * - If already set to `false` another event wants that point non clickable. If you want to respect it leave it as `false` or set `true` to overwrite it. + * - If already set `true` and `point` shouldn't be clickable set to `false` + * - If already set to `true` you agree that `point` can click the object leave it as `true` + */ +struct lv_hit_test_info_t { + const lv_point_t * point; /**< A point relative to screen to check if it can click the object or not*/ + bool res; /**< true: `point` can click the object; false: it cannot*/ +}; + +/** + * Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not. + * In the event use `const lv_area_t * area = lv_event_get_cover_area(e)` to get the area to check + * and `lv_event_set_cover_res(e, res)` to set the result. + */ +struct lv_cover_check_info_t { + lv_cover_res_t res; + const lv_area_t * area; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_EVENT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_id_builtin.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_id_builtin.c index 4e1976bce..ed8f745ff 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_id_builtin.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_id_builtin.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_obj.h" +#include "lv_obj_class_private.h" +#include "lv_obj_private.h" #include "lv_global.h" #include "../osal/lv_os.h" #include "../stdlib/lv_sprintf.h" @@ -40,7 +41,7 @@ typedef struct _class_info_t { * GLOBAL FUNCTIONS **********************/ -#if LV_USE_OBJ_ID_BUILTIN +#if LV_USE_OBJ_ID && LV_USE_OBJ_ID_BUILTIN void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj) { @@ -78,9 +79,17 @@ void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj) obj->id = (void *)(lv_uintptr_t)id; } +void lv_obj_set_id(lv_obj_t * obj, void * id) +{ + LV_ASSERT_NULL(obj); + if(obj->id) lv_obj_free_id(obj); + obj->id = id; +} + void lv_obj_free_id(lv_obj_t * obj) { LV_UNUSED(obj); + obj->id = NULL; } const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len) @@ -92,7 +101,7 @@ const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len) name = obj->class_p->name; if(name == NULL) name = "nameless"; - lv_snprintf(buf, len, "%s%" LV_PRId32 "", name, (uint32_t)(lv_uintptr_t)obj->id); + lv_snprintf(buf, len, "%s%" LV_PRIu32 "", name, (uint32_t)(lv_uintptr_t)obj->id); return buf; } @@ -105,4 +114,9 @@ void lv_objid_builtin_destroy(void) global->objid_count = 0; } +int lv_obj_id_compare(const void * id1, const void * id2) +{ + return id1 == id2 ? 0 : 1; +} + #endif /*LV_USE_OBJ_ID_BUILTIN*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c index 0e8ecaa52..b5fd34d76 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c @@ -6,10 +6,14 @@ /********************* * INCLUDES *********************/ -#include "lv_obj.h" +#include "../misc/lv_area_private.h" +#include "../layouts/lv_layout_private.h" +#include "lv_obj_event_private.h" +#include "lv_obj_draw_private.h" +#include "lv_obj_private.h" #include "../display/lv_display.h" #include "../display/lv_display_private.h" -#include "lv_refr.h" +#include "lv_refr_private.h" #include "../core/lv_global.h" /********************* @@ -54,12 +58,12 @@ void lv_obj_set_x(lv_obj_t * obj, int32_t x) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_result_t res_x; + lv_style_res_t res_x; lv_style_value_t v_x; res_x = lv_obj_get_local_style_prop(obj, LV_STYLE_X, &v_x, 0); - if((res_x == LV_RESULT_OK && v_x.num != x) || res_x == LV_RESULT_INVALID) { + if((res_x == LV_STYLE_RES_FOUND && v_x.num != x) || res_x == LV_STYLE_RES_NOT_FOUND) { lv_obj_set_style_x(obj, x, 0); } } @@ -68,12 +72,12 @@ void lv_obj_set_y(lv_obj_t * obj, int32_t y) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_result_t res_y; + lv_style_res_t res_y; lv_style_value_t v_y; res_y = lv_obj_get_local_style_prop(obj, LV_STYLE_Y, &v_y, 0); - if((res_y == LV_RESULT_OK && v_y.num != y) || res_y == LV_RESULT_INVALID) { + if((res_y == LV_STYLE_RES_FOUND && v_y.num != y) || res_y == LV_STYLE_RES_NOT_FOUND) { lv_obj_set_style_y(obj, y, 0); } } @@ -170,7 +174,7 @@ bool lv_obj_refr_size(lv_obj_t * obj) /*If the object is already out of the parent and its position is changes *surely the scrollbars also changes so invalidate them*/ - bool on1 = _lv_area_is_in(&ori, &parent_fit_area, 0); + bool on1 = lv_area_is_in(&ori, &parent_fit_area, 0); if(!on1) lv_obj_scrollbar_invalidate(parent); /*Set the length and height @@ -196,7 +200,7 @@ bool lv_obj_refr_size(lv_obj_t * obj) /*If the object was out of the parent invalidate the new scrollbar area too. *If it wasn't out of the parent but out now, also invalidate the scrollbars*/ - bool on2 = _lv_area_is_in(&obj->coords, &parent_fit_area, 0); + bool on2 = lv_area_is_in(&obj->coords, &parent_fit_area, 0); if(on1 || (!on1 && on2)) lv_obj_scrollbar_invalidate(parent); lv_obj_refresh_ext_draw_size(obj); @@ -215,12 +219,12 @@ void lv_obj_set_size(lv_obj_t * obj, int32_t w, int32_t h) void lv_obj_set_width(lv_obj_t * obj, int32_t w) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_result_t res_w; + lv_style_res_t res_w; lv_style_value_t v_w; res_w = lv_obj_get_local_style_prop(obj, LV_STYLE_WIDTH, &v_w, 0); - if((res_w == LV_RESULT_OK && v_w.num != w) || res_w == LV_RESULT_INVALID) { + if((res_w == LV_STYLE_RES_FOUND && v_w.num != w) || res_w == LV_STYLE_RES_NOT_FOUND) { lv_obj_set_style_width(obj, w, 0); } } @@ -228,12 +232,12 @@ void lv_obj_set_width(lv_obj_t * obj, int32_t w) void lv_obj_set_height(lv_obj_t * obj, int32_t h) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_result_t res_h; + lv_style_res_t res_h; lv_style_value_t v_h; res_h = lv_obj_get_local_style_prop(obj, LV_STYLE_HEIGHT, &v_h, 0); - if((res_h == LV_RESULT_OK && v_h.num != h) || res_h == LV_RESULT_INVALID) { + if((res_h == LV_STYLE_RES_FOUND && v_h.num != h) || res_h == LV_STYLE_RES_NOT_FOUND) { lv_obj_set_style_height(obj, h, 0); } } @@ -450,6 +454,9 @@ void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, in x = lv_obj_get_width(base); y = lv_obj_get_height(base) - lv_obj_get_height(obj); break; + + case LV_ALIGN_DEFAULT: + break; } if(LV_COORD_IS_PCT(x_ofs)) x_ofs = (lv_obj_get_width(base) * LV_COORD_GET_PCT(x_ofs)) / 100; @@ -721,7 +728,7 @@ void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y) /*If the object is already out of the parent and its position is changes *surely the scrollbars also changes so invalidate them*/ - on1 = _lv_area_is_in(&ori, &parent_fit_area, 0); + on1 = lv_area_is_in(&ori, &parent_fit_area, 0); if(!on1) lv_obj_scrollbar_invalidate(parent); } @@ -741,7 +748,7 @@ void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y) /*If the object was out of the parent invalidate the new scrollbar area too. *If it wasn't out of the parent but out now, also invalidate the scrollbars*/ if(parent) { - bool on2 = _lv_area_is_in(&obj->coords, &parent_fit_area, 0); + bool on2 = lv_area_is_in(&obj->coords, &parent_fit_area, 0); if(on1 || (!on1 && on2)) lv_obj_scrollbar_invalidate(parent); } } @@ -771,7 +778,7 @@ void lv_obj_transform_point_array(const lv_obj_t * obj, lv_point_t points[], siz lv_obj_point_transform_flag_t flags) { if(obj) { - lv_layer_type_t layer_type = _lv_obj_get_layer_type(obj); + lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); bool do_tranf = layer_type == LV_LAYER_TYPE_TRANSFORM; bool recursive = flags & LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE; bool inverse = flags & LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE; @@ -814,13 +821,21 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area) lv_area_copy(&area_tmp, area); if(!lv_obj_area_is_visible(obj, &area_tmp)) return; +#if LV_DRAW_TRANSFORM_USE_MATRIX + /** + * When using the global matrix, the vertex coordinates of clip_area lose precision after transformation, + * which can be solved by expanding the redrawing area. + */ + lv_area_increase(&area_tmp, 5, 5); +#else if(obj->spec_attr && obj->spec_attr->layer_type == LV_LAYER_TYPE_TRANSFORM) { /*Make the area slightly larger to avoid rounding errors. *5 is an empirical value*/ lv_area_increase(&area_tmp, 5, 5); } +#endif - _lv_inv_area(lv_obj_get_display(obj), &area_tmp); + lv_inv_area(lv_obj_get_display(obj), &area_tmp); } void lv_obj_invalidate(const lv_obj_t * obj) @@ -829,7 +844,7 @@ void lv_obj_invalidate(const lv_obj_t * obj) /*Truncate the area to the object*/ lv_area_t obj_coords; - int32_t ext_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_size = lv_obj_get_ext_draw_size(obj); lv_area_copy(&obj_coords, &obj->coords); obj_coords.x1 -= ext_size; obj_coords.y1 -= ext_size; @@ -856,12 +871,12 @@ bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area) /*Truncate the area to the object*/ lv_area_t obj_coords; - int32_t ext_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_size = lv_obj_get_ext_draw_size(obj); lv_area_copy(&obj_coords, &obj->coords); lv_area_increase(&obj_coords, ext_size, ext_size); /*The area is not on the object*/ - if(!_lv_area_intersect(area, area, &obj_coords)) return false; + if(!lv_area_intersect(area, area, &obj_coords)) return false; lv_obj_get_transformed_area(obj, area, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE); @@ -874,12 +889,12 @@ bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area) /*Truncate to the parent and if no common parts break*/ lv_area_t parent_coords = parent->coords; if(lv_obj_has_flag(parent, LV_OBJ_FLAG_OVERFLOW_VISIBLE)) { - int32_t parent_ext_size = _lv_obj_get_ext_draw_size(parent); + int32_t parent_ext_size = lv_obj_get_ext_draw_size(parent); lv_area_increase(&parent_coords, parent_ext_size, parent_ext_size); } lv_obj_get_transformed_area(parent, &parent_coords, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE); - if(!_lv_area_intersect(area, area, &parent_coords)) return false; + if(!lv_area_intersect(area, area, &parent_coords)) return false; parent = lv_obj_get_parent(parent); } @@ -892,7 +907,7 @@ bool lv_obj_is_visible(const lv_obj_t * obj) LV_ASSERT_OBJ(obj, MY_CLASS); lv_area_t obj_coords; - int32_t ext_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_size = lv_obj_get_ext_draw_size(obj); lv_area_copy(&obj_coords, &obj->coords); obj_coords.x1 -= ext_size; obj_coords.y1 -= ext_size; @@ -924,7 +939,7 @@ bool lv_obj_hit_test(lv_obj_t * obj, const lv_point_t * point) lv_area_t a; lv_obj_get_click_area(obj, &a); - bool res = _lv_area_is_point_on(&a, point, 0); + bool res = lv_area_is_point_on(&a, point, 0); if(res == false) return false; if(lv_obj_has_flag(obj, LV_OBJ_FLAG_ADV_HITTEST)) { @@ -952,6 +967,11 @@ int32_t lv_clamp_height(int32_t height, int32_t min_height, int32_t max_height, return LV_CLAMP(min_height, height, max_height); } +void lv_obj_center(lv_obj_t * obj) +{ + lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -1118,7 +1138,7 @@ static void layout_update_core(lv_obj_t * obj) lv_obj_refr_pos(obj); if(child_cnt > 0) { - _lv_layout_apply(obj); + lv_layout_apply(obj); } } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h index eafc6f149..584f0b7e8 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h @@ -179,9 +179,9 @@ void lv_obj_set_align(lv_obj_t * obj, lv_align_t align); void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_ofs, int32_t y_ofs); /** - * Align an object to an other object. + * Align an object to another object. * @param obj pointer to an object to align - * @param base pointer to an other object (if NULL `obj`s parent is used). 'obj' will be aligned to it. + * @param base pointer to another object (if NULL `obj`s parent is used). 'obj' will be aligned to it. * @param align type of alignment (see 'lv_align_t' enum) * @param x_ofs x coordinate offset after alignment * @param y_ofs y coordinate offset after alignment @@ -195,10 +195,7 @@ void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, in * @param obj pointer to an object to align * @note if the parent size changes `obj` needs to be aligned manually again */ -static inline void lv_obj_center(lv_obj_t * obj) -{ - lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); -} +void lv_obj_center(lv_obj_t * obj); /** * Copy the coordinates of an object to an area @@ -256,14 +253,14 @@ int32_t lv_obj_get_y(const lv_obj_t * obj); int32_t lv_obj_get_y2(const lv_obj_t * obj); /** - * Get the actually set x coordinate of object, i.e. the offset form the set alignment + * Get the actually set x coordinate of object, i.e. the offset from the set alignment * @param obj pointer to an object * @return the set x coordinate */ int32_t lv_obj_get_x_aligned(const lv_obj_t * obj); /** - * Get the actually set y coordinate of object, i.e. the offset form the set alignment + * Get the actually set y coordinate of object, i.e. the offset from the set alignment * @param obj pointer to an object * @return the set y coordinate */ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h new file mode 100644 index 000000000..d9eee4939 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h @@ -0,0 +1,88 @@ +/** + * @file lv_obj_private.h + * + */ + +#ifndef LV_OBJ_PRIVATE_H +#define LV_OBJ_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Special, rarely used attributes. + * They are allocated automatically if any elements is set. + */ +struct lv_obj_spec_attr_t { + lv_obj_t ** children; /**< Store the pointer of the children in an array.*/ + lv_group_t * group_p; + lv_event_list_t event_list; + + lv_point_t scroll; /**< The current X/Y scroll offset*/ + + int32_t ext_click_pad; /**< Extra click padding in all direction*/ + int32_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/ + + uint16_t child_cnt; /**< Number of children*/ + uint16_t scrollbar_mode : 2; /**< How to display scrollbars, see `lv_scrollbar_mode_t`*/ + uint16_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally, see `lv_scroll_snap_t`*/ + uint16_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/ + uint16_t scroll_dir : 4; /**< The allowed scroll direction(s), see `lv_dir_t`*/ + uint16_t layer_type : 2; /**< Cache the layer type here. Element of lv_intermediate_layer_type_t */ +}; + +struct lv_obj_t { + const lv_obj_class_t * class_p; + lv_obj_t * parent; + lv_obj_spec_attr_t * spec_attr; + lv_obj_style_t * styles; +#if LV_OBJ_STYLE_CACHE + uint32_t style_main_prop_is_set; + uint32_t style_other_prop_is_set; +#endif + void * user_data; +#if LV_USE_OBJ_ID + void * id; +#endif + lv_area_t coords; + lv_obj_flag_t flags; + lv_state_t state; + uint16_t layout_inv : 1; + uint16_t readjust_scroll_after_layout : 1; + uint16_t scr_layout_inv : 1; + uint16_t skip_trans : 1; + uint16_t style_cnt : 6; + uint16_t h_layout : 1; + uint16_t w_layout : 1; + uint16_t is_deleting : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c index 20a2d25c1..f15ee1186 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c @@ -6,9 +6,12 @@ /********************* * INCLUDES *********************/ +#include "lv_obj_private.h" #include "../core/lv_obj.h" #include "../stdlib/lv_string.h" +#include "../misc/lv_utils.h" #include "lv_obj_property.h" +#include "lv_obj_class_private.h" #if LV_USE_OBJ_PROPERTY @@ -21,13 +24,19 @@ **********************/ typedef void (*lv_property_set_int_t)(lv_obj_t *, int32_t); -typedef void (*lv_property_set_pointer_t)(lv_obj_t *, const void *); +typedef void (*lv_property_set_bool_t)(lv_obj_t *, bool); +typedef void (*lv_property_set_precise_t)(lv_obj_t *, lv_value_precise_t); typedef void (*lv_property_set_color_t)(lv_obj_t *, lv_color_t); +typedef void (*lv_property_set_point_t)(lv_obj_t *, lv_point_t *); +typedef void (*lv_property_set_pointer_t)(lv_obj_t *, const void *); typedef lv_result_t (*lv_property_setter_t)(lv_obj_t *, lv_prop_id_t, const lv_property_t *); typedef int32_t (*lv_property_get_int_t)(const lv_obj_t *); -typedef void * (*lv_property_get_pointer_t)(const lv_obj_t *); +typedef bool (*lv_property_get_bool_t)(const lv_obj_t *); +typedef lv_value_precise_t (*lv_property_get_precise_t)(const lv_obj_t *); typedef lv_color_t (*lv_property_get_color_t)(const lv_obj_t *); +typedef lv_point_t (*lv_property_get_point_t)(lv_obj_t *); +typedef void * (*lv_property_get_pointer_t)(const lv_obj_t *); typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_property_t *); /********************** @@ -35,6 +44,7 @@ typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_p **********************/ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set); +static int32_t property_name_compare(const void * ref, const void * element); /********************** * STATIC VARIABLES @@ -52,13 +62,14 @@ lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value) { LV_ASSERT(obj && value); - if(value->id == LV_PROPERTY_ID_INVALID) { - LV_LOG_WARN("invalid property id set to %p\n", obj); + uint32_t index = LV_PROPERTY_ID_INDEX(value->id); + if(value->id == LV_PROPERTY_ID_INVALID || index > LV_PROPERTY_ID_ANY) { + LV_LOG_WARN("Invalid property id set to %p", obj); return LV_RESULT_INVALID; } - if(value->id < LV_PROPERTY_ID_START) { - lv_obj_set_local_style_prop(obj, value->id, value->_style, 0); + if(index < LV_PROPERTY_ID_START) { + lv_obj_set_local_style_prop(obj, index, value->style, value->selector); return LV_RESULT_OK; } @@ -80,28 +91,110 @@ lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, u lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id) { lv_result_t result; - lv_property_t value; + lv_property_t value = { 0 }; - if(id == LV_PROPERTY_ID_INVALID) { - LV_LOG_WARN("invalid property id to get from %p\n", obj); - value.id = 0; + uint32_t index = LV_PROPERTY_ID_INDEX(id); + if(id == LV_PROPERTY_ID_INVALID || index > LV_PROPERTY_ID_ANY) { + LV_LOG_WARN("Invalid property id to get from %p", obj); + value.id = LV_PROPERTY_ID_INVALID; value.num = 0; return value; } - if(id < LV_PROPERTY_ID_START) { - lv_obj_get_local_style_prop(obj, id, &value._style, 0); + if(index < LV_PROPERTY_ID_START) { + lv_obj_get_local_style_prop(obj, index, &value.style, 0); value.id = id; + value.selector = 0; return value; } result = obj_property(obj, id, &value, false); if(result != LV_RESULT_OK) - value.id = 0; + value.id = LV_PROPERTY_ID_INVALID; return value; } +lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector) +{ + lv_property_t value; + uint32_t index = LV_PROPERTY_ID_INDEX(id); + + if(index == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_START) { + LV_LOG_WARN("invalid style property id %d", id); + value.id = LV_PROPERTY_ID_INVALID; + value.num = 0; + return value; + } + + lv_obj_get_local_style_prop(obj, id, &value.style, selector); + value.id = id; + value.selector = selector; + return value; +} + +lv_prop_id_t lv_style_property_get_id(const char * name) +{ +#if LV_USE_OBJ_PROPERTY_NAME + lv_property_name_t * found; + /*Check style property*/ + found = lv_utils_bsearch(name, lv_style_property_names, sizeof(lv_style_property_names) / sizeof(lv_property_name_t), + sizeof(lv_property_name_t), property_name_compare); + if(found) return found->id; +#else + LV_UNUSED(name); +#endif + return LV_PROPERTY_ID_INVALID; +} + +lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name) +{ +#if LV_USE_OBJ_PROPERTY_NAME + const lv_property_name_t * names; + lv_property_name_t * found; + + names = clz->property_names; + if(names == NULL) { + /* try base class*/ + return LV_PROPERTY_ID_INVALID; + } + + found = lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare); + if(found) return found->id; +#else + LV_UNUSED(obj); + LV_UNUSED(name); + LV_UNUSED(property_name_compare); +#endif + return LV_PROPERTY_ID_INVALID; +} + +lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name) +{ +#if LV_USE_OBJ_PROPERTY_NAME + const lv_obj_class_t * clz; + lv_prop_id_t id; + + for(clz = obj->class_p; clz; clz = clz->base_class) { + id = lv_obj_class_property_get_id(clz, name); + if(id != LV_PROPERTY_ID_INVALID) return id; + } + + /*Check style property*/ + id = lv_style_property_get_id(name); + if(id != LV_PROPERTY_ID_INVALID) return id; +#else + LV_UNUSED(obj); + LV_UNUSED(name); + LV_UNUSED(property_name_compare); +#endif + return LV_PROPERTY_ID_INVALID; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set) { const lv_property_ops_t * properties; @@ -139,7 +232,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * /*id matched but we got null pointer to functions*/ if(set ? prop->setter == NULL : prop->getter == NULL) { - LV_LOG_WARN("null %s provided, id: %d\n", set ? "setter" : "getter", id); + LV_LOG_WARN("NULL %s provided, id: %d", set ? "setter" : "getter", id); return LV_RESULT_INVALID; } @@ -147,23 +240,47 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * if(!set) value->id = prop->id; switch(LV_PROPERTY_ID_TYPE(prop->id)) { - case LV_PROPERTY_TYPE_INT: - if(set)((lv_property_set_int_t)(prop->setter))(obj, value->num); - else value->num = ((lv_property_get_int_t)(prop->getter))(obj); - break; + case LV_PROPERTY_TYPE_INT: { + if(set)((lv_property_set_int_t)(prop->setter))(obj, value->num); + else value->num = ((lv_property_get_int_t)(prop->getter))(obj); + break; + } + case LV_PROPERTY_TYPE_BOOL: { + if(set)((lv_property_set_bool_t)(prop->setter))(obj, value->enable); + else value->enable = ((lv_property_get_bool_t)(prop->getter))(obj); + break; + } + + case LV_PROPERTY_TYPE_PRECISE: { + if(set)((lv_property_set_precise_t)(prop->setter))(obj, value->precise); + else value->precise = ((lv_property_get_precise_t)(prop->getter))(obj); + break; + } + case LV_PROPERTY_TYPE_COLOR: { + if(set)((lv_property_set_color_t)prop->setter)(obj, value->color); + else value->color = ((lv_property_get_color_t)(prop->getter))(obj); + break; + } + case LV_PROPERTY_TYPE_POINT: { + lv_point_t * point = &value->point; + if(set)((lv_property_set_point_t)(prop->setter))(obj, point); + else *point = ((lv_property_get_point_t)(prop->getter))(obj); + break; + } case LV_PROPERTY_TYPE_POINTER: case LV_PROPERTY_TYPE_IMGSRC: - if(set)((lv_property_set_pointer_t)(prop->setter))(obj, value->ptr); - else value->ptr = ((lv_property_get_pointer_t)(prop->getter))(obj); - break; - case LV_PROPERTY_TYPE_COLOR: - if(set)((lv_property_set_color_t)prop->setter)(obj, value->color); - else value->color = ((lv_property_get_color_t)(prop->getter))(obj); - break; - default: - LV_LOG_WARN("unknown property id: 0x%08x\n", prop->id); - return LV_RESULT_INVALID; - break; + case LV_PROPERTY_TYPE_TEXT: + case LV_PROPERTY_TYPE_OBJ: + case LV_PROPERTY_TYPE_DISPLAY: + case LV_PROPERTY_TYPE_FONT: { + if(set)((lv_property_set_pointer_t)(prop->setter))(obj, value->ptr); + else value->ptr = ((lv_property_get_pointer_t)(prop->getter))(obj); + break; + } + default: { + LV_LOG_WARN("Unknown property id: 0x%08x", prop->id); + return LV_RESULT_INVALID; + } } return LV_RESULT_OK; @@ -172,8 +289,14 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * /*If no setter found, try base class then*/ } - LV_LOG_WARN("unknown property id: 0x%08x\n", id); + LV_LOG_WARN("Unknown property id: 0x%08x", id); return LV_RESULT_INVALID; } +static int property_name_compare(const void * ref, const void * element) +{ + const lv_property_name_t * prop = element; + return lv_strcmp(ref, prop->name); +} + #endif /*LV_USE_OBJ_PROPERTY*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.h index ca3754ab3..4c8c142f4 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.h @@ -27,60 +27,100 @@ extern "C" { #define LV_PROPERTY_TYPE_INT 1 /*int32_t type*/ #define LV_PROPERTY_TYPE_PRECISE 2 /*lv_value_precise_t, int32_t or float depending on LV_USE_FLOAT*/ #define LV_PROPERTY_TYPE_COLOR 3 /*ARGB8888 type*/ -#define LV_PROPERTY_TYPE_POINTER 4 /*void * pointer*/ -#define LV_PROPERTY_TYPE_IMGSRC 5 /*Special pointer for image*/ +#define LV_PROPERTY_TYPE_POINT 4 /*lv_point_t */ +#define LV_PROPERTY_TYPE_POINTER 5 /*void * pointer*/ +#define LV_PROPERTY_TYPE_IMGSRC 6 /*Special pointer for image*/ +#define LV_PROPERTY_TYPE_TEXT 7 /*Special pointer of char* */ +#define LV_PROPERTY_TYPE_OBJ 8 /*Special pointer of lv_obj_t* */ +#define LV_PROPERTY_TYPE_DISPLAY 9 /*Special pointer of lv_display_t* */ +#define LV_PROPERTY_TYPE_FONT 10 /*Special pointer of lv_font_t* */ +#define LV_PROPERTY_TYPE_BOOL 11 /*int32_t type*/ -/********************** - * TYPEDEFS - **********************/ +#define LV_PROPERTY_TYPE_SHIFT 28 +#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT) -#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << 28) - -#define LV_PROPERTY_ID_TYPE(id) ((id) >> 28) +#define LV_PROPERTY_ID_TYPE(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) #define LV_PROPERTY_ID_INDEX(id) ((id) & 0xfffffff) /*Set properties from an array of lv_property_t*/ #define LV_OBJ_SET_PROPERTY_ARRAY(obj, array) lv_obj_set_properties(obj, array, sizeof(array)/sizeof(array[0])) + +/********************** + * TYPEDEFS + **********************/ + /** * Group of predefined widget ID start value. */ enum { - LV_PROPERTY_ID_INVALID = 0, + LV_PROPERTY_ID_INVALID = 0, - /*ID 0 to 0xff are style ID, check lv_style_prop_t*/ - LV_PROPERTY_ID_START = 0x100, /*ID little than 0xff is style ID*/ + /*ID 0x01 to 0xff are style ID, check lv_style_prop_t*/ + LV_PROPERTY_STYLE_START = 0x00, - /* lv_obj.c */ - LV_PROPERTY_OBJ_START = 1000, + LV_PROPERTY_ID_START = 0x0100, /*ID smaller than 0xff is style ID*/ + /*Define the property ID for every widget here. */ + LV_PROPERTY_OBJ_START = 0x0100, /* lv_obj.c */ + LV_PROPERTY_IMAGE_START = 0x0200, /* lv_image.c */ + LV_PROPERTY_LABEL_START = 0x0300, /* lv_label.c */ + LV_PROPERTY_KEYBOARD_START = 0x0400, /* lv_keyboard.c */ + LV_PROPERTY_TEXTAREA_START = 0x0500, /* lv_textarea.c */ + LV_PROPERTY_ROLLER_START = 0x0600, /* lv_roller.c */ + LV_PROPERTY_DROPDOWN_START = 0x0700, /* lv_dropdown.c */ - /* lv_image.c */ - LV_PROPERTY_IMAGE_START = 1100, + /*Special ID, use it to extend ID and make sure it's unique and compile time determinant*/ + LV_PROPERTY_ID_BUILTIN_LAST = 0xffff, /*ID of 0x10000 ~ 0xfffffff is reserved for user*/ - /*Special ID*/ - LV_PROPERTY_ID_BUILTIN_LAST, /*Use it to extend ID and make sure it's unique and compile time determinant*/ - - LV_PROPERTY_ID_ANY = 0x7ffffffe, /*Special ID used by lvgl to intercept all setter/getter call.*/ + LV_PROPERTY_ID_ANY = 0x7ffffffe, /*Special ID used by lvgl to intercept all setter/getter call.*/ }; -typedef uint32_t lv_prop_id_t; +struct lv_property_name_t { + const char * name; + lv_prop_id_t id; +}; typedef struct { lv_prop_id_t id; union { int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/ + bool enable; /**< booleans*/ const void * ptr; /**< Constant pointers (font, cone text, etc)*/ lv_color_t color; /**< Colors*/ lv_value_precise_t precise; /**< float or int for precise value*/ - lv_style_value_t _style; /**< A place holder for style value which is same as property value.*/ + lv_point_t point; /**< Point*/ + struct { + /** + * Note that place struct member `style` at first place is intended. + * `style` shares same memory with `num`, `ptr`, `color`. + * So we set the style value directly without using `prop.style.num`. + * + * E.g. + * + * static const lv_property_t obj_pos_x = { + * .id = LV_PROPERTY_STYLE_X, + * .num = 123, + * .selector = LV_STATE_PRESSED, + * } + * + * instead of: + * static const lv_property_t obj_pos_x = { + * .id = LV_PROPERTY_STYLE_X, + * .style.num = 123, // note this line. + * .selector = LV_STATE_PRESSED, + * } + */ + lv_style_value_t style; /**< Make sure it's the first element in struct. */ + uint32_t selector; /**< Style selector, lv_part_t | lv_state_t */ + }; }; } lv_property_t; typedef struct { lv_prop_id_t id; - void * setter; - void * getter; + void * setter; /**< Callback used to set property. */ + void * getter; /**< Callback used to get property. */ } lv_property_ops_t; /********************** @@ -92,14 +132,20 @@ typedef struct { *====================*/ /** - * Set widget property value. + * Set widget property. * @param obj pointer to an object - * @param id ID of which property * @param value The property value to set * @return return LV_RESULT_OK if success */ lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value); +/** + * Set multiple widget properties. Helper `LV_OBJ_SET_PROPERTY_ARRAY` can be used for constant property array. + * @param obj pointer to an object + * @param value The property value array to set + * @param count The count of the property value array + * @return return LV_RESULT_OK if success + */ lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count); /*===================== @@ -107,18 +153,53 @@ lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, u *====================*/ /** - * Read property value from object + * Read property value from object. + * If id is a style property, the style selector is default to 0. * @param obj pointer to an object - * @param id ID of which property - * @param value pointer to a buffer to store the value - * @return ? to be discussed, LV_RESULT_OK or LV_RESULT_INVALID + * @param id ID of which property to read + * @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed. */ lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id); +/** + * Read a style property value from object + * @param obj pointer to an object + * @param id ID of style property + * @param selector selector for the style property. + * @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed. + */ +lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector); + +/** + * Get the property ID by name recursively to base classes. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`. + * @param obj pointer to an object that has specified property or base class has. + * @param name property name + * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. + */ +lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name); + +/** + * Get the property ID by name without check base class recursively. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`. + * @param clz pointer to an object class that has specified property or base class has. + * @param name property name + * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. + */ +lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name); + +/** + * Get the style property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`. + * @param name property name + * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. + */ +lv_prop_id_t lv_style_property_get_id(const char * name); + /********************** * MACROS **********************/ +#include "../widgets/property/lv_obj_property_names.h" +#include "../widgets/property/lv_style_properties.h" + #endif /*LV_USE_OBJ_PROPERTY*/ #ifdef __cplusplus diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.c index 1add20222..fa5e16fc9 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.c @@ -6,11 +6,13 @@ /********************* * INCLUDES *********************/ -#include "lv_obj_scroll.h" -#include "lv_obj.h" +#include "lv_obj_scroll_private.h" +#include "../misc/lv_anim_private.h" +#include "lv_obj_private.h" #include "../indev/lv_indev.h" #include "../indev/lv_indev_scroll.h" #include "../display/lv_display.h" +#include "../misc/lv_area.h" /********************* * DEFINES @@ -33,7 +35,7 @@ **********************/ static void scroll_x_anim(void * obj, int32_t v); static void scroll_y_anim(void * obj, int32_t v); -static void scroll_completed_completed_cb(lv_anim_t * a); +static void scroll_end_cb(lv_anim_t * a); static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_point_t * scroll_value, lv_anim_enable_t anim_en); @@ -309,7 +311,7 @@ void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t a lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); - lv_anim_set_completed_cb(&a, scroll_completed_completed_cb); + lv_anim_set_deleted_cb(&a, scroll_end_cb); if(dx) { uint32_t t = lv_anim_speed_clamped((lv_display_get_horizontal_resolution(d)) >> 1, SCROLL_ANIM_TIME_MIN, @@ -350,7 +352,7 @@ void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t a res = lv_obj_send_event(obj, LV_EVENT_SCROLL_BEGIN, NULL); if(res != LV_RESULT_OK) return; - res = _lv_obj_scroll_by_raw(obj, dx, dy); + res = lv_obj_scroll_by_raw(obj, dx, dy); if(res != LV_RESULT_OK) return; res = lv_obj_send_event(obj, LV_EVENT_SCROLL_END, NULL); @@ -408,7 +410,7 @@ void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en) } } -lv_result_t _lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y) +lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y) { if(x == 0 && y == 0) return LV_RESULT_OK; @@ -440,6 +442,8 @@ void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en) lv_obj_update_layout(obj); lv_point_t p; lv_indev_scroll_get_snap_dist(obj, &p); + if(p.x == LV_COORD_MAX || p.x == LV_COORD_MIN) p.x = 0; + if(p.y == LV_COORD_MAX || p.y == LV_COORD_MIN) p.y = 0; lv_obj_scroll_by(obj, p.x, p.y, anim_en); } @@ -450,7 +454,7 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE) == false) return; - lv_dir_t sm = lv_obj_get_scrollbar_mode(obj); + lv_scrollbar_mode_t sm = lv_obj_get_scrollbar_mode(obj); if(sm == LV_SCROLLBAR_MODE_OFF) return; /*If there is no indev scrolling this object but `mode==active` return*/ @@ -667,17 +671,18 @@ void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en) static void scroll_x_anim(void * obj, int32_t v) { - _lv_obj_scroll_by_raw(obj, v + lv_obj_get_scroll_x(obj), 0); + lv_obj_scroll_by_raw(obj, v + lv_obj_get_scroll_x(obj), 0); } static void scroll_y_anim(void * obj, int32_t v) { - _lv_obj_scroll_by_raw(obj, 0, v + lv_obj_get_scroll_y(obj)); + lv_obj_scroll_by_raw(obj, 0, v + lv_obj_get_scroll_y(obj)); } -static void scroll_completed_completed_cb(lv_anim_t * a) +static void scroll_end_cb(lv_anim_t * a) { - lv_obj_send_event(a->var, LV_EVENT_SCROLL_END, NULL); + /*Do not sent END event if there wasn't a BEGIN*/ + if(a->start_cb_called) lv_obj_send_event(a->var, LV_EVENT_SCROLL_END, NULL); } static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_point_t * scroll_value, @@ -731,6 +736,8 @@ static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_p act = lv_area_get_height(area_tmp) / 2 + area_tmp->y1 + y_scroll; y_scroll += snap_goal - act; break; + case LV_SCROLL_SNAP_NONE: + break; } int32_t x_scroll = 0; @@ -773,16 +780,13 @@ static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_p act = lv_area_get_width(area_tmp) / 2 + area_tmp->x1 + x_scroll; x_scroll += snap_goal - act; break; + case LV_SCROLL_SNAP_NONE: + break; } /*Remove any pending scroll animations.*/ - bool y_del = lv_anim_delete(parent, scroll_y_anim); - bool x_del = lv_anim_delete(parent, scroll_x_anim); - if(y_del || x_del) { - lv_result_t res; - res = lv_obj_send_event(parent, LV_EVENT_SCROLL_END, NULL); - if(res != LV_RESULT_OK) return; - } + lv_anim_delete(parent, scroll_y_anim); + lv_anim_delete(parent, scroll_x_anim); if((scroll_dir & LV_DIR_LEFT) == 0 && x_scroll < 0) x_scroll = 0; if((scroll_dir & LV_DIR_RIGHT) == 0 && x_scroll > 0) x_scroll = 0; diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.h index 0114a3b65..f2cb2f103 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.h @@ -28,32 +28,20 @@ extern "C" { /*Can't include lv_obj.h because it includes this header file*/ /** Scrollbar modes: shows when should the scrollbars be visible*/ -enum _lv_scrollbar_mode_t { +typedef enum { LV_SCROLLBAR_MODE_OFF, /**< Never show scrollbars*/ LV_SCROLLBAR_MODE_ON, /**< Always show scrollbars*/ LV_SCROLLBAR_MODE_ACTIVE, /**< Show scroll bars when object is being scrolled*/ LV_SCROLLBAR_MODE_AUTO, /**< Show scroll bars when the content is large enough to be scrolled*/ -}; - -#ifdef DOXYGEN -typedef _lv_scrollbar_mode_t lv_scrollbar_mode_t; -#else -typedef uint8_t lv_scrollbar_mode_t; -#endif /*DOXYGEN*/ +} lv_scrollbar_mode_t; /** Scroll span align options. Tells where to align the snappable children when scroll stops.*/ -enum _lv_scroll_snap_t { +typedef enum { LV_SCROLL_SNAP_NONE, /**< Do not align, leave where it is*/ LV_SCROLL_SNAP_START, /**< Align to the left/top*/ LV_SCROLL_SNAP_END, /**< Align to the right/bottom*/ LV_SCROLL_SNAP_CENTER /**< Align to the center*/ -}; - -#ifdef DOXYGEN -typedef _lv_scroll_snap_t lv_scroll_snap_t; -#else -typedef uint8_t lv_scroll_snap_t; -#endif /*DOXYGEN*/ +} lv_scroll_snap_t; /********************** * GLOBAL PROTOTYPES @@ -105,7 +93,6 @@ lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const lv_obj_t * obj); /** * Get the object in which directions can be scrolled * @param obj pointer to an object - * @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t` */ lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj); @@ -257,17 +244,6 @@ void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en); */ void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en); -/** - * Low level function to scroll by given x and y coordinates. - * `LV_EVENT_SCROLL` is sent. - * @param obj pointer to an object to scroll - * @param x pixels to scroll horizontally - * @param y pixels to scroll vertically - * @return `LV_RESULT_INVALID`: to object was deleted in `LV_EVENT_SCROLL`; - * `LV_RESULT_OK`: if the object is still valid - */ -lv_result_t _lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y); - /** * Tell whether an object is being scrolled or not at this moment * @param obj pointer to an object diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll_private.h new file mode 100644 index 000000000..9ae6332d4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll_private.h @@ -0,0 +1,50 @@ +/** + * @file lv_obj_scroll_private.h + * + */ + +#ifndef LV_OBJ_SCROLL_PRIVATE_H +#define LV_OBJ_SCROLL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_scroll.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Low level function to scroll by given x and y coordinates. + * `LV_EVENT_SCROLL` is sent. + * @param obj pointer to an object to scroll + * @param x pixels to scroll horizontally + * @param y pixels to scroll vertically + * @return `LV_RESULT_INVALID`: to object was deleted in `LV_EVENT_SCROLL`; + * `LV_RESULT_OK`: if the object is still valid + */ +lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_SCROLL_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c index 2273c0e41..26bc39729 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c @@ -6,7 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_obj.h" +#include "lv_obj_private.h" +#include "../misc/lv_anim_private.h" +#include "lv_obj_style_private.h" +#include "lv_obj_class_private.h" #include "../display/lv_display.h" #include "../display/lv_display_private.h" #include "../misc/lv_color.h" @@ -49,7 +52,7 @@ typedef enum { * STATIC PROTOTYPES **********************/ static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector); -static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, uint32_t part); +static lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_part_t part); static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop, lv_style_value_t * v); static void report_style_change_core(void * style, lv_obj_t * obj); @@ -78,14 +81,14 @@ static lv_style_res_t get_selector_style_prop(const lv_obj_t * obj, lv_style_sel * GLOBAL FUNCTIONS **********************/ -void _lv_obj_style_init(void) +void lv_obj_style_init(void) { - _lv_ll_init(style_trans_ll_p, sizeof(trans_t)); + lv_ll_init(style_trans_ll_p, sizeof(trans_t)); } -void _lv_obj_style_deinit(void) +void lv_obj_style_deinit(void) { - _lv_ll_clear(style_trans_ll_p); + lv_ll_clear(style_trans_ll_p); if(_style_custom_prop_flag_lookup_table != NULL) { lv_free(_style_custom_prop_flag_lookup_table); _style_custom_prop_flag_lookup_table = NULL; @@ -120,7 +123,7 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto /*Allocate space for the new style and shift the rest of the style to the end*/ obj->style_cnt++; LV_ASSERT(obj->style_cnt != 0); - obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t)); + obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(lv_obj_style_t)); LV_ASSERT_MALLOC(obj->styles); uint32_t j; @@ -128,7 +131,7 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto obj->styles[j] = obj->styles[j - 1]; } - lv_memzero(&obj->styles[i], sizeof(_lv_obj_style_t)); + lv_memzero(&obj->styles[i], sizeof(lv_obj_style_t)); obj->styles[i].style = style; obj->styles[i].selector = selector; @@ -136,8 +139,8 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto uint32_t * prop_is_set = part == LV_PART_MAIN ? &obj->style_main_prop_is_set : &obj->style_other_prop_is_set; if(lv_style_is_const(style)) { lv_style_const_prop_t * props = style->values_and_props; - for(i = 0; props[i].prop_ptr; i++) { - (*prop_is_set) |= STYLE_PROP_SHIFTED(*props[i].prop_ptr); + for(i = 0; props[i].prop != LV_STYLE_PROP_INV; i++) { + (*prop_is_set) |= STYLE_PROP_SHIFTED(props[i].prop); } } else { @@ -183,7 +186,7 @@ bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv continue; } - lv_memzero(&obj->styles[i], sizeof(_lv_obj_style_t)); + lv_memzero(&obj->styles[i], sizeof(lv_obj_style_t)); obj->styles[i].style = new_style; obj->styles[i].selector = selector; @@ -237,7 +240,7 @@ void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_sele } obj->style_cnt--; - obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t)); + obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(lv_obj_style_t)); deleted = true; /*The style from the current `i` index is removed, so `i` points to the next style. @@ -300,7 +303,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style /*Cache the layer type*/ if((part == LV_PART_ANY || part == LV_PART_MAIN) && is_layer_refr) { - _lv_obj_update_layer_type(obj); + lv_obj_update_layer_type(obj); } if(prop == LV_STYLE_PROP_ANY || is_ext_draw) { @@ -409,8 +412,8 @@ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_sty return res; } -void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, lv_state_t new_state, - const _lv_obj_style_transition_dsc_t * tr_dsc) +void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, lv_state_t new_state, + const lv_obj_style_transition_dsc_t * tr_dsc) { trans_t * tr; @@ -427,8 +430,9 @@ void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t v1 = lv_obj_get_style_prop(obj, part, tr_dsc->prop); obj->state = new_state; - _lv_obj_style_t * style_trans = get_trans_style(obj, part); + lv_obj_style_t * style_trans = get_trans_style(obj, part); lv_style_set_prop((lv_style_t *)style_trans->style, tr_dsc->prop, v1); /*Be sure `trans_style` has a valid value*/ + lv_obj_refresh_style(obj, tr_dsc->selector, tr_dsc->prop); if(tr_dsc->prop == LV_STYLE_RADIUS) { if(v1.num == LV_RADIUS_CIRCLE || v2.num == LV_RADIUS_CIRCLE) { @@ -439,7 +443,7 @@ void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t } } - tr = _lv_ll_ins_head(style_trans_ll_p); + tr = lv_ll_ins_head(style_trans_ll_p); LV_ASSERT_MALLOC(tr); if(tr == NULL) return; tr->start_value = v1; @@ -463,7 +467,7 @@ void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t lv_anim_start(&a); } -lv_style_value_t _lv_obj_style_apply_color_filter(const lv_obj_t * obj, uint32_t part, lv_style_value_t v) +lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v) { if(obj == NULL) return v; const lv_color_filter_dsc_t * f = lv_obj_get_style_color_filter_dsc(obj, part); @@ -474,9 +478,9 @@ lv_style_value_t _lv_obj_style_apply_color_filter(const lv_obj_t * obj, uint32_t return v; } -_lv_style_state_cmp_t _lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2) +lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2) { - _lv_style_state_cmp_t res = _LV_STYLE_STATE_CMP_SAME; + lv_style_state_cmp_t res = LV_STYLE_STATE_CMP_SAME; /*Are there any new styles for the new state?*/ uint32_t i; @@ -510,25 +514,25 @@ _lv_style_state_cmp_t _lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t sta else if(lv_style_get_prop(style, LV_STYLE_BORDER_WIDTH, &v)) layout_diff = true; if(layout_diff) { - return _LV_STYLE_STATE_CMP_DIFF_LAYOUT; + return LV_STYLE_STATE_CMP_DIFF_LAYOUT; } /*Check for draw pad changes*/ - if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_HEIGHT, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_ROTATION, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_SCALE_X, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_SCALE_Y, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_OPA, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_PAD, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_SHADOW_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OPA, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OFFSET_X, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OFFSET_Y, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_SHADOW_SPREAD, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(lv_style_get_prop(style, LV_STYLE_LINE_WIDTH, &v)) res = _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; - else if(res == _LV_STYLE_STATE_CMP_SAME) res = _LV_STYLE_STATE_CMP_DIFF_REDRAW; + if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_WIDTH, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_HEIGHT, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_ROTATION, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_SCALE_X, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_TRANSFORM_SCALE_Y, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_OPA, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_PAD, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_OUTLINE_WIDTH, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_SHADOW_WIDTH, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OPA, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OFFSET_X, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_SHADOW_OFFSET_Y, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_SHADOW_SPREAD, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(lv_style_get_prop(style, LV_STYLE_LINE_WIDTH, &v)) res = LV_STYLE_STATE_CMP_DIFF_DRAW_PAD; + else if(res == LV_STYLE_STATE_CMP_SAME) res = LV_STYLE_STATE_CMP_DIFF_REDRAW; } } @@ -601,7 +605,7 @@ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) return opa_final; } -void _lv_obj_update_layer_type(lv_obj_t * obj) +void lv_obj_update_layer_type(lv_obj_t * obj) { lv_layer_type_t layer_type = calculate_layer_type(obj); if(obj->spec_attr) obj->spec_attr->layer_type = layer_type; @@ -634,7 +638,7 @@ static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector obj->style_cnt++; LV_ASSERT(obj->style_cnt != 0); - obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t)); + obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(lv_obj_style_t)); LV_ASSERT_MALLOC(obj->styles); for(i = obj->style_cnt - 1; i > 0 ; i--) { @@ -644,7 +648,7 @@ static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector obj->styles[i] = obj->styles[i - 1]; } - lv_memzero(&obj->styles[i], sizeof(_lv_obj_style_t)); + lv_memzero(&obj->styles[i], sizeof(lv_obj_style_t)); obj->styles[i].style = lv_malloc(sizeof(lv_style_t)); lv_style_init((lv_style_t *)obj->styles[i].style); @@ -660,7 +664,7 @@ static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector * @param selector OR-ed value of parts and state for which the style should be get * @return pointer to the transition style */ -static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t selector) +static lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t selector) { uint32_t i; for(i = 0; i < obj->style_cnt; i++) { @@ -672,13 +676,13 @@ static _lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t se obj->style_cnt++; LV_ASSERT(obj->style_cnt != 0); - obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(_lv_obj_style_t)); + obj->styles = lv_realloc(obj->styles, obj->style_cnt * sizeof(lv_obj_style_t)); for(i = obj->style_cnt - 1; i > 0 ; i--) { obj->styles[i] = obj->styles[i - 1]; } - lv_memzero(&obj->styles[0], sizeof(_lv_obj_style_t)); + lv_memzero(&obj->styles[0], sizeof(lv_obj_style_t)); obj->styles[0].style = lv_malloc(sizeof(lv_style_t)); lv_style_init((lv_style_t *)obj->styles[0].style); @@ -691,7 +695,7 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t se lv_style_value_t * v) { - const uint32_t group = (uint32_t)1 << _lv_style_get_prop_group(prop); + const uint32_t group = (uint32_t)1 << lv_style_get_prop_group(prop); const lv_part_t part = lv_obj_style_get_selector_part(selector); const lv_state_t state = lv_obj_style_get_selector_state(selector); const lv_state_t state_inv = ~state; @@ -700,7 +704,7 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t se lv_style_res_t found; uint32_t i; for(i = 0; i < obj->style_cnt; i++) { - _lv_obj_style_t * obj_style = &obj->styles[i]; + lv_obj_style_t * obj_style = &obj->styles[i]; if(obj_style->is_trans == false) break; if(skip_trans) continue; @@ -716,7 +720,7 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t se for(; i < obj->style_cnt; i++) { if((obj->styles[i].style->has_group & group) == 0) continue; - _lv_obj_style_t * obj_style = &obj->styles[i]; + lv_obj_style_t * obj_style = &obj->styles[i]; lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector); if(part_act != part) continue; @@ -784,7 +788,7 @@ static void refresh_children_style(lv_obj_t * obj) /** * Remove the transition from object's part's property. - * - Remove the transition from `_lv_obj_style_trans_ll` and free it + * - Remove the transition from `lv_obj_style_trans_ll` and free it * - Delete pending transitions * @param obj pointer to an object which transition(s) should be removed * @param part a part of object or 0xFF to remove from all parts @@ -796,12 +800,12 @@ static bool trans_delete(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, t trans_t * tr; trans_t * tr_prev; bool removed = false; - tr = _lv_ll_get_tail(style_trans_ll_p); + tr = lv_ll_get_tail(style_trans_ll_p); while(tr != NULL) { if(tr == tr_limit) break; /*'tr' might be deleted, so get the next object while 'tr' is valid*/ - tr_prev = _lv_ll_get_prev(style_trans_ll_p, tr); + tr_prev = lv_ll_get_prev(style_trans_ll_p, tr); if(tr->obj == obj && (part == tr->selector || part == LV_PART_ANY) && (prop == tr->prop || prop == LV_STYLE_PROP_ANY)) { /*Remove any transitioned properties from the trans. style @@ -815,7 +819,7 @@ static bool trans_delete(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop, t /*Free the transition descriptor too*/ lv_anim_delete(tr, NULL); - _lv_ll_remove(style_trans_ll_p, tr); + lv_ll_remove(style_trans_ll_p, tr); lv_free(tr); removed = true; @@ -905,9 +909,10 @@ static void trans_anim_start_cb(lv_anim_t * a) tr->prop = prop_tmp; - _lv_obj_style_t * style_trans = get_trans_style(tr->obj, tr->selector); - lv_style_set_prop((lv_style_t *)style_trans->style, tr->prop, - tr->start_value); /*Be sure `trans_style` has a valid value*/ + lv_obj_style_t * style_trans = get_trans_style(tr->obj, tr->selector); + /*Be sure `trans_style` has a valid value*/ + lv_style_set_prop((lv_style_t *)style_trans->style, tr->prop, tr->start_value); + lv_obj_refresh_style(tr->obj, tr->selector, tr->prop); } @@ -922,7 +927,7 @@ static void trans_anim_completed_cb(lv_anim_t * a) *It allows changing it by normal styles*/ bool running = false; trans_t * tr_i; - _LV_LL_READ(style_trans_ll_p, tr_i) { + LV_LL_READ(style_trans_ll_p, tr_i) { if(tr_i != tr && tr_i->obj == tr->obj && tr_i->selector == tr->selector && tr_i->prop == tr->prop) { running = true; break; @@ -933,10 +938,10 @@ static void trans_anim_completed_cb(lv_anim_t * a) uint32_t i; for(i = 0; i < obj->style_cnt; i++) { if(obj->styles[i].is_trans && obj->styles[i].selector == tr->selector) { - _lv_ll_remove(style_trans_ll_p, tr); + lv_ll_remove(style_trans_ll_p, tr); lv_free(tr); - _lv_obj_style_t * obj_style = &obj->styles[i]; + lv_obj_style_t * obj_style = &obj->styles[i]; lv_style_remove_prop((lv_style_t *)obj_style->style, prop); if(lv_style_is_empty(obj->styles[i].style)) { @@ -974,8 +979,8 @@ static void full_cache_refresh(lv_obj_t * obj, lv_part_t part) uint32_t j; if(lv_style_is_const(style)) { lv_style_const_prop_t * props = style->values_and_props; - for(j = 0; props[j].prop_ptr; j++) { - obj->style_main_prop_is_set |= STYLE_PROP_SHIFTED(*props[j].prop_ptr); + for(j = 0; props[j].prop != LV_STYLE_PROP_INV; j++) { + obj->style_main_prop_is_set |= STYLE_PROP_SHIFTED(props[j].prop); } } else { @@ -994,8 +999,8 @@ static void full_cache_refresh(lv_obj_t * obj, lv_part_t part) uint32_t j; if(lv_style_is_const(style)) { lv_style_const_prop_t * props = style->values_and_props; - for(j = 0; props[j].prop_ptr; j++) { - obj->style_other_prop_is_set |= STYLE_PROP_SHIFTED(*props[j].prop_ptr); + for(j = 0; props[j].prop != LV_STYLE_PROP_INV; j++) { + obj->style_other_prop_is_set |= STYLE_PROP_SHIFTED(props[j].prop); } } else { @@ -1027,8 +1032,8 @@ static bool style_has_flag(const lv_style_t * style, uint32_t flag) if(lv_style_is_const(style)) { lv_style_const_prop_t * props = style->values_and_props; uint32_t i; - for(i = 0; props[i].prop_ptr; i++) { - if(lv_style_prop_has_flag(*props[i].prop_ptr, flag)) { + for(i = 0; props[i].prop != LV_STYLE_PROP_INV; i++) { + if(lv_style_prop_has_flag(props[i].prop, flag)) { return true; } } @@ -1061,14 +1066,14 @@ static lv_style_res_t get_selector_style_prop(const lv_obj_t * obj, lv_style_sel if(found == LV_STYLE_RES_FOUND) return LV_STYLE_RES_FOUND; } - extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[]; + extern const uint8_t lv_style_builtin_prop_flag_lookup_table[]; bool inheritable = false; - if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS) { - inheritable = _lv_style_builtin_prop_flag_lookup_table[prop] & LV_STYLE_PROP_FLAG_INHERITABLE; + if(prop < LV_STYLE_NUM_BUILT_IN_PROPS) { + inheritable = lv_style_builtin_prop_flag_lookup_table[prop] & LV_STYLE_PROP_FLAG_INHERITABLE; } else { if(_style_custom_prop_flag_lookup_table != NULL) { - inheritable = _style_custom_prop_flag_lookup_table[prop - _LV_STYLE_NUM_BUILT_IN_PROPS] & + inheritable = _style_custom_prop_flag_lookup_table[prop - LV_STYLE_NUM_BUILT_IN_PROPS] & LV_STYLE_PROP_FLAG_INHERITABLE; } } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.h index 56639492f..ff4e365d8 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.h @@ -13,10 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include #include "../misc/lv_bidi.h" #include "../misc/lv_style.h" +#include "../misc/lv_types.h" /********************* * DEFINES @@ -25,67 +24,32 @@ extern "C" { /********************** * TYPEDEFS **********************/ -/*Can't include lv_obj.h because it includes this header file*/ - -#ifndef LV_OBJ_H -/// @cond -/** - * Tells Doxygen to ignore a duplicate declaration - */ -typedef uint32_t lv_part_t; -typedef uint16_t lv_state_t; -/// @endcond - -#endif typedef enum { - _LV_STYLE_STATE_CMP_SAME, /*The style properties in the 2 states are identical*/ - _LV_STYLE_STATE_CMP_DIFF_REDRAW, /*The differences can be shown with a simple redraw*/ - _LV_STYLE_STATE_CMP_DIFF_DRAW_PAD, /*The differences can be shown with a simple redraw*/ - _LV_STYLE_STATE_CMP_DIFF_LAYOUT, /*The differences can be shown with a simple redraw*/ -} _lv_style_state_cmp_t; + LV_STYLE_STATE_CMP_SAME, /**< The style properties in the 2 states are identical */ + LV_STYLE_STATE_CMP_DIFF_REDRAW, /**< The differences can be shown with a simple redraw */ + LV_STYLE_STATE_CMP_DIFF_DRAW_PAD, /**< The differences can be shown with a simple redraw */ + LV_STYLE_STATE_CMP_DIFF_LAYOUT, /**< The differences can be shown with a simple redraw */ +} lv_style_state_cmp_t; typedef uint32_t lv_style_selector_t; -typedef struct { - const lv_style_t * style; - uint32_t selector : 24; - uint32_t is_local : 1; - uint32_t is_trans : 1; -} _lv_obj_style_t; - -typedef struct { - uint16_t time; - uint16_t delay; - lv_style_selector_t selector; - lv_style_prop_t prop; - lv_anim_path_cb_t path_cb; - void * user_data; -} _lv_obj_style_transition_dsc_t; - /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Initialize the object related style manager module. - * Called by LVGL in `lv_init()` - */ -void _lv_obj_style_init(void); - -/** - * Deinitialize the object related style manager module. - * Called by LVGL in `lv_deinit()` - */ -void _lv_obj_style_deinit(void); - /** * Add a style to an object. * @param obj pointer to an object * @param style pointer to a style to add * @param selector OR-ed value of parts and state to which the style should be added - * @example lv_obj_add_style(btn, &style_btn, 0); //Default button style - * @example lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed + * + * Examples: + * @code + * lv_obj_add_style(btn, &style_btn, 0); //Default button style + * + * lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed + * @endcode */ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector); @@ -95,8 +59,13 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto * @param old_style pointer to a style to replace. * @param new_style pointer to a style to replace the old style with. * @param selector OR-ed values of states and a part to replace only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used - * @example lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_ANY | LV_STATE_ANY); //Replace a specific style - * @example lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_MAIN | LV_STATE_PRESSED); //Replace a specific style assigned to the main part when it is pressed + * + * Examples: + * @code + * lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_ANY | LV_STATE_ANY); //Replace a specific style + * + * lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_MAIN | LV_STATE_PRESSED); //Replace a specific style assigned to the main part when it is pressed + * @endcode */ bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv_style_t * new_style, lv_style_selector_t selector); @@ -106,9 +75,15 @@ bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv * @param obj pointer to an object * @param style pointer to a style to remove. Can be NULL to check only the selector * @param selector OR-ed values of states and a part to remove only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used - * @example lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style - * @example lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part - * @example lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles + * + * Examples: + * @code + * lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style + * + * lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part + * + * lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles + * @endcode */ void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector); @@ -188,27 +163,7 @@ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_sty /** * Used internally for color filtering */ -lv_style_value_t _lv_obj_style_apply_color_filter(const lv_obj_t * obj, uint32_t part, lv_style_value_t v); - -/** - * Used internally to create a style transition - * @param obj - * @param part - * @param prev_state - * @param new_state - * @param tr - */ -void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, - lv_state_t new_state, const _lv_obj_style_transition_dsc_t * tr); - -/** - * Used internally to compare the appearance of an object in 2 states - * @param obj - * @param state1 - * @param state2 - * @return - */ -_lv_style_state_cmp_t _lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2); +lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v); /** * Fade in an an object and all its children. @@ -298,7 +253,7 @@ static inline void lv_obj_set_style_transform_scale(lv_obj_t * obj, int32_t valu lv_obj_set_style_transform_scale_y(obj, value, selector); } -static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, lv_part_t part) { int32_t padding = lv_obj_get_style_pad_left(obj, part); int32_t border_width = lv_obj_get_style_border_width(obj, part); @@ -306,7 +261,7 @@ static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, uint32_t return (border_side & LV_BORDER_SIDE_LEFT) ? padding + border_width : padding; } -static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, lv_part_t part) { int32_t padding = lv_obj_get_style_pad_right(obj, part); int32_t border_width = lv_obj_get_style_border_width(obj, part); @@ -314,7 +269,7 @@ static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, uint32_ return (border_side & LV_BORDER_SIDE_RIGHT) ? padding + border_width : padding; } -static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, lv_part_t part) { int32_t padding = lv_obj_get_style_pad_top(obj, part); int32_t border_width = lv_obj_get_style_border_width(obj, part); @@ -322,7 +277,7 @@ static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, uint32_t return (border_side & LV_BORDER_SIDE_TOP) ? padding + border_width : padding; } -static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, lv_part_t part) { int32_t padding = lv_obj_get_style_pad_bottom(obj, part); int32_t border_width = lv_obj_get_style_border_width(obj, part); @@ -332,16 +287,16 @@ static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, uint32 lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_t part, const char * txt); -static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, lv_part_t part) { - int16_t zoom = lv_obj_get_style_transform_scale_x(obj, part); - return zoom != 0 ? zoom : 1; + int32_t scale = lv_obj_get_style_transform_scale_x(obj, part); + return scale > 0 ? scale : 1; } -static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, lv_part_t part) { - int16_t zoom = lv_obj_get_style_transform_scale_y(obj, part); - return zoom != 0 ? zoom : 1; + int32_t scale = lv_obj_get_style_transform_scale_y(obj, part); + return scale > 0 ? scale : 1; } /** @@ -352,13 +307,6 @@ static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * o */ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part); -/** - * Update the layer type of a widget bayed on its current styles. - * The result will be stored in `obj->spec_attr->layer_type` - * @param obj the object whose layer should be updated - */ -void _lv_obj_update_layer_type(lv_obj_t * obj); - /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.c index f9b21e807..ad97db594 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.c @@ -754,7 +754,7 @@ void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_sel lv_obj_set_local_style_prop(obj, LV_STYLE_BASE_DIR, v, selector); } -void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const lv_image_dsc_t * value, lv_style_selector_t selector) +void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector) { lv_style_value_t v = { .ptr = value diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.h index c3bd10761..77cf53785 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_gen.h @@ -17,663 +17,670 @@ extern "C" { #include "../misc/lv_area.h" #include "../misc/lv_style.h" #include "../core/lv_obj_style.h" +#include "../misc/lv_types.h" -static inline int32_t lv_obj_get_style_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_min_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_min_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_max_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_max_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_height(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_height(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_HEIGHT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_HEIGHT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_max_height(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_max_height(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_HEIGHT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_length(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_length(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LENGTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_x(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_x(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_X); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_y(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_y(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_Y); return (int32_t)v.num; } -static inline lv_align_t lv_obj_get_style_align(const lv_obj_t * obj, uint32_t part) +static inline lv_align_t lv_obj_get_style_align(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ALIGN); return (lv_align_t)v.num; } -static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_height(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_height(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_HEIGHT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_translate_x(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_translate_x(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_X); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_Y); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_scale_x(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_scale_x(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SCALE_X); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_scale_y(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_scale_y(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SCALE_Y); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_rotation(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_rotation(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_ROTATION); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_pivot_x(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_pivot_x(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_X); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_pivot_y(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_pivot_y(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_Y); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_skew_x(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_skew_x(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SKEW_X); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_transform_skew_y(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_transform_skew_y(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SKEW_Y); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_pad_top(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_pad_top(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_TOP); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_pad_bottom(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_pad_bottom(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_BOTTOM); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_LEFT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_pad_right(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_pad_right(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_RIGHT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_pad_row(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_pad_row(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_ROW); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_COLUMN); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_margin_top(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_margin_top(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_TOP); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_margin_bottom(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_margin_bottom(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_BOTTOM); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_margin_left(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_margin_left(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_LEFT); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_margin_right(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_margin_right(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_RIGHT); return (int32_t)v.num; } -static inline lv_color_t lv_obj_get_style_bg_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_bg_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_bg_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_bg_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_bg_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_bg_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_OPA); return (lv_opa_t)v.num; } -static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BG_GRAD_COLOR)); return v.color; } -static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const lv_obj_t * obj, uint32_t part) +static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_DIR); return (lv_grad_dir_t)v.num; } -static inline int32_t lv_obj_get_style_bg_main_stop(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_bg_main_stop(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_STOP); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_bg_grad_stop(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_bg_grad_stop(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_STOP); return (int32_t)v.num; } -static inline lv_opa_t lv_obj_get_style_bg_main_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_bg_main_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_OPA); return (lv_opa_t)v.num; } -static inline lv_opa_t lv_obj_get_style_bg_grad_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_bg_grad_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_OPA); return (lv_opa_t)v.num; } -static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const lv_obj_t * obj, uint32_t part) +static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD); return (const lv_grad_dsc_t *)v.ptr; } -static inline const void * lv_obj_get_style_bg_image_src(const lv_obj_t * obj, uint32_t part) +static inline const void * lv_obj_get_style_bg_image_src(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_SRC); return (const void *)v.ptr; } -static inline lv_opa_t lv_obj_get_style_bg_image_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_bg_image_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_OPA); return (lv_opa_t)v.num; } -static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BG_IMAGE_RECOLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_bg_image_recolor_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_bg_image_recolor_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR_OPA); return (lv_opa_t)v.num; } -static inline bool lv_obj_get_style_bg_image_tiled(const lv_obj_t * obj, uint32_t part) +static inline bool lv_obj_get_style_bg_image_tiled(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_TILED); return (bool)v.num; } -static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_BORDER_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_border_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_border_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_OPA); return (lv_opa_t)v.num; } -static inline int32_t lv_obj_get_style_border_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_border_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_WIDTH); return (int32_t)v.num; } -static inline lv_border_side_t lv_obj_get_style_border_side(const lv_obj_t * obj, uint32_t part) +static inline lv_border_side_t lv_obj_get_style_border_side(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_SIDE); return (lv_border_side_t)v.num; } -static inline bool lv_obj_get_style_border_post(const lv_obj_t * obj, uint32_t part) +static inline bool lv_obj_get_style_border_post(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_POST); return (bool)v.num; } -static inline int32_t lv_obj_get_style_outline_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_outline_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_WIDTH); return (int32_t)v.num; } -static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_OUTLINE_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_outline_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_outline_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_OPA); return (lv_opa_t)v.num; } -static inline int32_t lv_obj_get_style_outline_pad(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_outline_pad(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_PAD); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_shadow_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_shadow_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_shadow_offset_x(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_shadow_offset_x(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFFSET_X); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_shadow_offset_y(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_shadow_offset_y(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFFSET_Y); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_shadow_spread(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_shadow_spread(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_SPREAD); return (int32_t)v.num; } -static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_SHADOW_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_shadow_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_shadow_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OPA); return (lv_opa_t)v.num; } -static inline lv_opa_t lv_obj_get_style_image_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_image_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_OPA); return (lv_opa_t)v.num; } -static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, + LV_STYLE_IMAGE_RECOLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR_OPA); return (lv_opa_t)v.num; } -static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_line_dash_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_line_dash_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_WIDTH); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_line_dash_gap(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_line_dash_gap(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_GAP); return (int32_t)v.num; } -static inline bool lv_obj_get_style_line_rounded(const lv_obj_t * obj, uint32_t part) +static inline bool lv_obj_get_style_line_rounded(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_ROUNDED); return (bool)v.num; } -static inline lv_color_t lv_obj_get_style_line_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_line_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_line_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_line_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_line_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_line_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_OPA); return (lv_opa_t)v.num; } -static inline int32_t lv_obj_get_style_arc_width(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_arc_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_WIDTH); return (int32_t)v.num; } -static inline bool lv_obj_get_style_arc_rounded(const lv_obj_t * obj, uint32_t part) +static inline bool lv_obj_get_style_arc_rounded(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_ROUNDED); return (bool)v.num; } -static inline lv_color_t lv_obj_get_style_arc_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_arc_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_arc_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_arc_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_arc_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_arc_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_OPA); return (lv_opa_t)v.num; } -static inline const void * lv_obj_get_style_arc_image_src(const lv_obj_t * obj, uint32_t part) +static inline const void * lv_obj_get_style_arc_image_src(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_IMAGE_SRC); return (const void *)v.ptr; } -static inline lv_color_t lv_obj_get_style_text_color(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_text_color(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR); return v.color; } -static inline lv_color_t lv_obj_get_style_text_color_filtered(const lv_obj_t * obj, uint32_t part) +static inline lv_color_t lv_obj_get_style_text_color_filtered(const lv_obj_t * obj, lv_part_t part) { - lv_style_value_t v = _lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR)); + lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR)); return v.color; } -static inline lv_opa_t lv_obj_get_style_text_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_text_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_OPA); return (lv_opa_t)v.num; } -static inline const lv_font_t * lv_obj_get_style_text_font(const lv_obj_t * obj, uint32_t part) +static inline const lv_font_t * lv_obj_get_style_text_font(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_FONT); return (const lv_font_t *)v.ptr; } -static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LETTER_SPACE); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_text_line_space(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_text_line_space(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LINE_SPACE); return (int32_t)v.num; } -static inline lv_text_decor_t lv_obj_get_style_text_decor(const lv_obj_t * obj, uint32_t part) +static inline lv_text_decor_t lv_obj_get_style_text_decor(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_DECOR); return (lv_text_decor_t)v.num; } -static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, uint32_t part) +static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_ALIGN); return (lv_text_align_t)v.num; } -static inline int32_t lv_obj_get_style_radius(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_radius(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_RADIUS); return (int32_t)v.num; } -static inline bool lv_obj_get_style_clip_corner(const lv_obj_t * obj, uint32_t part) +static inline bool lv_obj_get_style_clip_corner(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_CLIP_CORNER); return (bool)v.num; } -static inline lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA); return (lv_opa_t)v.num; } -static inline lv_opa_t lv_obj_get_style_opa_layered(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_opa_layered(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA_LAYERED); return (lv_opa_t)v.num; } -static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const lv_obj_t * obj, uint32_t part) +static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC); return (const lv_color_filter_dsc_t *)v.ptr; } -static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, uint32_t part) +static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_OPA); return (lv_opa_t)v.num; } -static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, uint32_t part) +static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM); return (const lv_anim_t *)v.ptr; } -static inline uint32_t lv_obj_get_style_anim_duration(const lv_obj_t * obj, uint32_t part) +static inline uint32_t lv_obj_get_style_anim_duration(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM_DURATION); return (uint32_t)v.num; } -static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const lv_obj_t * obj, uint32_t part) +static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSITION); return (const lv_style_transition_dsc_t *)v.ptr; } -static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const lv_obj_t * obj, uint32_t part) +static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLEND_MODE); return (lv_blend_mode_t)v.num; } -static inline uint16_t lv_obj_get_style_layout(const lv_obj_t * obj, uint32_t part) +static inline uint16_t lv_obj_get_style_layout(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LAYOUT); return (uint16_t)v.num; } -static inline lv_base_dir_t lv_obj_get_style_base_dir(const lv_obj_t * obj, uint32_t part) +static inline lv_base_dir_t lv_obj_get_style_base_dir(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BASE_DIR); return (lv_base_dir_t)v.num; } -static inline const lv_image_dsc_t * lv_obj_get_style_bitmap_mask_src(const lv_obj_t * obj, uint32_t part) +static inline const void * lv_obj_get_style_bitmap_mask_src(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BITMAP_MASK_SRC); - return (const lv_image_dsc_t *)v.ptr; + return (const void *)v.ptr; } -static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, uint32_t part) +static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ROTARY_SENSITIVITY); return (uint32_t)v.num; } #if LV_USE_FLEX -static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, uint32_t part) +static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_FLOW); return (lv_flex_flow_t)v.num; } -static inline lv_flex_align_t lv_obj_get_style_flex_main_place(const lv_obj_t * obj, uint32_t part) +static inline lv_flex_align_t lv_obj_get_style_flex_main_place(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_MAIN_PLACE); return (lv_flex_align_t)v.num; } -static inline lv_flex_align_t lv_obj_get_style_flex_cross_place(const lv_obj_t * obj, uint32_t part) +static inline lv_flex_align_t lv_obj_get_style_flex_cross_place(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_CROSS_PLACE); return (lv_flex_align_t)v.num; } -static inline lv_flex_align_t lv_obj_get_style_flex_track_place(const lv_obj_t * obj, uint32_t part) +static inline lv_flex_align_t lv_obj_get_style_flex_track_place(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_TRACK_PLACE); return (lv_flex_align_t)v.num; } -static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, uint32_t part) +static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_GROW); return (uint8_t)v.num; @@ -682,61 +689,61 @@ static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, uint32_t #endif /*LV_USE_FLEX*/ #if LV_USE_GRID -static inline const int32_t * lv_obj_get_style_grid_column_dsc_array(const lv_obj_t * obj, uint32_t part) +static inline const int32_t * lv_obj_get_style_grid_column_dsc_array(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_COLUMN_DSC_ARRAY); return (const int32_t *)v.ptr; } -static inline lv_grid_align_t lv_obj_get_style_grid_column_align(const lv_obj_t * obj, uint32_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_column_align(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_COLUMN_ALIGN); return (lv_grid_align_t)v.num; } -static inline const int32_t * lv_obj_get_style_grid_row_dsc_array(const lv_obj_t * obj, uint32_t part) +static inline const int32_t * lv_obj_get_style_grid_row_dsc_array(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_ROW_DSC_ARRAY); return (const int32_t *)v.ptr; } -static inline lv_grid_align_t lv_obj_get_style_grid_row_align(const lv_obj_t * obj, uint32_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_row_align(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_ROW_ALIGN); return (lv_grid_align_t)v.num; } -static inline int32_t lv_obj_get_style_grid_cell_column_pos(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_grid_cell_column_pos(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_COLUMN_POS); return (int32_t)v.num; } -static inline lv_grid_align_t lv_obj_get_style_grid_cell_x_align(const lv_obj_t * obj, uint32_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_cell_x_align(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_X_ALIGN); return (lv_grid_align_t)v.num; } -static inline int32_t lv_obj_get_style_grid_cell_column_span(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_grid_cell_column_span(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_COLUMN_SPAN); return (int32_t)v.num; } -static inline int32_t lv_obj_get_style_grid_cell_row_pos(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_grid_cell_row_pos(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_ROW_POS); return (int32_t)v.num; } -static inline lv_grid_align_t lv_obj_get_style_grid_cell_y_align(const lv_obj_t * obj, uint32_t part) +static inline lv_grid_align_t lv_obj_get_style_grid_cell_y_align(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_Y_ALIGN); return (lv_grid_align_t)v.num; } -static inline int32_t lv_obj_get_style_grid_cell_row_span(const lv_obj_t * obj, uint32_t part) +static inline int32_t lv_obj_get_style_grid_cell_row_span(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_ROW_SPAN); return (int32_t)v.num; @@ -837,7 +844,7 @@ void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t void lv_obj_set_style_blend_mode(lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector); void lv_obj_set_style_layout(lv_obj_t * obj, uint16_t value, lv_style_selector_t selector); void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector); -void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const lv_image_dsc_t * value, lv_style_selector_t selector); +void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector); void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector); #if LV_USE_FLEX void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_private.h new file mode 100644 index 000000000..7fafc58b1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_private.h @@ -0,0 +1,95 @@ +/** + * @file lv_obj_style_private.h + * + */ + +#ifndef LV_OBJ_STYLE_PRIVATE_H +#define LV_OBJ_STYLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_obj_style_t { + const lv_style_t * style; + uint32_t selector : 24; + uint32_t is_local : 1; + uint32_t is_trans : 1; +}; + +struct lv_obj_style_transition_dsc_t { + uint16_t time; + uint16_t delay; + lv_style_selector_t selector; + lv_style_prop_t prop; + lv_anim_path_cb_t path_cb; + void * user_data; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the object related style manager module. + * Called by LVGL in `lv_init()` + */ +void lv_obj_style_init(void); + +/** + * Deinitialize the object related style manager module. + * Called by LVGL in `lv_deinit()` + */ +void lv_obj_style_deinit(void); + +/** + * Used internally to create a style transition + * @param obj + * @param part + * @param prev_state + * @param new_state + * @param tr + */ +void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, + lv_state_t new_state, const lv_obj_style_transition_dsc_t * tr); + +/** + * Used internally to compare the appearance of an object in 2 states + * @param obj + * @param state1 + * @param state2 + * @return + */ +lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2); + +/** + * Update the layer type of a widget bayed on its current styles. + * The result will be stored in `obj->spec_attr->layer_type` + * @param obj the object whose layer should be updated + */ +void lv_obj_update_layer_type(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_STYLE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c index 5b8fd420b..15c069e90 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c @@ -6,14 +6,13 @@ /********************* * INCLUDES *********************/ -#include - -#include "lv_obj.h" +#include "lv_obj_private.h" +#include "lv_obj_class_private.h" #include "../indev/lv_indev.h" #include "../indev/lv_indev_private.h" #include "../display/lv_display.h" #include "../display/lv_display_private.h" -#include "../misc/lv_anim.h" +#include "../misc/lv_anim_private.h" #include "../misc/lv_async.h" #include "../core/lv_global.h" @@ -35,7 +34,7 @@ static void lv_obj_delete_async_cb(void * obj); static void obj_delete_core(lv_obj_t * obj); static lv_obj_tree_walk_res_t walk_core(lv_obj_t * obj, lv_obj_tree_walk_cb_t cb, void * user_data); -static lv_obj_tree_walk_res_t dump_tree_core(lv_obj_t * obj, int32_t depth); +static void dump_tree_core(lv_obj_t * obj, int32_t depth); static lv_obj_t * lv_obj_get_first_not_deleting_child(lv_obj_t * obj); /********************** @@ -156,6 +155,10 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent) return; } + if(parent == obj->parent) { + return; + } + lv_obj_invalidate(obj); lv_obj_allocate_spec_attr(parent); @@ -210,7 +213,7 @@ void lv_obj_move_to_index(lv_obj_t * obj, int32_t index) } const uint32_t parent_child_count = lv_obj_get_child_count(parent); - /* old_index only can be 0 or greater, this point can not be reached if the parent is not null */ + /* old_index only can be 0 or greater, this point cannot be reached if the parent is not null */ const int32_t old_index = lv_obj_get_index(obj); LV_ASSERT(0 <= old_index); @@ -306,7 +309,7 @@ lv_display_t * lv_obj_get_display(const lv_obj_t * obj) lv_display_t * d; lv_ll_t * disp_head = disp_ll_p; - _LV_LL_READ(disp_head, d) { + LV_LL_READ(disp_head, d) { uint32_t i; for(i = 0; i < d->screen_cnt; i++) { if(d->screens[i] == scr) return d; @@ -390,7 +393,7 @@ lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx, const l int32_t sibling_idx = (int32_t)lv_obj_get_index_by_type(obj, class_p) + idx; if(sibling_idx < 0) return NULL; - return lv_obj_get_child(parent, sibling_idx); + return lv_obj_get_child_by_type(parent, sibling_idx, class_p); } uint32_t lv_obj_get_child_count(const lv_obj_t * obj) @@ -486,8 +489,13 @@ static void lv_obj_delete_async_cb(void * obj) static void obj_indev_reset(lv_indev_t * indev, lv_obj_t * obj) { - /*Wait for release to avoid accidentally triggering other obj to be clicked*/ - lv_indev_wait_release(indev); + /* If the input device is already in the release state, + * there is no need to wait for the input device to be released + */ + if(lv_indev_get_state(indev) != LV_INDEV_STATE_RELEASED) { + /*Wait for release to avoid accidentally triggering other obj to be clicked*/ + lv_indev_wait_release(indev); + } /*Reset the input device*/ lv_indev_reset(indev, obj); @@ -530,6 +538,9 @@ static void obj_delete_core(lv_obj_t * obj) if(indev->pointer.last_pressed == obj) { indev->pointer.last_pressed = NULL; } + if(indev->pointer.last_hovered == obj) { + indev->pointer.last_hovered = NULL; + } } if(indev->group == group && obj == lv_indev_get_active_obj()) { @@ -545,7 +556,7 @@ static void obj_delete_core(lv_obj_t * obj) } /*All children deleted. Now clean up the object specific data*/ - _lv_obj_destruct(obj); + lv_obj_destruct(obj); /*Remove the screen for the screen list*/ if(obj->parent == NULL) { @@ -609,10 +620,8 @@ static lv_obj_tree_walk_res_t walk_core(lv_obj_t * obj, lv_obj_tree_walk_cb_t cb return LV_OBJ_TREE_WALK_NEXT; } -static lv_obj_tree_walk_res_t dump_tree_core(lv_obj_t * obj, int32_t depth) +static void dump_tree_core(lv_obj_t * obj, int32_t depth) { - lv_obj_tree_walk_res_t res; - #if LV_USE_LOG const char * id; @@ -630,14 +639,8 @@ static lv_obj_tree_walk_res_t dump_tree_core(lv_obj_t * obj, int32_t depth) if(obj && obj->spec_attr && obj->spec_attr->child_cnt) { for(uint32_t i = 0; i < obj->spec_attr->child_cnt; i++) { - res = dump_tree_core(lv_obj_get_child(obj, i), depth + 1); - if(res == LV_OBJ_TREE_WALK_END) - break; + dump_tree_core(lv_obj_get_child(obj, i), depth + 1); } - return LV_OBJ_TREE_WALK_NEXT; - } - else { - return LV_OBJ_TREE_WALK_END; } } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h index c500c7956..9f679dd40 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h @@ -1,5 +1,5 @@ /** - * @file struct _lv_obj_tree.h + * @file lv_obj_tree.h * */ @@ -13,8 +13,6 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include #include "../misc/lv_types.h" #include "../misc/lv_anim.h" #include "../display/lv_display.h" @@ -226,7 +224,7 @@ void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * use * Iterate through all children of any object and print their ID. * @param start_obj start integrating from this object */ -void lv_obj_dump_tree(lv_obj_t * start_ob); +void lv_obj_dump_tree(lv_obj_t * start_obj); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c index fbd1c8a87..13a2608e6 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c @@ -6,15 +6,21 @@ /********************* * INCLUDES *********************/ -#include -#include "lv_refr.h" +#include "lv_refr_private.h" +#include "lv_obj_draw_private.h" +#include "../misc/lv_area_private.h" +#include "../draw/sw/lv_draw_sw_mask_private.h" +#include "../draw/lv_draw_mask_private.h" +#include "lv_obj_private.h" +#include "lv_obj_event_private.h" #include "../display/lv_display.h" #include "../display/lv_display_private.h" #include "../tick/lv_tick.h" -#include "../misc/lv_timer.h" +#include "../misc/lv_timer_private.h" #include "../misc/lv_math.h" #include "../misc/lv_profiler.h" -#include "../draw/lv_draw.h" +#include "../misc/lv_types.h" +#include "../draw/lv_draw_private.h" #include "../font/lv_font_fmt_txt.h" #include "../stdlib/lv_string.h" #include "lv_global.h" @@ -66,11 +72,11 @@ static void wait_for_flushing(lv_display_t * disp); /** * Initialize the screen refresh subsystem */ -void _lv_refr_init(void) +void lv_refr_init(void) { } -void _lv_refr_deinit(void) +void lv_refr_deinit(void) { } @@ -79,13 +85,13 @@ void lv_refr_now(lv_display_t * disp) lv_anim_refr_now(); if(disp) { - if(disp->refr_timer) _lv_display_refr_timer(disp->refr_timer); + if(disp->refr_timer) lv_display_refr_timer(disp->refr_timer); } else { lv_display_t * d; d = lv_display_get_next(NULL); while(d) { - if(d->refr_timer) _lv_display_refr_timer(d->refr_timer); + if(d->refr_timer) lv_display_refr_timer(d->refr_timer); d = lv_display_get_next(d); } } @@ -99,10 +105,10 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) /*Truncate the clip area to `obj size + ext size` area*/ lv_area_t obj_coords_ext; lv_obj_get_coords(obj, &obj_coords_ext); - int32_t ext_draw_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_draw_size = lv_obj_get_ext_draw_size(obj); lv_area_increase(&obj_coords_ext, ext_draw_size, ext_draw_size); - if(!_lv_area_intersect(&clip_coords_for_obj, &clip_area_ori, &obj_coords_ext)) return; + if(!lv_area_intersect(&clip_coords_for_obj, &clip_area_ori, &obj_coords_ext)) return; /*If the object is visible on the current clip area*/ layer->_clip_area = clip_coords_for_obj; @@ -130,7 +136,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) } lv_area_t clip_coords_for_children; bool refr_children = true; - if(!_lv_area_intersect(&clip_coords_for_children, &clip_area_ori, obj_coords)) { + if(!lv_area_intersect(&clip_coords_for_children, &clip_area_ori, obj_coords)) { refr_children = false; } @@ -183,7 +189,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) lv_area_t bottom = obj->coords; bottom.y1 = bottom.y2 - rout + 1; - if(_lv_area_intersect(&bottom, &bottom, &clip_area_ori)) { + if(lv_area_intersect(&bottom, &bottom, &clip_area_ori)) { layer_children = lv_draw_layer_create(layer, LV_COLOR_FORMAT_ARGB8888, &bottom); for(i = 0; i < child_cnt; i++) { @@ -204,7 +210,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) lv_area_t top = obj->coords; top.y2 = top.y1 + rout - 1; - if(_lv_area_intersect(&top, &top, &clip_area_ori)) { + if(lv_area_intersect(&top, &top, &clip_area_ori)) { layer_children = lv_draw_layer_create(layer, LV_COLOR_FORMAT_ARGB8888, &top); for(i = 0; i < child_cnt; i++) { @@ -227,7 +233,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) lv_area_t mid = obj->coords; mid.y1 += rout; mid.y2 -= rout; - if(_lv_area_intersect(&mid, &mid, &clip_area_ori)) { + if(lv_area_intersect(&mid, &mid, &clip_area_ori)) { layer->_clip_area = mid; for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; @@ -248,12 +254,23 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) layer->_clip_area = clip_area_ori; } -void _lv_inv_area(lv_display_t * disp, const lv_area_t * area_p) +void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p) { if(!disp) disp = lv_display_get_default(); if(!disp) return; if(!lv_display_is_invalidation_enabled(disp)) return; + /** + * There are two reasons for this issue: + * 1.LVGL API is being used across threads, such as modifying widget properties in another thread + * or within an interrupt handler during the main thread rendering process. + * 2.User-customized widget modify widget properties/styles again within the DRAW event. + * + * Therefore, ensure that LVGL is used in a single-threaded manner, or refer to + * documentation: https://docs.lvgl.io/master/porting/os.html for proper locking mechanisms. + * Additionally, ensure that only drawing-related tasks are performed within the DRAW event, + * and move widget property/style modifications to other events. + */ LV_ASSERT_MSG(!disp->rendering_in_progress, "Invalidate area is not allowed during rendering."); /*Clear the invalidate buffer if the parameter is NULL*/ @@ -271,9 +288,16 @@ void _lv_inv_area(lv_display_t * disp, const lv_area_t * area_p) lv_area_t com_area; bool suc; - suc = _lv_area_intersect(&com_area, area_p, &scr_area); + suc = lv_area_intersect(&com_area, area_p, &scr_area); if(suc == false) return; /*Out of the screen*/ + if(disp->color_format == LV_COLOR_FORMAT_I1) { + /*Make sure that the X coordinates start and end on byte boundary. + *E.g. convert 11;27 to 8;31*/ + com_area.x1 &= ~0x7; /*Round down: Nx8*/ + com_area.x2 |= 0x7; /*Round up: Nx8 - 1*/ + } + /*If there were at least 1 invalid area in full refresh mode, redraw the whole screen*/ if(disp->render_mode == LV_DISPLAY_RENDER_MODE_FULL) { disp->inv_areas[0] = scr_area; @@ -288,7 +312,7 @@ void _lv_inv_area(lv_display_t * disp, const lv_area_t * area_p) /*Save only if this area is not in one of the saved areas*/ uint16_t i; for(i = 0; i < disp->inv_p; i++) { - if(_lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return; + if(lv_area_is_in(&com_area, &disp->inv_areas[i], 0) != false) return; } /*Save the area*/ @@ -307,7 +331,7 @@ void _lv_inv_area(lv_display_t * disp, const lv_area_t * area_p) * Get the display which is being refreshed * @return the display being refreshed */ -lv_display_t * _lv_refr_get_disp_refreshing(void) +lv_display_t * lv_refr_get_disp_refreshing(void) { return disp_refr; } @@ -316,12 +340,12 @@ lv_display_t * _lv_refr_get_disp_refreshing(void) * Get the display which is being refreshed * @return the display being refreshed */ -void _lv_refr_set_disp_refreshing(lv_display_t * disp) +void lv_refr_set_disp_refreshing(lv_display_t * disp) { disp_refr = disp; } -void _lv_display_refr_timer(lv_timer_t * tmr) +void lv_display_refr_timer(lv_timer_t * tmr) { LV_PROFILER_BEGIN; LV_TRACE_REFR("begin"); @@ -331,7 +355,7 @@ void _lv_display_refr_timer(lv_timer_t * tmr) /* Ensure the timer does not run again automatically. * This is done before refreshing in case refreshing invalidates something else. * However if the performance monitor is enabled keep the timer running to count the FPS.*/ -#if !(defined(LV_USE_PERF_MONITOR) && LV_USE_PERF_MONITOR) +#if LV_USE_PERF_MONITOR lv_timer_pause(tmr); #endif } @@ -378,23 +402,19 @@ void _lv_display_refr_timer(lv_timer_t * tmr) /*If refresh happened ...*/ lv_display_send_event(disp_refr, LV_EVENT_RENDER_READY, NULL); - if(!lv_display_is_double_buffered(disp_refr) || - disp_refr->render_mode != LV_DISPLAY_RENDER_MODE_DIRECT) goto refr_clean_up; + /*In double buffered direct mode save the updated areas. + *They will be used on the next call to synchronize the buffers.*/ + if(lv_display_is_double_buffered(disp_refr) && disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) { + uint32_t i; + for(i = 0; i < disp_refr->inv_p; i++) { + if(disp_refr->inv_area_joined[i]) + continue; - /*With double buffered direct mode synchronize the rendered areas to the other buffer*/ - /*We need to wait for ready here to not mess up the active screen*/ - wait_for_flushing(disp_refr); - - uint32_t i; - for(i = 0; i < disp_refr->inv_p; i++) { - if(disp_refr->inv_area_joined[i]) - continue; - - lv_area_t * sync_area = _lv_ll_ins_tail(&disp_refr->sync_areas); - *sync_area = disp_refr->inv_areas[i]; + lv_area_t * sync_area = lv_ll_ins_tail(&disp_refr->sync_areas); + *sync_area = disp_refr->inv_areas[i]; + } } -refr_clean_up: lv_memzero(disp_refr->inv_areas, sizeof(disp_refr->inv_areas)); lv_memzero(disp_refr->inv_area_joined, sizeof(disp_refr->inv_area_joined)); disp_refr->inv_p = 0; @@ -402,7 +422,7 @@ refr_clean_up: refr_finish: #if LV_DRAW_SW_COMPLEX == 1 - _lv_draw_sw_mask_cleanup(); + lv_draw_sw_mask_cleanup(); #endif lv_display_send_event(disp_refr, LV_EVENT_REFR_READY, NULL); @@ -435,11 +455,11 @@ static void lv_refr_join_area(void) } /*Check if the areas are on each other*/ - if(_lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) { + if(lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) { continue; } - _lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]); + lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]); /*Join two area only if the joined area size is smaller*/ if(lv_area_get_size(&joined_area) < (lv_area_get_size(&disp_refr->inv_areas[join_in]) + @@ -466,7 +486,7 @@ static void refr_sync_areas(void) if(!lv_display_is_double_buffered(disp_refr)) return; /*Do not sync if no sync areas*/ - if(_lv_ll_is_empty(&disp_refr->sync_areas)) return; + if(lv_ll_is_empty(&disp_refr->sync_areas)) return; LV_PROFILER_BEGIN; /*With double buffered direct mode synchronize the rendered areas to the other buffer*/ @@ -492,22 +512,22 @@ static void refr_sync_areas(void) if(disp_refr->inv_area_joined[i]) continue; /*Iterate over sync areas*/ - sync_area = _lv_ll_get_head(&disp_refr->sync_areas); + sync_area = lv_ll_get_head(&disp_refr->sync_areas); while(sync_area != NULL) { /*Get next sync area*/ - next_area = _lv_ll_get_next(&disp_refr->sync_areas, sync_area); + next_area = lv_ll_get_next(&disp_refr->sync_areas, sync_area); /*Remove intersect of redraw area from sync area and get remaining areas*/ - res_c = _lv_area_diff(res, sync_area, &disp_refr->inv_areas[i]); + res_c = lv_area_diff(res, sync_area, &disp_refr->inv_areas[i]); /*New sub areas created after removing intersect*/ if(res_c != -1) { /*Replace old sync area with new areas*/ for(j = 0; j < res_c; j++) { - new_area = _lv_ll_ins_prev(&disp_refr->sync_areas, sync_area); + new_area = lv_ll_ins_prev(&disp_refr->sync_areas, sync_area); *new_area = res[j]; } - _lv_ll_remove(&disp_refr->sync_areas, sync_area); + lv_ll_remove(&disp_refr->sync_areas, sync_area); lv_free(sync_area); } @@ -518,17 +538,17 @@ static void refr_sync_areas(void) lv_area_t disp_area = {0, 0, (int32_t)hor_res - 1, (int32_t)ver_res - 1}; /*Copy sync areas (if any remaining)*/ - for(sync_area = _lv_ll_get_head(&disp_refr->sync_areas); sync_area != NULL; - sync_area = _lv_ll_get_next(&disp_refr->sync_areas, sync_area)) { + for(sync_area = lv_ll_get_head(&disp_refr->sync_areas); sync_area != NULL; + sync_area = lv_ll_get_next(&disp_refr->sync_areas, sync_area)) { /** * @todo Resize SDL window will trigger crash because of sync_area is larger than disp_area */ - _lv_area_intersect(sync_area, sync_area, &disp_area); + lv_area_intersect(sync_area, sync_area, &disp_area); lv_draw_buf_copy(off_screen, sync_area, on_screen, sync_area); } /*Clear sync areas*/ - _lv_ll_clear(&disp_refr->sync_areas); + lv_ll_clear(&disp_refr->sync_areas); LV_PROFILER_END; } @@ -575,15 +595,16 @@ static void refr_invalid_areas(void) * Reshape the draw buffer if required * @param layer pointer to a layer which will be drawn */ -static void layer_reshape_draw_buf(lv_layer_t * layer) +static void layer_reshape_draw_buf(lv_layer_t * layer, uint32_t stride) { - LV_ASSERT(lv_draw_buf_reshape( - layer->draw_buf, - layer->color_format, - lv_area_get_width(&layer->buf_area), - lv_area_get_height(&layer->buf_area), - 0) - != NULL); + lv_draw_buf_t * ret = lv_draw_buf_reshape( + layer->draw_buf, + layer->color_format, + lv_area_get_width(&layer->buf_area), + lv_area_get_height(&layer->buf_area), + stride); + LV_UNUSED(ret); + LV_ASSERT_NULL(ret); } /** @@ -596,6 +617,10 @@ static void refr_area(const lv_area_t * area_p) lv_layer_t * layer = disp_refr->layer_head; layer->draw_buf = disp_refr->buf_act; +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_matrix_identity(&layer->matrix); +#endif + /*With full refresh just redraw directly into the buffer*/ /*In direct mode draw directly on the absolute coordinates of the buffer*/ if(disp_refr->render_mode != LV_DISPLAY_RENDER_MODE_PARTIAL) { @@ -603,19 +628,22 @@ static void refr_area(const lv_area_t * area_p) layer->buf_area.y1 = 0; layer->buf_area.x2 = lv_display_get_horizontal_resolution(disp_refr) - 1; layer->buf_area.y2 = lv_display_get_vertical_resolution(disp_refr) - 1; - layer_reshape_draw_buf(layer); lv_area_t disp_area; lv_area_set(&disp_area, 0, 0, lv_display_get_horizontal_resolution(disp_refr) - 1, lv_display_get_vertical_resolution(disp_refr) - 1); if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_FULL) { disp_refr->last_part = 1; + layer_reshape_draw_buf(layer, layer->draw_buf->header.stride); layer->_clip_area = disp_area; + layer->phy_clip_area = disp_area; refr_area_part(layer); } else if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) { disp_refr->last_part = disp_refr->last_area; + layer_reshape_draw_buf(layer, layer->draw_buf->header.stride); layer->_clip_area = *area_p; + layer->phy_clip_area = *area_p; refr_area_part(layer); } LV_PROFILER_END; @@ -643,7 +671,8 @@ static void refr_area(const lv_area_t * area_p) layer->draw_buf = disp_refr->buf_act; layer->buf_area = sub_area; layer->_clip_area = sub_area; - layer_reshape_draw_buf(layer); + layer->phy_clip_area = sub_area; + layer_reshape_draw_buf(layer, LV_STRIDE_AUTO); if(sub_area.y2 > y2) sub_area.y2 = y2; row_last = sub_area.y2; if(y2 == row_last) disp_refr->last_part = 1; @@ -660,7 +689,8 @@ static void refr_area(const lv_area_t * area_p) layer->draw_buf = disp_refr->buf_act; layer->buf_area = sub_area; layer->_clip_area = sub_area; - layer_reshape_draw_buf(layer); + layer->phy_clip_area = sub_area; + layer_reshape_draw_buf(layer, LV_STRIDE_AUTO); disp_refr->last_part = 1; refr_area_part(layer); } @@ -741,9 +771,9 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) { lv_obj_t * found_p = NULL; - if(_lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; + if(lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL; - if(_lv_obj_get_layer_type(obj) != LV_LAYER_TYPE_NONE) return NULL; + if(lv_obj_get_layer_type(obj) != LV_LAYER_TYPE_NONE) return NULL; /*If this object is fully cover the draw area then check the children too*/ lv_cover_check_info_t info; @@ -811,7 +841,7 @@ static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj) } } - /*Call the post draw draw function of the parents of the to object*/ + /*Call the post draw function of the parents of the to object*/ lv_obj_send_event(parent, LV_EVENT_DRAW_POST_BEGIN, (void *)layer); lv_obj_send_event(parent, LV_EVENT_DRAW_POST, (void *)layer); lv_obj_send_event(parent, LV_EVENT_DRAW_POST_END, (void *)layer); @@ -828,7 +858,7 @@ static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj) static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_type_t layer_type, lv_area_t * layer_area_out, lv_area_t * obj_draw_size_out) { - int32_t ext_draw_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_draw_size = lv_obj_get_ext_draw_size(obj); lv_obj_get_coords(obj, obj_draw_size_out); lv_area_increase(obj_draw_size_out, ext_draw_size, ext_draw_size); @@ -838,7 +868,7 @@ static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_t lv_area_t clip_coords_for_obj; lv_area_t tranf_coords = *obj_draw_size_out; lv_obj_get_transformed_area(obj, &tranf_coords, LV_OBJ_POINT_TRANSFORM_FLAG_NONE); - if(!_lv_area_intersect(&clip_coords_for_obj, &layer->_clip_area, &tranf_coords)) { + if(!lv_area_intersect(&clip_coords_for_obj, &layer->_clip_area, &tranf_coords)) { return LV_RESULT_INVALID; } @@ -847,7 +877,7 @@ static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_t *in order to cover transformed area after transformation.*/ lv_area_t inverse_clip_coords_for_obj = clip_coords_for_obj; lv_obj_get_transformed_area(obj, &inverse_clip_coords_for_obj, LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE); - if(!_lv_area_intersect(&inverse_clip_coords_for_obj, &inverse_clip_coords_for_obj, obj_draw_size_out)) { + if(!lv_area_intersect(&inverse_clip_coords_for_obj, &inverse_clip_coords_for_obj, obj_draw_size_out)) { return LV_RESULT_INVALID; } @@ -856,7 +886,7 @@ static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_t } else if(layer_type == LV_LAYER_TYPE_SIMPLE) { lv_area_t clip_coords_for_obj; - if(!_lv_area_intersect(&clip_coords_for_obj, &layer->_clip_area, obj_draw_size_out)) { + if(!lv_area_intersect(&clip_coords_for_obj, &layer->_clip_area, obj_draw_size_out)) { return LV_RESULT_INVALID; } *layer_area_out = clip_coords_for_obj; @@ -873,7 +903,7 @@ static bool alpha_test_area_on_obj(lv_obj_t * obj, const lv_area_t * area) { /*Test for alpha by assuming there is no alpha. If it fails, fall back to rendering with alpha*/ /*If the layer area is not fully on the object, it can't fully cover it*/ - if(!_lv_area_is_on(area, &obj->coords)) return true; + if(!lv_area_is_on(area, &obj->coords)) return true; lv_cover_check_info_t info; info.res = LV_COVER_RES_COVER; @@ -883,24 +913,131 @@ static bool alpha_test_area_on_obj(lv_obj_t * obj, const lv_area_t * area) else return true; } -void refr_obj(lv_layer_t * layer, lv_obj_t * obj) +#if LV_DRAW_TRANSFORM_USE_MATRIX + +static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj) +{ + lv_matrix_t ori_matrix = layer->matrix; + lv_matrix_t obj_matrix; + lv_matrix_identity(&obj_matrix); + + lv_point_t pivot = { + .x = lv_obj_get_style_transform_pivot_x(obj, 0), + .y = lv_obj_get_style_transform_pivot_y(obj, 0) + }; + + pivot.x = obj->coords.x1 + lv_pct_to_px(pivot.x, lv_area_get_width(&obj->coords)); + pivot.y = obj->coords.y1 + lv_pct_to_px(pivot.y, lv_area_get_height(&obj->coords)); + + int32_t rotation = lv_obj_get_style_transform_rotation(obj, 0); + int32_t scale_x = lv_obj_get_style_transform_scale_x(obj, 0); + int32_t scale_y = lv_obj_get_style_transform_scale_y(obj, 0); + int32_t skew_x = lv_obj_get_style_transform_skew_x(obj, 0); + int32_t skew_y = lv_obj_get_style_transform_skew_y(obj, 0); + + if(scale_x <= 0 || scale_y <= 0) { + /* NOT draw if scale is negative or zero */ + return; + } + + /* generate the obj matrix */ + lv_matrix_translate(&obj_matrix, pivot.x, pivot.y); + if(rotation != 0) { + lv_matrix_rotate(&obj_matrix, rotation * 0.1f); + } + + if(scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) { + lv_matrix_scale( + &obj_matrix, + (float)scale_x / LV_SCALE_NONE, + (float)scale_y / LV_SCALE_NONE + ); + } + + if(skew_x != 0 || skew_y != 0) { + lv_matrix_skew(&obj_matrix, skew_x, skew_y); + } + + lv_matrix_translate(&obj_matrix, -pivot.x, -pivot.y); + + /* apply the obj matrix */ + lv_matrix_multiply(&layer->matrix, &obj_matrix); + + /* calculate clip area without transform */ + lv_matrix_t matrix_reverse; + lv_matrix_inverse(&matrix_reverse, &obj_matrix); + + lv_area_t clip_area = layer->_clip_area; + lv_area_t clip_area_ori = layer->_clip_area; + clip_area = lv_matrix_transform_area(&matrix_reverse, &clip_area); + + /* increase the clip area by 1 pixel to avoid rounding errors */ + if(!lv_matrix_is_identity_or_translation(&obj_matrix)) { + lv_area_increase(&clip_area, 1, 1); + } + + layer->_clip_area = clip_area; + + /* redraw obj */ + lv_obj_redraw(layer, obj); + + /* restore original matrix */ + layer->matrix = ori_matrix; + /* restore clip area */ + layer->_clip_area = clip_area_ori; +} + +static bool refr_check_obj_clip_overflow(lv_layer_t * layer, lv_obj_t * obj) +{ + if(lv_obj_get_style_transform_rotation(obj, 0) == 0) { + return false; + } + + /*Truncate the area to the object*/ + lv_area_t obj_coords; + int32_t ext_size = lv_obj_get_ext_draw_size(obj); + lv_area_copy(&obj_coords, &obj->coords); + lv_area_increase(&obj_coords, ext_size, ext_size); + + lv_obj_get_transformed_area(obj, &obj_coords, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE); + + lv_area_t clip_coords_for_obj; + if(!lv_area_intersect(&clip_coords_for_obj, &layer->_clip_area, &obj_coords)) { + return false; + } + + bool has_clip = lv_memcmp(&clip_coords_for_obj, &obj_coords, sizeof(lv_area_t)) != 0; + return has_clip; +} + +#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ + +static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) { if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return; - lv_layer_type_t layer_type = _lv_obj_get_layer_type(obj); + lv_opa_t opa = lv_obj_get_style_opa_layered(obj, 0); + if(opa < LV_OPA_MIN) return; + +#if LV_DRAW_TRANSFORM_USE_MATRIX + /*If the layer opa is full then use the matrix transform*/ + if(opa >= LV_OPA_MAX && !refr_check_obj_clip_overflow(layer, obj)) { + refr_obj_matrix(layer, obj); + return; + } +#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ + + lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); if(layer_type == LV_LAYER_TYPE_NONE) { lv_obj_redraw(layer, obj); } else { - lv_opa_t opa = lv_obj_get_style_opa_layered(obj, 0); - if(opa < LV_OPA_MIN) return; - lv_area_t layer_area_full; lv_area_t obj_draw_size; lv_result_t res = layer_get_area(layer, obj, layer_type, &layer_area_full, &obj_draw_size); if(res != LV_RESULT_OK) return; - /*Simple layers can be subdivied into smaller layers*/ + /*Simple layers can be subdivided into smaller layers*/ uint32_t max_rgb_row_height = lv_area_get_height(&layer_area_full); uint32_t max_argb_row_height = lv_area_get_height(&layer_area_full); if(layer_type == LV_LAYER_TYPE_SIMPLE) { @@ -959,7 +1096,7 @@ void refr_obj(lv_layer_t * layer, lv_obj_t * obj) layer_draw_dsc.blend_mode = lv_obj_get_style_blend_mode(obj, 0); layer_draw_dsc.antialias = disp_refr->antialiasing; layer_draw_dsc.bitmap_mask_src = lv_obj_get_style_bitmap_mask_src(obj, 0); - layer_draw_dsc.original_area = obj_draw_size; + layer_draw_dsc.image_area = obj_draw_size; layer_draw_dsc.src = new_layer; lv_draw_layer(layer, &layer_draw_dsc, &layer_area_act); @@ -971,10 +1108,11 @@ void refr_obj(lv_layer_t * layer, lv_obj_t * obj) static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h) { - bool has_alpha = lv_color_format_has_alpha(disp->color_format); - lv_color_format_t cf = has_alpha ? LV_COLOR_FORMAT_ARGB8888 : disp->color_format; + lv_color_format_t cf = disp->color_format; uint32_t stride = lv_draw_buf_width_to_stride(area_w, cf); - int32_t max_row = (uint32_t)disp->buf_act->data_size / stride; + uint32_t overhead = LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t); + + int32_t max_row = (uint32_t)(disp->buf_act->data_size - overhead) / stride; if(max_row > area_h) max_row = area_h; @@ -1064,6 +1202,12 @@ static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * }; lv_display_send_event(disp, LV_EVENT_FLUSH_START, &offset_area); + + /*For backward compatibility support LV_COLOR_16_SWAP (from v8)*/ +#if defined(LV_COLOR_16_SWAP) && LV_COLOR_16_SWAP + lv_draw_sw_rgb565_swap(px_map, lv_area_get_size(&offset_area)); +#endif + disp->flush_cb(disp, &offset_area, px_map); lv_display_send_event(disp, LV_EVENT_FLUSH_FINISH, &offset_area); @@ -1078,7 +1222,10 @@ static void wait_for_flushing(lv_display_t * disp) lv_display_send_event(disp, LV_EVENT_FLUSH_WAIT_START, NULL); if(disp->flush_wait_cb) { - disp->flush_wait_cb(disp); + if(disp->flushing) { + disp->flush_wait_cb(disp); + } + disp->flushing = 0; } else { while(disp->flushing); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h index 537b9eedd..6b756edb5 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h @@ -15,7 +15,7 @@ extern "C" { *********************/ #include "lv_obj.h" #include "../display/lv_display.h" -#include +#include "../misc/lv_types.h" /********************* * DEFINES @@ -41,16 +41,6 @@ extern "C" { * GLOBAL FUNCTIONS **********************/ -/** - * Initialize the screen refresh subsystem - */ -void _lv_refr_init(void); - -/** - * Deinitialize the screen refresh subsystem - */ -void _lv_refr_deinit(void); - /** * Redraw the invalidated areas now. * Normally the redrawing is periodically executed in `lv_timer_handler` but a long blocking process @@ -67,32 +57,6 @@ void lv_refr_now(lv_display_t * disp); */ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj); -/** - * Invalidate an area on display to redraw it - * @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas) - * @param disp pointer to display where the area should be invalidated (NULL can be used if there is - * only one display) - */ -void _lv_inv_area(lv_display_t * disp, const lv_area_t * area_p); - -/** - * Get the display which is being refreshed - * @return the display being refreshed - */ -lv_display_t * _lv_refr_get_disp_refreshing(void); - -/** - * Set the display which is being refreshed - * @param disp the display being refreshed - */ -void _lv_refr_set_disp_refreshing(lv_display_t * disp); - -/** - * Called periodically to handle the refreshing - * @param timer pointer to the timer itself - */ -void _lv_display_refr_timer(lv_timer_t * timer); - /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_refr_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_refr_private.h new file mode 100644 index 000000000..8f840780b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr_private.h @@ -0,0 +1,75 @@ +/** + * @file lv_refr_private.h + * + */ + +#ifndef LV_REFR_PRIVATE_H +#define LV_REFR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_refr.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the screen refresh subsystem + */ +void lv_refr_init(void); + +/** + * Deinitialize the screen refresh subsystem + */ +void lv_refr_deinit(void); + +/** + * Invalidate an area on display to redraw it + * @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas) + * @param disp pointer to display where the area should be invalidated (NULL can be used if there is + * only one display) + */ +void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p); + +/** + * Get the display which is being refreshed + * @return the display being refreshed + */ +lv_display_t * lv_refr_get_disp_refreshing(void); + +/** + * Set the display which is being refreshed + * @param disp the display being refreshed + */ +void lv_refr_set_disp_refreshing(lv_display_t * disp); + +/** + * Called periodically to handle the refreshing + * @param timer pointer to the timer itself + */ +void lv_display_refr_timer(lv_timer_t * timer); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_REFR_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/display/lv_display.c b/lib/libesp32_lvgl/lvgl/src/display/lv_display.c index 2e839f45a..df4bb9b27 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display.c +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display.c @@ -6,13 +6,18 @@ /********************* * INCLUDES *********************/ +#include "../display/lv_display_private.h" +#include "../misc/lv_event_private.h" +#include "../misc/lv_anim_private.h" +#include "../draw/lv_draw_private.h" +#include "../core/lv_obj_private.h" #include "lv_display.h" #include "../misc/lv_math.h" -#include "../core/lv_refr.h" -#include "../display/lv_display_private.h" +#include "../core/lv_refr_private.h" #include "../stdlib/lv_string.h" #include "../themes/lv_theme.h" #include "../core/lv_global.h" +#include "../others/sysmon/lv_sysmon.h" #if LV_USE_DRAW_SW #include "../draw/sw/lv_draw_sw.h" @@ -56,7 +61,7 @@ static void disp_event_cb(lv_event_t * e); lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res) { - lv_display_t * disp = _lv_ll_ins_head(disp_ll_p); + lv_display_t * disp = lv_ll_ins_head(disp_ll_p); LV_ASSERT_MALLOC(disp); if(!disp) return NULL; @@ -86,13 +91,13 @@ lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res) disp->inv_en_cnt = 1; disp->last_activity_time = lv_tick_get(); - _lv_ll_init(&disp->sync_areas, sizeof(lv_area_t)); + lv_ll_init(&disp->sync_areas, sizeof(lv_area_t)); lv_display_t * disp_def_tmp = disp_def; disp_def = disp; /*Temporarily change the default screen to create the default screens on the new display*/ /*Create a refresh timer*/ - disp->refr_timer = lv_timer_create(_lv_display_refr_timer, LV_DEF_REFR_PERIOD, disp); + disp->refr_timer = lv_timer_create(lv_display_refr_timer, LV_DEF_REFR_PERIOD, disp); LV_ASSERT_MALLOC(disp->refr_timer); if(disp->refr_timer == NULL) { lv_free(disp); @@ -139,13 +144,23 @@ lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res) lv_timer_ready(disp->refr_timer); /*Be sure the screen will be refreshed immediately on start up*/ +#if LV_USE_PERF_MONITOR + lv_sysmon_show_performance(disp); +#endif + +#if LV_USE_MEM_MONITOR + lv_sysmon_show_memory(disp); +#endif + return disp; } void lv_display_delete(lv_display_t * disp) { bool was_default = false; + bool was_refr = false; if(disp == lv_display_get_default()) was_default = true; + if(disp == lv_refr_get_disp_refreshing()) was_refr = true; lv_display_send_event(disp, LV_EVENT_DELETE, NULL); lv_event_remove_all(&(disp->event_list)); @@ -178,12 +193,12 @@ void lv_display_delete(lv_display_t * disp) disp->act_scr = NULL; while(disp->screen_cnt != 0) { - /*Delete the screenst*/ + /*Delete the screens*/ lv_obj_delete(disp->screens[0]); } - _lv_ll_clear(&disp->sync_areas); - _lv_ll_remove(disp_ll_p, disp); + lv_ll_clear(&disp->sync_areas); + lv_ll_remove(disp_ll_p, disp); if(disp->refr_timer) lv_timer_delete(disp->refr_timer); if(disp->layer_deinit) disp->layer_deinit(disp, disp->layer_head); @@ -191,7 +206,9 @@ void lv_display_delete(lv_display_t * disp) lv_free(disp); - if(was_default) lv_display_set_default(_lv_ll_get_head(disp_ll_p)); + if(was_default) lv_display_set_default(lv_ll_get_head(disp_ll_p)); + + if(was_refr) lv_refr_set_disp_refreshing(NULL); } void lv_display_set_default(lv_display_t * disp) @@ -207,9 +224,9 @@ lv_display_t * lv_display_get_default(void) lv_display_t * lv_display_get_next(lv_display_t * disp) { if(disp == NULL) - return _lv_ll_get_head(disp_ll_p); + return lv_ll_get_head(disp_ll_p); else - return _lv_ll_get_next(disp_ll_p, disp); + return lv_ll_get_next(disp_ll_p, disp); } /*--------------------- @@ -457,6 +474,8 @@ void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_fo disp->color_format = color_format; disp->layer_head->color_format = color_format; + if(disp->buf_1) disp->buf_1->header.cf = color_format; + if(disp->buf_2) disp->buf_2->header.cf = color_format; lv_display_send_event(disp, LV_EVENT_COLOR_FORMAT_CHANGED, NULL); } @@ -559,7 +578,7 @@ lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp) return disp->bottom_layer; } -void lv_screen_load(struct _lv_obj_t * scr) +void lv_screen_load(struct lv_obj_t * scr) { lv_screen_load_anim(scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, false); } @@ -568,7 +587,7 @@ void lv_screen_load_anim(lv_obj_t * new_scr, lv_screen_load_anim_t anim_type, ui bool auto_del) { lv_display_t * d = lv_obj_get_display(new_scr); - lv_obj_t * act_scr = lv_screen_active(); + lv_obj_t * act_scr = d->act_scr; if(act_scr == new_scr || d->scr_to_load == new_scr) { return; @@ -581,20 +600,16 @@ void lv_screen_load_anim(lv_obj_t * new_scr, lv_screen_load_anim_t anim_type, ui lv_obj_set_pos(d->scr_to_load, 0, 0); lv_obj_remove_local_style_prop(d->scr_to_load, LV_STYLE_OPA, 0); - if(d->del_prev) { - lv_obj_delete(act_scr); - } - act_scr = lv_screen_active(); /*Active screen changed.*/ + d->prev_scr = d->act_scr; + act_scr = d->scr_to_load; /*Active screen changed.*/ scr_load_internal(d->scr_to_load); } d->scr_to_load = new_scr; - if(d->prev_scr && d->del_prev) { - lv_obj_delete(d->prev_scr); - d->prev_scr = NULL; - } + if(d->prev_scr && d->del_prev) lv_obj_delete(d->prev_scr); + d->prev_scr = NULL; d->draw_prev_over_act = is_out_anim(anim_type); d->del_prev = auto_del; @@ -924,6 +939,67 @@ lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp) return disp->buf_act; } +void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area) +{ + lv_display_rotation_t rotation = lv_display_get_rotation(disp); + + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + + switch(rotation) { + case LV_DISPLAY_ROTATION_0: + return; + case LV_DISPLAY_ROTATION_90: + area->y2 = disp->ver_res - area->x1 - 1; + area->x1 = area->y1; + area->x2 = area->x1 + h - 1; + area->y1 = area->y2 - w + 1; + break; + case LV_DISPLAY_ROTATION_180: + area->y2 = disp->ver_res - area->y1 - 1; + area->y1 = area->y2 - h + 1; + area->x2 = disp->hor_res - area->x1 - 1; + area->x1 = area->x2 - w + 1; + break; + case LV_DISPLAY_ROTATION_270: + area->x1 = disp->hor_res - area->y2 - 1; + area->y2 = area->x2; + area->x2 = area->x1 + h - 1; + area->y1 = area->y2 - w + 1; + break; + } +} + +lv_obj_t * lv_screen_active(void) +{ + return lv_display_get_screen_active(lv_display_get_default()); +} + +lv_obj_t * lv_layer_top(void) +{ + return lv_display_get_layer_top(lv_display_get_default()); +} + +lv_obj_t * lv_layer_sys(void) +{ + return lv_display_get_layer_sys(lv_display_get_default()); +} + +lv_obj_t * lv_layer_bottom(void) +{ + return lv_display_get_layer_bottom(lv_display_get_default()); +} + +int32_t lv_dpx(int32_t n) +{ + return LV_DPX(n); +} + +int32_t lv_display_dpx(const lv_display_t * disp, int32_t n) +{ + return LV_DPX_CALC(lv_display_get_dpi(disp), n); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -998,7 +1074,7 @@ static void scr_load_anim_start(lv_anim_t * a) { lv_display_t * d = lv_obj_get_display(a->var); - d->prev_scr = lv_screen_active(); + d->prev_scr = d->act_scr; d->act_scr = a->var; lv_obj_send_event(d->act_scr, LV_EVENT_SCREEN_LOAD_START, NULL); diff --git a/lib/libesp32_lvgl/lvgl/src/display/lv_display.h b/lib/libesp32_lvgl/lvgl/src/display/lv_display.h index c3ce14775..e3e7c49f2 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display.h +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display.h @@ -1,5 +1,5 @@ /** - * @file lv_disp.h + * @file lv_display.h * */ @@ -228,6 +228,8 @@ int32_t lv_display_get_dpi(const lv_display_t * disp); /** * Set the buffers for a display, similarly to `lv_display_set_draw_buffers`, but accept the raw buffer pointers. + * For DIRECT/FULL rending modes, the buffer size must be at least + * `hor_res * ver_res * lv_color_format_get_size(lv_display_get_color_format(disp))` * @param disp pointer to a display * @param buf1 first buffer * @param buf2 second buffer (can be `NULL`) @@ -362,7 +364,7 @@ lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp); /** * Return the bottom layer. The bottom layer is the same on all screen and it is under the normal screen layer. - * It's visible only if the the screen is transparent. + * It's visible only if the screen is transparent. * @param disp pointer to display (NULL to use the default screen) * @return pointer to the bottom layer object */ @@ -372,7 +374,7 @@ lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp); * Load a screen on the default display * @param scr pointer to a screen */ -void lv_screen_load(struct _lv_obj_t * scr); +void lv_screen_load(struct lv_obj_t * scr); /** * Switch screen with animation @@ -389,37 +391,25 @@ void lv_screen_load_anim(lv_obj_t * scr, lv_screen_load_anim_t anim_type, uint32 * Get the active screen of the default display * @return pointer to the active screen */ -static inline lv_obj_t * lv_screen_active(void) -{ - return lv_display_get_screen_active(lv_display_get_default()); -} +lv_obj_t * lv_screen_active(void); /** * Get the top layer of the default display * @return pointer to the top layer */ -static inline lv_obj_t * lv_layer_top(void) -{ - return lv_display_get_layer_top(lv_display_get_default()); -} +lv_obj_t * lv_layer_top(void); /** * Get the system layer of the default display * @return pointer to the sys layer */ -static inline lv_obj_t * lv_layer_sys(void) -{ - return lv_display_get_layer_sys(lv_display_get_default()); -} +lv_obj_t * lv_layer_sys(void); /** * Get the bottom layer of the default display * @return pointer to the bottom layer */ -static inline lv_obj_t * lv_layer_bottom(void) -{ - return lv_display_get_layer_bottom(lv_display_get_default()); -} +lv_obj_t * lv_layer_bottom(void); /*--------------------- * OTHERS @@ -536,6 +526,13 @@ void * lv_display_get_user_data(lv_display_t * disp); void * lv_display_get_driver_data(lv_display_t * disp); lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp); +/** + * Rotate an area in-place according to the display's rotation + * @param disp pointer to a display + * @param area pointer to an area to rotate + */ +void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area); + /********************** * MACROS **********************/ @@ -565,8 +562,8 @@ lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp); * 1 dip is 2 px on a 320 DPI screen * https://stackoverflow.com/questions/2025282/what-is-the-difference-between-px-dip-dp-and-sp */ -#define _LV_DPX_CALC(dpi, n) ((n) == 0 ? 0 :LV_MAX((( (dpi) * (n) + 80) / 160), 1)) /*+80 for rounding*/ -#define LV_DPX(n) _LV_DPX_CALC(lv_display_get_dpi(NULL), n) +#define LV_DPX_CALC(dpi, n) ((n) == 0 ? 0 :LV_MAX((( (dpi) * (n) + 80) / 160), 1)) /*+80 for rounding*/ +#define LV_DPX(n) LV_DPX_CALC(lv_display_get_dpi(NULL), n) /** * Scale the given number of pixels (a distance or size) relative to a 160 DPI display @@ -576,10 +573,7 @@ lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp); * @param n the number of pixels to scale * @return `n x current_dpi/160` */ -static inline int32_t lv_dpx(int32_t n) -{ - return LV_DPX(n); -} +int32_t lv_dpx(int32_t n); /** * Scale the given number of pixels (a distance or size) relative to a 160 DPI display @@ -590,10 +584,7 @@ static inline int32_t lv_dpx(int32_t n) * @param n the number of pixels to scale * @return `n x current_dpi/160` */ -static inline int32_t lv_display_dpx(const lv_display_t * disp, int32_t n) -{ - return _LV_DPX_CALC(lv_display_get_dpi(disp), n); -} +int32_t lv_display_dpx(const lv_display_t * disp, int32_t n); #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h b/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h index c7d2569cf..bcdc95c46 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h @@ -18,18 +18,22 @@ extern "C" { #include "../draw/lv_draw.h" #include "lv_display.h" +#if LV_USE_SYSMON +#include "../others/sysmon/lv_sysmon_private.h" +#endif + /********************* * DEFINES *********************/ #ifndef LV_INV_BUF_SIZE -#define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas*/ +#define LV_INV_BUF_SIZE 32 /**< Buffer size for invalid areas */ #endif /********************** * TYPEDEFS **********************/ -struct _lv_display_t { +struct lv_display_t { /*--------------------- * Resolution @@ -53,7 +57,8 @@ struct _lv_display_t { /** Vertical offset from the full / physical display. Set to 0 for fullscreen mode.*/ int32_t offset_y; - uint32_t dpi; /** DPI (dot per inch) of the display. Default value is `LV_DPI_DEF`.*/ + /** DPI (dot per inch) of the display. Default value is `LV_DPI_DEF`.*/ + uint32_t dpi; /*--------------------- * Buffering @@ -71,16 +76,18 @@ struct _lv_display_t { /** * Used to wait while flushing is ready. * It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc. - * If not set `flushing` flag is used which can be cleared with `lv_display_flush_ready()`*/ + * If not set `flushing` flag is used which can be cleared with `lv_display_flush_ready()` */ lv_display_flush_wait_cb_t flush_wait_cb; - /*1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ Read-Modify-Write issue might occur)*/ + /** 1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ + * Read-Modify-Write issue might occur) */ volatile int flushing; - /*1: It was the last chunk to flush. (It can't be a bit field because when it's cleared from IRQ Read-Modify-Write issue might occur)*/ + /** 1: It was the last chunk to flush. (It can't be a bit field because when it's cleared + * from IRQ Read-Modify-Write issue might occur) */ volatile int flushing_last; - volatile uint32_t last_area : 1; /*1: the last area is being rendered*/ - volatile uint32_t last_part : 1; /*1: the last part of the current area is being rendered*/ + volatile uint32_t last_area : 1; /**< 1: last area is being rendered */ + volatile uint32_t last_part : 1; /**< 1: last part of the current area is being rendered */ lv_display_render_mode_t render_mode; uint32_t antialiasing : 1; /**< 1: anti-aliasing is enabled on this display.*/ @@ -99,7 +106,7 @@ struct _lv_display_t { /** Double buffer sync areas (redrawn during last refresh) */ lv_ll_t sync_areas; - lv_draw_buf_t _static_buf1; /*Used when user pass in a raw buffer as display draw buffer*/ + lv_draw_buf_t _static_buf1; /**< Used when user pass in a raw buffer as display draw buffer */ lv_draw_buf_t _static_buf2; /*--------------------- * Layer @@ -114,15 +121,15 @@ struct _lv_display_t { /** Screens of the display*/ lv_obj_t ** screens; /**< Array of screen objects.*/ + lv_obj_t * sys_layer; /**< @see lv_display_get_layer_sys*/ + lv_obj_t * top_layer; /**< @see lv_display_get_layer_top*/ lv_obj_t * act_scr; /**< Currently active screen on this display*/ + lv_obj_t * bottom_layer;/**< @see lv_display_get_layer_bottom*/ lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations*/ lv_obj_t * scr_to_load; /**< The screen prepared to load in lv_screen_load_anim*/ - lv_obj_t * bottom_layer; /**< @see lv_display_get_layer_bottom*/ - lv_obj_t * top_layer; /**< @see lv_display_get_layer_top*/ - lv_obj_t * sys_layer; /**< @see lv_display_get_layer_sys*/ uint32_t screen_cnt; uint8_t draw_prev_over_act : 1;/** 1: Draw previous screen over active screen*/ - uint8_t del_prev : 1; /** 1: Automatically delete the previous screen when the screen load animation is ready*/ + uint8_t del_prev : 1; /** 1: Automatically delete the previous screen when the screen load animation is ready*/ /*--------------------- * Others @@ -135,10 +142,9 @@ struct _lv_display_t { lv_event_list_t event_list; uint32_t sw_rotate : 1; /**< 1: use software rotation (slower)*/ - uint32_t rotation : 2; /**< Element of @lv_display_rotation_t*/ + uint32_t rotation : 2; /**< Element of lv_display_rotation_t*/ - /**< The theme assigned to the screen*/ - lv_theme_t * theme; + lv_theme_t * theme; /**< The theme assigned to the screen*/ /** A timer which periodically checks the dirty areas and refreshes them*/ lv_timer_t * refr_timer; @@ -148,6 +154,17 @@ struct _lv_display_t { /** The area being refreshed*/ lv_area_t refreshed_area; + +#if LV_USE_PERF_MONITOR + lv_obj_t * perf_label; + lv_sysmon_backend_data_t perf_sysmon_backend; + lv_sysmon_perf_info_t perf_sysmon_info; +#endif + +#if LV_USE_MEM_MONITOR + lv_obj_t * mem_label; +#endif + }; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c index c73585e11..8de27efad 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c @@ -3,14 +3,19 @@ * */ +/** + * Modified by NXP in 2024 + */ + /********************* * INCLUDES *********************/ -#include "lv_draw.h" +#include "../misc/lv_area_private.h" +#include "lv_draw_private.h" #include "sw/lv_draw_sw.h" #include "../display/lv_display_private.h" #include "../core/lv_global.h" -#include "../core/lv_refr.h" +#include "../core/lv_refr_private.h" #include "../stdlib/lv_string.h" /********************* @@ -77,6 +82,7 @@ void * lv_draw_create_unit(size_t size) new_unit->next = _draw_info.unit_head; _draw_info.unit_head = new_unit; + _draw_info.unit_cnt++; return new_unit; } @@ -89,6 +95,9 @@ lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords) new_task->area = *coords; new_task->_real_area = *coords; new_task->clip_area = layer->_clip_area; +#if LV_DRAW_TRANSFORM_USE_MATRIX + new_task->matrix = layer->matrix; +#endif new_task->state = LV_DRAW_TASK_STATE_QUEUED; /*Find the tail*/ @@ -150,19 +159,33 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t) LV_PROFILER_END; } +void lv_draw_wait_for_finish(void) +{ +#if LV_USE_OS + lv_draw_unit_t * u = _draw_info.unit_head; + while(u) { + if(u->wait_for_finish_cb) + u->wait_for_finish_cb(u); + u = u->next; + } +#endif +} + void lv_draw_dispatch(void) { LV_PROFILER_BEGIN; - bool render_running = false; + bool task_dispatched = false; lv_display_t * disp = lv_display_get_next(NULL); while(disp) { lv_layer_t * layer = disp->layer_head; while(layer) { - if(lv_draw_dispatch_layer(disp, layer)) - render_running = true; + /* If there are no tasks in the layer, skip it */ + if(layer->draw_task_head && lv_draw_dispatch_layer(disp, layer)) + task_dispatched = true; layer = layer->next; } - if(!render_running) { + if(!task_dispatched) { + lv_draw_wait_for_finish(); lv_draw_dispatch_request(); } disp = lv_display_get_next(disp); @@ -179,7 +202,7 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) while(t) { lv_draw_task_t * t_next = t->next; if(t->state == LV_DRAW_TASK_STATE_READY) { - if(t_prev) t_prev->next = t->next; /*Remove by it by assigning the next task to the previous*/ + if(t_prev) t_prev->next = t->next; /*Remove it by assigning the next task to the previous*/ else layer->draw_task_head = t_next; /*If it was the head, set the next as head*/ /*If it was layer drawing free the layer too*/ @@ -189,8 +212,7 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) if(layer_drawn->draw_buf) { int32_t h = lv_area_get_height(&layer_drawn->buf_area); - int32_t w = lv_area_get_width(&layer_drawn->buf_area); - uint32_t layer_size_byte = h * lv_draw_buf_width_to_stride(w, layer_drawn->color_format); + uint32_t layer_size_byte = h * layer_drawn->draw_buf->header.stride; _draw_info.used_memory_for_layers_kb -= get_layer_size_kb(layer_size_byte); LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB\n", _draw_info.used_memory_for_layers_kb); @@ -228,7 +250,7 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) t = t_next; } - bool render_running = false; + bool task_dispatched = false; /*This layer is ready, enable blending its buffer*/ if(layer->parent && layer->all_tasks_added && layer->draw_task_head == NULL) { @@ -253,13 +275,13 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) lv_draw_unit_t * u = _draw_info.unit_head; while(u) { int32_t taken_cnt = u->dispatch_cb(u, layer); - if(taken_cnt >= 0) render_running = true; + if(taken_cnt != LV_DRAW_UNIT_IDLE) task_dispatched = true; u = u->next; } } LV_PROFILER_END; - return render_running; + return task_dispatched; } void lv_draw_dispatch_wait_for_request(void) @@ -281,13 +303,18 @@ void lv_draw_dispatch_request(void) #endif } +uint32_t lv_draw_get_unit_count(void) +{ + return _draw_info.unit_cnt; +} + lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id) { LV_PROFILER_BEGIN; /*If the first task is screen sized, there cannot be independent areas*/ if(layer->draw_task_head) { - int32_t hor_res = lv_display_get_horizontal_resolution(_lv_refr_get_disp_refreshing()); - int32_t ver_res = lv_display_get_vertical_resolution(_lv_refr_get_disp_refreshing()); + int32_t hor_res = lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing()); + int32_t ver_res = lv_display_get_vertical_resolution(lv_refr_get_disp_refreshing()); lv_draw_task_t * t = layer->draw_task_head; if(t->state != LV_DRAW_TASK_STATE_QUEUED && t->area.x1 <= 0 && t->area.x2 >= hor_res - 1 && @@ -301,7 +328,7 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas while(t) { /*Find a queued and independent task*/ if(t->state == LV_DRAW_TASK_STATE_QUEUED && - (t->preferred_draw_unit_id == LV_DRAW_UNIT_ID_ANY || t->preferred_draw_unit_id == draw_unit_id) && + (t->preferred_draw_unit_id == LV_DRAW_UNIT_NONE || t->preferred_draw_unit_id == draw_unit_id) && is_independent(layer, t)) { LV_PROFILER_END; return t; @@ -324,7 +351,7 @@ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) lv_draw_task_t * t = t_check->next; while(t) { if((t->state == LV_DRAW_TASK_STATE_QUEUED || t->state == LV_DRAW_TASK_STATE_WAITING) && - _lv_area_is_on(&t_check->area, &t->area)) { + lv_area_is_on(&t_check->area, &t->area)) { cnt++; } @@ -336,7 +363,7 @@ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t color_format, const lv_area_t * area) { - lv_display_t * disp = _lv_refr_get_disp_refreshing(); + lv_display_t * disp = lv_refr_get_disp_refreshing(); lv_layer_t * new_layer = lv_malloc_zeroed(sizeof(lv_layer_t)); LV_ASSERT_MALLOC(new_layer); if(new_layer == NULL) return NULL; @@ -344,8 +371,13 @@ lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t c new_layer->parent = parent_layer; new_layer->_clip_area = *area; new_layer->buf_area = *area; + new_layer->phy_clip_area = *area; new_layer->color_format = color_format; +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_matrix_identity(&new_layer->matrix); +#endif + if(disp->layer_head) { lv_layer_t * tail = disp->layer_head; while(tail->next) tail = tail->next; @@ -392,6 +424,21 @@ void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y) return lv_draw_buf_goto_xy(layer->draw_buf, x, y); } +lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t) +{ + return t->type; +} + +void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t) +{ + return t->draw_dsc; +} + +void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area) +{ + *area = t->area; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -411,7 +458,7 @@ static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check) while(t && t != t_check) { if(t->state != LV_DRAW_TASK_STATE_READY) { lv_area_t a; - if(_lv_area_intersect(&a, &t->_real_area, &t_check->_real_area)) { + if(lv_area_intersect(&a, &t->_real_area, &t_check->_real_area)) { LV_PROFILER_END; return false; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h index 0672bc55d..298526776 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h @@ -3,6 +3,10 @@ * */ +/** + * Modified by NXP in 2024 + */ + #ifndef LV_DRAW_H #define LV_DRAW_H @@ -19,6 +23,7 @@ extern "C" { #include "../misc/lv_style.h" #include "../misc/lv_text.h" #include "../misc/lv_profiler.h" +#include "../misc/lv_matrix.h" #include "lv_image_decoder.h" #include "../osal/lv_os.h" #include "lv_draw_buf.h" @@ -26,13 +31,21 @@ extern "C" { /********************* * DEFINES *********************/ -#define LV_DRAW_UNIT_ID_ANY 0 +#define LV_DRAW_UNIT_NONE 0 +#define LV_DRAW_UNIT_IDLE -1 /**< The draw unit is idle, new dispatching might be requested to try again */ + +#if LV_DRAW_TRANSFORM_USE_MATRIX +#if !LV_USE_MATRIX +#error "LV_DRAW_TRANSFORM_USE_MATRIX requires LV_USE_MATRIX = 1" +#endif +#endif /********************** * TYPEDEFS **********************/ typedef enum { + LV_DRAW_TASK_TYPE_NONE = 0, LV_DRAW_TASK_TYPE_FILL, LV_DRAW_TASK_TYPE_BORDER, LV_DRAW_TASK_TYPE_BOX_SHADOW, @@ -54,97 +67,7 @@ typedef enum { LV_DRAW_TASK_STATE_READY, } lv_draw_task_state_t; -struct _lv_draw_task_t { - lv_draw_task_t * next; - - lv_draw_task_type_t type; - - /** - * The area where to draw - */ - lv_area_t area; - - /** - * The real draw area. E.g. for shadow, outline, or transformed images it's different from `area` - */ - lv_area_t _real_area; - - /** The original area which is updated*/ - lv_area_t clip_area_original; - - /** - * The clip area of the layer is saved here when the draw task is created. - * As the clip area of the layer can be changed as new draw tasks are added its current value needs to be saved. - * Therefore during drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks. - */ - lv_area_t clip_area; - - volatile int state; /*int instead of lv_draw_task_state_t to be sure its atomic*/ - - void * draw_dsc; - - /** - * The ID of the draw_unit which should take this task - */ - uint8_t preferred_draw_unit_id; - - /** - * Set to which extent `preferred_draw_unit_id` is good at this task. - * 80: means 20% better (faster) than software rendering - * 100: the default value - * 110: means 10% worse (slower) than software rendering - */ - uint8_t preference_score; - -}; - -typedef struct { - void * user_data; -} lv_draw_mask_t; - -struct _lv_draw_unit_t { - lv_draw_unit_t * next; - - /** - * The target_layer on which drawing should happen - */ - lv_layer_t * target_layer; - - const lv_area_t * clip_area; - - /** - * Called to try to assign a draw task to itself. - * `lv_draw_get_next_available_task` can be used to get an independent draw task. - * A draw task should be assign only if the draw unit can draw it too - * @param draw_unit pointer to the draw unit - * @param layer pointer to a layer on which the draw task should be drawn - * @return >=0: The number of taken draw task: - * 0 means the task has not yet been completed. - * 1 means a new task has been accepted. - * -1: The draw unit wanted to work on a task but couldn't do that - * due to some errors (e.g. out of memory). - * It signals that LVGL should call the dispatcher later again - * to let draw unit try to start the rendering again. - */ - int32_t (*dispatch_cb)(lv_draw_unit_t * draw_unit, lv_layer_t * layer); - - /** - * - * @param draw_unit - * @param task - * @return - */ - int32_t (*evaluate_cb)(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); - - /** - * Called to delete draw unit. - * @param draw_unit - * @return - */ - int32_t (*delete_cb)(lv_draw_unit_t * draw_unit); -}; - -struct _lv_layer_t { +struct lv_layer_t { /** Target draw buffer of the layer*/ lv_draw_buf_t * draw_buf; @@ -165,6 +88,16 @@ struct _lv_layer_t { */ lv_area_t _clip_area; + /** + * The physical clipping area relative to the display. + */ + lv_area_t phy_clip_area; + +#if LV_DRAW_TRANSFORM_USE_MATRIX + /** Transform matrix to be applied when rendering the layer */ + lv_matrix_t matrix; +#endif + /** Linked list of draw tasks */ lv_draw_task_t * draw_task_head; @@ -176,7 +109,7 @@ struct _lv_layer_t { typedef struct { lv_obj_t * obj; - uint32_t part; + lv_part_t part; uint32_t id1; uint32_t id2; lv_layer_t * layer; @@ -184,18 +117,6 @@ typedef struct { void * user_data; } lv_draw_dsc_base_t; -typedef struct { - lv_draw_unit_t * unit_head; - uint32_t used_memory_for_layers_kb; -#if LV_USE_OS - lv_thread_sync_t sync; -#else - int dispatch_req; -#endif - lv_mutex_t circle_cache_mutex; - bool task_running; -} lv_draw_global_info_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -231,7 +152,7 @@ lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords); * It will send an event about the new draw task to the widget * and assign it to a draw unit. * @param layer pointer to a layer - * @param t poinr to a draw task + * @param t pointer to a draw task */ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t); @@ -254,24 +175,35 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer); */ void lv_draw_dispatch_wait_for_request(void); +/** + * Wait for draw finish in case of asynchronous task execution. + * If `LV_USE_OS == 0` it just return. + */ +void lv_draw_wait_for_finish(void); + /** * When a draw unit finished a draw task it needs to request dispatching * to let LVGL assign a new draw task to it */ void lv_draw_dispatch_request(void); +/** + * Get the total number of draw units. + */ +uint32_t lv_draw_get_unit_count(void); + /** * Find and available draw task * @param layer the draw ctx to search in * @param t_prev continue searching from this task - * @param draw_unit_id check the task where `preferred_draw_unit_id` equals this value or `LV_DRAW_UNIT_ID_ANY` + * @param draw_unit_id check the task where `preferred_draw_unit_id` equals this value or `LV_DRAW_UNIT_NONE` * @return tan available draw task or NULL if there is no any */ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id); /** * Tell how many draw task are waiting to be drawn on the area of `t_check`. - * It can be used to determine if a GPU shall combine many draw tasks in to one or not. + * It can be used to determine if a GPU shall combine many draw tasks into one or not. * If a lot of tasks are waiting for the current ones it makes sense to draw them one-by-one * to not block the dependent tasks' rendering * @param t_check the task whose dependent tasks shall be counted @@ -304,6 +236,27 @@ void * lv_draw_layer_alloc_buf(lv_layer_t * layer); */ void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y); +/** + * Get the type of a draw task + * @param t the draw task to get the type of + * @return the draw task type +*/ +lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t); + +/** + * Get the draw descriptor of a draw task + * @param t the draw task to get the draw descriptor of + * @return a void pointer to the draw descriptor +*/ +void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t); + +/** + * Get the draw area of a draw task + * @param t the draw task to get the draw area of + * @param area the destination where the draw area will be stored +*/ +void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area); + /********************** * GLOBAL VARIABLES **********************/ @@ -312,17 +265,6 @@ void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y); * MACROS **********************/ -/********************** - * POST INCLUDES - *********************/ -#include "lv_draw_rect.h" -#include "lv_draw_label.h" -#include "lv_draw_image.h" -#include "lv_draw_arc.h" -#include "lv_draw_line.h" -#include "lv_draw_triangle.h" -#include "lv_draw_mask.h" - #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c index 634c0429e..f092ea73f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "lv_draw_private.h" #include "../core/lv_obj.h" #include "lv_draw_arc.h" #include "../core/lv_obj_event.h" @@ -41,6 +42,7 @@ void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc) dsc->width = 1; dsc->opa = LV_OPA_COVER; dsc->color = lv_color_black(); + dsc->base.dsc_size = sizeof(lv_draw_arc_dsc_t); } lv_draw_arc_dsc_t * lv_draw_task_get_arc_dsc(lv_draw_task_t * task) diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c index bd7f7406e..daebe9543 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c @@ -6,15 +6,19 @@ /********************* * INCLUDES *********************/ +#include "lv_draw_buf_private.h" #include "../misc/lv_types.h" -#include "lv_draw_buf.h" #include "../stdlib/lv_string.h" #include "../core/lv_global.h" +#include "../misc/lv_math.h" +#include "../misc/lv_area_private.h" /********************* * DEFINES *********************/ -#define handlers LV_GLOBAL_DEFAULT()->draw_buf_handlers +#define default_handlers LV_GLOBAL_DEFAULT()->draw_buf_handlers +#define font_draw_buf_handlers LV_GLOBAL_DEFAULT()->font_draw_buf_handlers +#define image_cache_draw_buf_handlers LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers /********************** * TYPEDEFS @@ -26,10 +30,12 @@ static void * buf_malloc(size_t size, lv_color_format_t color_format); static void buf_free(void * buf); static void * buf_align(void * buf, lv_color_format_t color_format); -static void * draw_buf_malloc(size_t size_bytes, lv_color_format_t color_format); -static void draw_buf_free(void * buf); +static void * draw_buf_malloc(const lv_draw_buf_handlers_t * handler, size_t size_bytes, + lv_color_format_t color_format); +static void draw_buf_free(const lv_draw_buf_handlers_t * handler, void * buf); static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format); static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride); +static void draw_buf_get_full_area(const lv_draw_buf_t * draw_buf, lv_area_t * full_area); /********************** * STATIC VARIABLES @@ -43,74 +49,132 @@ static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format * GLOBAL FUNCTIONS **********************/ -void _lv_draw_buf_init_handlers(void) +void lv_draw_buf_init_handlers(void) { - lv_memzero(&handlers, sizeof(lv_draw_buf_handlers_t)); - handlers.buf_malloc_cb = buf_malloc; - handlers.buf_free_cb = buf_free; - handlers.align_pointer_cb = buf_align; - handlers.invalidate_cache_cb = NULL; - handlers.width_to_stride_cb = width_to_stride; + lv_draw_buf_init_with_default_handlers(&default_handlers); + lv_draw_buf_init_with_default_handlers(&font_draw_buf_handlers); + lv_draw_buf_init_with_default_handlers(&image_cache_draw_buf_handlers); +} + +void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers) +{ + lv_draw_buf_handlers_init(handlers, buf_malloc, buf_free, buf_align, NULL, NULL, width_to_stride); +} + +void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, + lv_draw_buf_malloc_cb buf_malloc_cb, + lv_draw_buf_free_cb buf_free_cb, + lv_draw_buf_align_cb align_pointer_cb, + lv_draw_buf_cache_operation_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb flush_cache_cb, + lv_draw_buf_width_to_stride_cb width_to_stride_cb) +{ + lv_memzero(handlers, sizeof(lv_draw_buf_handlers_t)); + handlers->buf_malloc_cb = buf_malloc_cb; + handlers->buf_free_cb = buf_free_cb; + handlers->align_pointer_cb = align_pointer_cb; + handlers->invalidate_cache_cb = invalidate_cache_cb; + handlers->flush_cache_cb = flush_cache_cb; + handlers->width_to_stride_cb = width_to_stride_cb; } lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void) { - return &handlers; + return &default_handlers; } uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format) { - if(handlers.width_to_stride_cb) return handlers.width_to_stride_cb(w, color_format); + return lv_draw_buf_width_to_stride_ex(&default_handlers, w, color_format); +} + +uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, + lv_color_format_t color_format) +{ + if(handlers->width_to_stride_cb) return handlers->width_to_stride_cb(w, color_format); else return 0; } void * lv_draw_buf_align(void * data, lv_color_format_t color_format) { - if(handlers.align_pointer_cb) return handlers.align_pointer_cb(data, color_format); + return lv_draw_buf_align_ex(&default_handlers, data, color_format); +} + +void * lv_draw_buf_align_ex(const lv_draw_buf_handlers_t * handlers, void * data, lv_color_format_t color_format) +{ + if(handlers->align_pointer_cb) return handlers->align_pointer_cb(data, color_format); else return NULL; } void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) { - if(handlers.invalidate_cache_cb) { - LV_ASSERT_NULL(draw_buf); - const lv_image_header_t * header = &draw_buf->header; - lv_area_t full; - if(area == NULL) { - full = (lv_area_t) { - 0, 0, header->w - 1, header->h - 1 - }; - area = &full; - } - handlers.invalidate_cache_cb(draw_buf, area); + LV_ASSERT_NULL(draw_buf); + LV_ASSERT_NULL(draw_buf->handlers); + + const lv_draw_buf_handlers_t * handlers = draw_buf->handlers; + if(!handlers->invalidate_cache_cb) { + return; } + + lv_area_t full; + if(area == NULL) { + draw_buf_get_full_area(draw_buf, &full); + area = &full; + } + + handlers->invalidate_cache_cb(draw_buf, area); +} + +void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + LV_ASSERT_NULL(draw_buf); + LV_ASSERT_NULL(draw_buf->handlers); + + const lv_draw_buf_handlers_t * handlers = draw_buf->handlers; + if(!handlers->flush_cache_cb) { + return; + } + + lv_area_t full; + if(area == NULL) { + draw_buf_get_full_area(draw_buf, &full); + area = &full; + } + + handlers->flush_cache_cb(draw_buf, area); } void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) { LV_ASSERT_NULL(draw_buf); - if(a && lv_area_get_width(a) < 0) return; - if(a && lv_area_get_height(a) < 0) return; const lv_image_header_t * header = &draw_buf->header; uint32_t stride = header->stride; if(a == NULL) { - lv_memzero(draw_buf->data, header->h * stride); + uint8_t * buf = lv_draw_buf_goto_xy(draw_buf, 0, 0); + lv_memzero(buf, header->h * stride); + return; } - else { - uint8_t * bufc; - uint32_t line_length; - int32_t start_y, end_y; - uint8_t px_size = lv_color_format_get_size(header->cf); - bufc = lv_draw_buf_goto_xy(draw_buf, a->x1, a->y1); - line_length = lv_area_get_width(a) * px_size; - start_y = a->y1; - end_y = a->y2; - for(; start_y <= end_y; start_y++) { - lv_memzero(bufc, line_length); - bufc += stride; - } + + lv_area_t a_draw_buf; + a_draw_buf.x1 = 0; + a_draw_buf.y1 = 0; + a_draw_buf.x2 = draw_buf->header.w - 1; + a_draw_buf.y2 = draw_buf->header.h - 1; + + lv_area_t a_clipped; + if(!lv_area_intersect(&a_clipped, a, &a_draw_buf)) return; + if(lv_area_get_width(&a_clipped) <= 0) return; + if(lv_area_get_height(&a_clipped) <= 0) return; + + uint8_t * buf = lv_draw_buf_goto_xy(draw_buf, a_clipped.x1, a_clipped.y1); + uint8_t bpp = lv_color_format_get_bpp(header->cf); + uint32_t line_length = (lv_area_get_width(&a_clipped) * bpp + 7) >> 3; + int32_t y; + for(y = a_clipped.y1; y <= a_clipped.y2; y++) { + lv_memzero(buf, line_length); + buf += stride; } } @@ -191,16 +255,23 @@ lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, l header->flags = 0; header->magic = LV_IMAGE_HEADER_MAGIC; - draw_buf->data = lv_draw_buf_align(data, cf); + draw_buf->data = data; draw_buf->unaligned_data = data; + draw_buf->handlers = &default_handlers; draw_buf->data_size = data_size; - if(draw_buf->data != draw_buf->unaligned_data) { + if(lv_draw_buf_align(data, cf) != draw_buf->unaligned_data) { LV_LOG_WARN("Data is not aligned, ignored"); } return LV_RESULT_OK; } lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride) +{ + return lv_draw_buf_create_ex(&default_handlers, w, h, cf, stride); +} + +lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, uint32_t h, + lv_color_format_t cf, uint32_t stride) { lv_draw_buf_t * draw_buf = lv_malloc_zeroed(sizeof(lv_draw_buf_t)); LV_ASSERT_MALLOC(draw_buf); @@ -209,7 +280,7 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t size = _calculate_draw_buf_size(w, h, cf, stride); - void * buf = draw_buf_malloc(size, cf); + void * buf = draw_buf_malloc(handlers, size, cf); /*Do not assert here as LVGL or the app might just want to try creating a draw_buf*/ if(buf == NULL) { LV_LOG_WARN("No memory: %"LV_PRIu32"x%"LV_PRIu32", cf: %d, stride: %"LV_PRIu32", %"LV_PRIu32"Byte, ", @@ -227,13 +298,19 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, draw_buf->data = lv_draw_buf_align(buf, cf); draw_buf->unaligned_data = buf; draw_buf->data_size = size; + draw_buf->handlers = handlers; return draw_buf; } lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf) +{ + return lv_draw_buf_dup_ex(&default_handlers, draw_buf); +} + +lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf) { const lv_image_header_t * header = &draw_buf->header; - lv_draw_buf_t * new_buf = lv_draw_buf_create(header->w, header->h, header->cf, header->stride); + lv_draw_buf_t * new_buf = lv_draw_buf_create_ex(handlers, header->w, header->h, header->cf, header->stride); if(new_buf == NULL) return NULL; new_buf->header.flags = draw_buf->header.flags; @@ -271,14 +348,17 @@ lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t return draw_buf; } -void lv_draw_buf_destroy(lv_draw_buf_t * buf) +void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf) { - LV_ASSERT_NULL(buf); - if(buf == NULL) return; + LV_ASSERT_NULL(draw_buf); + if(draw_buf == NULL) return; - if(buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) { - draw_buf_free(buf->unaligned_data); - lv_free(buf); + if(draw_buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) { + LV_ASSERT_NULL(draw_buf->handlers); + + const lv_draw_buf_handlers_t * handlers = draw_buf->handlers; + draw_buf_free(handlers, draw_buf->unaligned_data); + lv_free(draw_buf); } else { LV_LOG_ERROR("draw buffer is not allocated, ignored"); @@ -298,7 +378,7 @@ void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y) if(x == 0) return data; - return data + x * lv_color_format_get_size(buf->header.cf); + return data + x * lv_color_format_get_bpp(buf->header.cf) / 8; } lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride) @@ -312,6 +392,10 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride) uint32_t w = header->w; uint32_t h = header->h; + if(!lv_draw_buf_has_flag(src, LV_IMAGE_FLAGS_MODIFIABLE)) { + return LV_RESULT_INVALID; + } + /*Use global stride*/ if(stride == 0) stride = lv_draw_buf_width_to_stride(w, header->cf); @@ -448,8 +532,52 @@ void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32 return; } - uint8_t * buf = (uint8_t *)draw_buf->data; - lv_memcpy(&buf[index * sizeof(color)], &color, sizeof(color)); + lv_color32_t * palette = (lv_color32_t *)draw_buf->data; + palette[index] = color; +} + +bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) +{ + return draw_buf->header.flags & flag; +} + +void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) +{ + draw_buf->header.flags |= flag; +} + +void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) +{ + draw_buf->header.flags &= ~flag; +} + +void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img) +{ + lv_draw_buf_init(buf, img->header.w, img->header.h, img->header.cf, img->header.stride, + (void *)img->data, img->data_size); + buf->header.flags = img->header.flags; +} + +void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img) +{ + lv_memcpy((void *)img, buf, sizeof(lv_image_dsc_t)); +} + +void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c) +{ + LV_LOG_WARN("Deprecated API, use lv_draw_buf_set_palette instead."); + lv_draw_buf_set_palette((lv_draw_buf_t *)dsc, id, c); +} + +void lv_image_buf_free(lv_image_dsc_t * dsc) +{ + LV_LOG_WARN("Deprecated API, use lv_draw_buf_destroy instead."); + if(dsc != NULL) { + if(dsc->data != NULL) + lv_free((void *)dsc->data); + + lv_free((void *)dsc); + } } /********************** @@ -476,8 +604,7 @@ static void * buf_align(void * buf, lv_color_format_t color_format) uint8_t * buf_u8 = buf; if(buf_u8) { - buf_u8 += LV_DRAW_BUF_ALIGN - 1; - buf_u8 = (uint8_t *)((lv_uintptr_t) buf_u8 & ~(LV_DRAW_BUF_ALIGN - 1)); + buf_u8 = (uint8_t *)LV_ROUND_UP((lv_uintptr_t)buf_u8, LV_DRAW_BUF_ALIGN); } return buf_u8; } @@ -487,18 +614,21 @@ static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format) uint32_t width_byte; width_byte = w * lv_color_format_get_bpp(color_format); width_byte = (width_byte + 7) >> 3; /*Round up*/ - return (width_byte + LV_DRAW_BUF_STRIDE_ALIGN - 1) & ~(LV_DRAW_BUF_STRIDE_ALIGN - 1); + + return LV_ROUND_UP(width_byte, LV_DRAW_BUF_STRIDE_ALIGN); } -static void * draw_buf_malloc(size_t size_bytes, lv_color_format_t color_format) +static void * draw_buf_malloc(const lv_draw_buf_handlers_t * handlers, size_t size_bytes, + lv_color_format_t color_format) { - if(handlers.buf_malloc_cb) return handlers.buf_malloc_cb(size_bytes, color_format); + if(handlers->buf_malloc_cb) return handlers->buf_malloc_cb(size_bytes, color_format); else return NULL; } -static void draw_buf_free(void * buf) +static void draw_buf_free(const lv_draw_buf_handlers_t * handlers, void * buf) { - if(handlers.buf_free_cb) handlers.buf_free_cb(buf); + if(handlers->buf_free_cb) + handlers->buf_free_cb(buf); } /** @@ -521,3 +651,9 @@ static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format return size; } + +static void draw_buf_get_full_area(const lv_draw_buf_t * draw_buf, lv_area_t * full_area) +{ + const lv_image_header_t * header = &draw_buf->header; + lv_area_set(full_area, 0, 0, header->w - 1, header->h - 1); +} diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h index 499285b9a..9cc6526e5 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h @@ -13,6 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ +#include "../misc/lv_types.h" #include "../misc/lv_area.h" #include "../misc/lv_color.h" #include "../stdlib/lv_string.h" @@ -22,39 +23,32 @@ extern "C" { * DEFINES *********************/ -/*Use this value to let LVGL calculate stride automatically*/ +/** Use this value to let LVGL calculate stride automatically */ #define LV_STRIDE_AUTO 0 LV_EXPORT_CONST_INT(LV_STRIDE_AUTO); -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_image_header_t header; - uint32_t data_size; /*Total buf size in bytes*/ - uint8_t * data; - void * unaligned_data; /*Unaligned address of `data`, used internally by lvgl*/ -} lv_draw_buf_t; - /** * Stride alignment for draw buffers. * It may vary between different color formats and hardware. * Refine it to suit your needs. */ -#define _LV_DRAW_BUF_STRIDE(w, cf) \ - ((((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8 + (LV_DRAW_BUF_STRIDE_ALIGN) - 1) & ~((LV_DRAW_BUF_STRIDE_ALIGN) - 1)) +#define LV_DRAW_BUF_STRIDE(w, cf) \ + LV_ROUND_UP(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8, LV_DRAW_BUF_STRIDE_ALIGN) -#define _LV_DRAW_BUF_SIZE(w, h, cf) \ - (_LV_DRAW_BUF_STRIDE(w, cf) * (h)) +/** Allocate a slightly larger buffer, so we can adjust the start address to meet alignment */ +#define LV_DRAW_BUF_SIZE(w, h, cf) \ + (LV_DRAW_BUF_STRIDE(w, cf) * (h) + LV_DRAW_BUF_ALIGN + \ + LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t)) /** * Define a static draw buffer with the given width, height, and color format. * Stride alignment is set to LV_DRAW_BUF_STRIDE_ALIGN. + * + * For platform that needs special buffer alignment, call LV_DRAW_BUF_INIT_STATIC. */ -#define LV_DRAW_BUF_DEFINE(name, _w, _h, _cf) \ - static uint8_t buf_##name[_LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \ +#define LV_DRAW_BUF_DEFINE_STATIC(name, _w, _h, _cf) \ + static uint8_t buf_##name[LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \ static lv_draw_buf_t name = { \ .header = { \ .magic = LV_IMAGE_HEADER_MAGIC, \ @@ -62,7 +56,7 @@ typedef struct { .flags = LV_IMAGE_FLAGS_MODIFIABLE, \ .w = (_w), \ .h = (_h), \ - .stride = _LV_DRAW_BUF_STRIDE(_w, _cf), \ + .stride = LV_DRAW_BUF_STRIDE(_w, _cf), \ .reserved_2 = 0, \ }, \ .data_size = sizeof(buf_##name), \ @@ -70,32 +64,64 @@ typedef struct { .unaligned_data = buf_##name, \ } +#define LV_DRAW_BUF_INIT_STATIC(name) \ + do { \ + lv_image_header_t * header = &name.header; \ + lv_draw_buf_init(&name, header->w, header->h, header->cf, header->stride, buf_##name, sizeof(buf_##name)); \ + lv_draw_buf_set_flag(&name, LV_IMAGE_FLAGS_MODIFIABLE); \ + } while(0) + +/********************** + * TYPEDEFS + **********************/ + typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format); typedef void (*lv_draw_buf_free_cb)(void * draw_buf); typedef void * (*lv_draw_buf_align_cb)(void * buf, lv_color_format_t color_format); -typedef void (*lv_draw_buf_invalidate_cache_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format); -typedef struct { - lv_draw_buf_malloc_cb buf_malloc_cb; - lv_draw_buf_free_cb buf_free_cb; - lv_draw_buf_align_cb align_pointer_cb; - lv_draw_buf_invalidate_cache_cb invalidate_cache_cb; - lv_draw_buf_width_to_stride_cb width_to_stride_cb; -} lv_draw_buf_handlers_t; +struct lv_draw_buf_t { + lv_image_header_t header; + uint32_t data_size; /**< Total buf size in bytes */ + uint8_t * data; + void * unaligned_data; /**< Unaligned address of `data`, used internally by lvgl */ + const lv_draw_buf_handlers_t * handlers; /**< draw buffer alloc/free ops. */ +}; /********************** * GLOBAL PROTOTYPES **********************/ /** - * Called internally to initialize the draw_buf_handlers in lv_global + * Initialize the draw buffer with the default handlers. + * + * @param handlers the draw buffer handlers to set */ -void _lv_draw_buf_init_handlers(void); +void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers); + +/** + * Initialize the draw buffer with given handlers. + * + * @param handlers the draw buffer handlers to set + * @param buf_malloc_cb the callback to allocate memory for the buffer + * @param buf_free_cb the callback to free memory of the buffer + * @param align_pointer_cb the callback to align the buffer + * @param invalidate_cache_cb the callback to invalidate the cache of the buffer + * @param flush_cache_cb the callback to flush buffer + * @param width_to_stride_cb the callback to calculate the stride based on the width and color format + */ +void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, + lv_draw_buf_malloc_cb buf_malloc_cb, + lv_draw_buf_free_cb buf_free_cb, + lv_draw_buf_align_cb align_pointer_cb, + lv_draw_buf_cache_operation_cb invalidate_cache_cb, + lv_draw_buf_cache_operation_cb flush_cache_cb, + lv_draw_buf_width_to_stride_cb width_to_stride_cb); /** * Get the struct which holds the callbacks for draw buf management. @@ -112,6 +138,16 @@ lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void); */ void * lv_draw_buf_align(void * buf, lv_color_format_t color_format); +/** + * Align the address of a buffer with custom draw buffer handlers. + * The buffer needs to be large enough for the real data after alignment + * @param handlers the draw buffer handlers + * @param buf the data to align + * @param color_format the color format of the buffer + * @return the aligned buffer + */ +void * lv_draw_buf_align_ex(const lv_draw_buf_handlers_t * handlers, void * buf, lv_color_format_t color_format); + /** * Invalidate the cache of the buffer * @param draw_buf the draw buffer needs to be invalidated @@ -120,6 +156,14 @@ void * lv_draw_buf_align(void * buf, lv_color_format_t color_format); */ void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +/** + * Flush the cache of the buffer + * @param draw_buf the draw buffer needs to be flushed + * @param area the area to flush in the buffer, + * use NULL to flush the whole draw buffer address range + */ +void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + /** * Calculate the stride in bytes based on a width and color format * @param w the width in pixels @@ -128,6 +172,16 @@ void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_ */ uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format); +/** + * Calculate the stride in bytes based on a width and color format + * @param handlers the draw buffer handlers + * @param w the width in pixels + * @param color_format the color format + * @return the stride in bytes + */ +uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, + lv_color_format_t color_format); + /** * Clear an area on the buffer * @param draw_buf pointer to draw buffer @@ -136,7 +190,7 @@ uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format) void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a); /** - * Copy an area from a buffer to an other + * Copy an area from a buffer to another * @param dest pointer to the destination draw buffer * @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer * @param src pointer to the source draw buffer @@ -163,7 +217,39 @@ void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride); /** - * Initialize a draw buf with the given buffer and parameters. + * Note: Eventually, lv_draw_buf_malloc/free will be kept as private. + * For now, we use `create` to distinguish with malloc. + * + * Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it + * that meets specified requirements. + * + * @param handlers the draw buffer handlers + * @param w the buffer width in pixels + * @param h the buffer height in pixels + * @param cf the color format for image + * @param stride the stride in bytes for image. Use 0 for automatic calculation based on + * w, cf, and global stride alignment configuration. + */ +lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, uint32_t h, + lv_color_format_t cf, uint32_t stride); + +/** + * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. + * @param draw_buf the draw buf to duplicate + * @return the duplicated draw buf on success, NULL if failed + */ +lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf); + +/** + * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. + * @param handlers the draw buffer handlers + * @param draw_buf the draw buf to duplicate + * @return the duplicated draw buf on success, NULL if failed + */ +lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf); + +/** + * Initialize a draw buf with the given buffer and parameters. Clear draw buffer flag to zero. * @param draw_buf the draw buf to initialize * @param w the buffer width in pixels * @param h the buffer height in pixels @@ -176,13 +262,6 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride, void * data, uint32_t data_size); -/** - * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. - * @param draw_buf the draw buf to duplicate - * @return the duplicated draw buf on success, NULL if failed - */ -lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf); - /** * Keep using the existing memory, reshape the draw buffer to the given width and height. * Return NULL if data_size is smaller than the required size. @@ -196,10 +275,12 @@ lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t uint32_t stride); /** - * Destroy a draw buf by free the actual buffer if it's marked as LV_IMAGE_FLAGS_ALLOCATED in header. + * Destroy a draw buf by freeing the actual buffer if it's marked as LV_IMAGE_FLAGS_ALLOCATED in header. * Then free the lv_draw_buf_t struct. + * + * @param draw_buf the draw buffer to destroy */ -void lv_draw_buf_destroy(lv_draw_buf_t * buf); +void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf); /** * Return pointer to the buffer at the given coordinates @@ -223,36 +304,20 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride); */ lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf); -static inline bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) -{ - return draw_buf->header.flags & flag; -} +bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); -static inline void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) -{ - draw_buf->header.flags |= flag; -} +void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); -static inline void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) -{ - draw_buf->header.flags &= ~flag; -} +void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); /** * As of now, draw buf share same definition as `lv_image_dsc_t`. * And is interchangeable with `lv_image_dsc_t`. */ -static inline void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img) -{ - lv_memcpy(buf, img, sizeof(lv_image_dsc_t)); - buf->unaligned_data = buf->data; -} +void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img); -static inline void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img) -{ - lv_memcpy((void *)img, buf, sizeof(lv_image_dsc_t)); -} +void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img); /** * Set the palette color of an indexed image. Valid only for `LV_COLOR_FORMAT_I1/2/4/8` @@ -269,26 +334,13 @@ void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32 /** * @deprecated Use lv_draw_buf_set_palette instead. */ -static inline void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c) -{ - LV_LOG_WARN("Deprecated API, use lv_draw_buf_set_palette instead."); - lv_draw_buf_set_palette((lv_draw_buf_t *)dsc, id, c); -} +void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c); /** * @deprecated Use lv_draw_buffer_create/destroy instead. * Free the data pointer and dsc struct of an image. */ -static inline void lv_image_buf_free(lv_image_dsc_t * dsc) -{ - LV_LOG_WARN("Deprecated API, use lv_draw_buf_destroy instead."); - if(dsc != NULL) { - if(dsc->data != NULL) - lv_free((void *)dsc->data); - - lv_free((void *)dsc); - } -} +void lv_image_buf_free(lv_image_dsc_t * dsc); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf_private.h new file mode 100644 index 000000000..051f9ba7c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_draw_buf_private.h + * + */ + +#ifndef LV_DRAW_BUF_PRIVATE_H +#define LV_DRAW_BUF_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_draw_buf_handlers_t { + lv_draw_buf_malloc_cb buf_malloc_cb; + lv_draw_buf_free_cb buf_free_cb; + lv_draw_buf_align_cb align_pointer_cb; + lv_draw_buf_cache_operation_cb invalidate_cache_cb; + lv_draw_buf_cache_operation_cb flush_cache_cb; + lv_draw_buf_width_to_stride_cb width_to_stride_cb; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Called internally to initialize the draw_buf_handlers in lv_global + */ +void lv_draw_buf_init_handlers(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_BUF_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.c index 941b631c1..45804573e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.c @@ -6,7 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_draw_image.h" +#include "lv_draw_image_private.h" +#include "../misc/lv_area_private.h" +#include "lv_image_decoder_private.h" +#include "lv_draw_private.h" #include "../display/lv_display.h" #include "../misc/lv_log.h" #include "../misc/lv_math.h" @@ -51,7 +54,7 @@ void lv_draw_image_dsc_init(lv_draw_image_dsc_t * dsc) dsc->scale_x = LV_SCALE_NONE; dsc->scale_y = LV_SCALE_NONE; dsc->antialias = LV_COLOR_DEPTH > 8 ? 1 : 0; - dsc->original_area.x2 = LV_COORD_MIN; /*Indicate invalid area by default by setting a negative size*/ + dsc->image_area.x2 = LV_COORD_MIN; /*Indicate invalid area by default by setting a negative size*/ dsc->base.dsc_size = sizeof(lv_draw_image_dsc_t); } @@ -62,6 +65,11 @@ lv_draw_image_dsc_t * lv_draw_task_get_image_dsc(lv_draw_task_t * task) void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) { + if(dsc->scale_x <= 0 || dsc->scale_y <= 0) { + /* NOT draw if scale is negative or zero */ + return; + } + lv_draw_task_t * t = lv_draw_add_task(layer, coords); t->draw_dsc = lv_malloc(sizeof(*dsc)); @@ -69,8 +77,8 @@ void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv t->type = LV_DRAW_TASK_TYPE_LAYER; t->state = LV_DRAW_TASK_STATE_WAITING; - _lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords), - dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); + lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords), + dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); lv_area_move(&t->_real_area, coords->x1, coords->y1); lv_layer_t * layer_to_draw = (lv_layer_t *)dsc->src; @@ -87,6 +95,11 @@ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv } if(dsc->opa <= LV_OPA_MIN) return; + if(dsc->scale_x <= 0 || dsc->scale_y <= 0) { + /* NOT draw if scale is negative or zero */ + return; + } + LV_PROFILER_BEGIN; lv_draw_image_dsc_t * new_image_dsc = lv_malloc(sizeof(*dsc)); @@ -102,8 +115,8 @@ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv t->draw_dsc = new_image_dsc; t->type = LV_DRAW_TASK_TYPE_IMAGE; - _lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords), - dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); + lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords), + dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); lv_area_move(&t->_real_area, coords->x1, coords->y1); lv_draw_finalize_task_creation(layer, t); @@ -127,8 +140,8 @@ lv_image_src_t lv_image_src_get_type(const void * src) } } -void _lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb) +void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb) { if(draw_core_cb == NULL) { LV_LOG_WARN("draw_core_cb is NULL"); @@ -141,8 +154,8 @@ void _lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_imag int32_t w = lv_area_get_width(coords); int32_t h = lv_area_get_height(coords); - _lv_image_buf_get_transformed_area(&draw_area, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, - &draw_dsc->pivot); + lv_image_buf_get_transformed_area(&draw_area, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, + &draw_dsc->pivot); draw_area.x1 += coords->x1; draw_area.y1 += coords->y1; @@ -151,7 +164,7 @@ void _lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_imag } lv_area_t clipped_img_area; - if(!_lv_area_intersect(&clipped_img_area, &draw_area, draw_unit->clip_area)) { + if(!lv_area_intersect(&clipped_img_area, &draw_area, draw_unit->clip_area)) { return; } @@ -167,8 +180,8 @@ void _lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_imag lv_image_decoder_close(&decoder_dsc); } -void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb) +void lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb) { if(draw_core_cb == NULL) { LV_LOG_WARN("draw_core_cb is NULL"); @@ -185,7 +198,13 @@ void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image int32_t img_w = draw_dsc->header.w; int32_t img_h = draw_dsc->header.h; - lv_area_t tile_area = *coords; + lv_area_t tile_area; + if(lv_area_get_width(&draw_dsc->image_area) >= 0) { + tile_area = draw_dsc->image_area; + } + else { + tile_area = *coords; + } lv_area_set_width(&tile_area, img_w); lv_area_set_height(&tile_area, img_h); @@ -198,11 +217,11 @@ void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image .y2 = LV_COORD_MIN, }; - while(tile_area.y1 <= draw_unit->clip_area->y2) { - while(tile_area.x1 <= draw_unit->clip_area->x2) { + while(tile_area.y1 <= coords->y2) { + while(tile_area.x1 <= coords->x2) { lv_area_t clipped_img_area; - if(_lv_area_intersect(&clipped_img_area, &tile_area, draw_unit->clip_area)) { + if(lv_area_intersect(&clipped_img_area, &tile_area, coords)) { img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, &relative_decoded_area, &tile_area, &clipped_img_area, draw_core_cb); } @@ -220,8 +239,8 @@ void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image lv_image_decoder_close(&decoder_dsc); } -void _lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle, - uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot) +void lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle, + uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot) { if(angle == 0 && scale_x == LV_SCALE_NONE && scale_y == LV_SCALE_NONE) { res->x1 = 0; @@ -285,7 +304,7 @@ static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_ if(res == LV_RESULT_OK) { /*Limit draw area to the current decoded area and draw the image*/ lv_area_t clipped_img_area_sub; - if(_lv_area_intersect(&clipped_img_area_sub, clipped_img_area, &absolute_decoded_area)) { + if(lv_area_intersect(&clipped_img_area_sub, clipped_img_area, &absolute_decoded_area)) { draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup, &absolute_decoded_area, &clipped_img_area_sub); } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.h index a6a9be568..a16f6d055 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.h @@ -1,5 +1,5 @@ /** - * @file lv_draw_img.h + * @file lv_draw_image.h * */ @@ -26,17 +26,7 @@ extern "C" { * MACROS **********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_color_t alpha_color; - const lv_color32_t * palette; - uint32_t palette_size : 9; -} lv_draw_image_sup_t; - -typedef struct _lv_draw_image_dsc_t { +typedef struct lv_draw_image_dsc_t { lv_draw_dsc_base_t base; const void * src; @@ -59,9 +49,15 @@ typedef struct _lv_draw_image_dsc_t { uint16_t tile : 1; lv_draw_image_sup_t * sup; - /** Might be used to indicate the original size of the image if only a small portion is rendered now. - * Used when a part of a layer is rendered to show the total layer size*/ - lv_area_t original_area; + /** Used to indicate the entire original, non-clipped area where the image is to be drawn. + * This is important for: + * 1. Layer rendering, where it might happen that only a smaller area of the layer is rendered. + * 2. Tiled images, where the target draw area is larger than the image to be tiled. + */ + lv_area_t image_area; + + int32_t clip_radius; + const lv_image_dsc_t * bitmap_mask_src; } lv_draw_image_dsc_t; @@ -100,14 +96,19 @@ lv_draw_image_dsc_t * lv_draw_task_get_image_dsc(lv_draw_task_t * task); * @param layer pointer to a layer * @param dsc pointer to an initialized draw descriptor * @param coords the coordinates of the image + * @note `coords` can be small than the real image area + * (if only a part of the image is rendered) + * or can be larger (in case of tiled images). . */ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); /** - * Create a draw task to blend a layer to an other layer + * Create a draw task to blend a layer to another layer * @param layer pointer to a layer * @param dsc pointer to an initialized draw descriptor - * @param coords the coordinates of the layer + * @param coords the coordinates of the layer. + * @note `coords` can be small than the total widget area from which the layer is created + * (if only a part of the widget was rendered to a layer) */ void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); @@ -121,41 +122,6 @@ void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv */ lv_image_src_t lv_image_src_get_type(const void * src); -/** - * Can be used by draw units to handle the decoding and - * prepare everything for the actual image rendering - * @param draw_unit pointer to a draw unit - * @param draw_dsc the draw descriptor of the image - * @param coords the absolute coordinates of the image - * @param draw_core_cb a callback to perform the actual rendering - */ -void _lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); - -/** - * Can be used by draw units for TILED images to handle the decoding and - * prepare everything for the actual image rendering - * @param draw_unit pointer to a draw unit - * @param draw_dsc the draw descriptor of the image - * @param coords the absolute coordinates of the image - * @param draw_core_cb a callback to perform the actual rendering - */ -void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); - -/** - * Get the area of a rectangle if its rotated and scaled - * @param res store the coordinates here - * @param w width of the rectangle to transform - * @param h height of the rectangle to transform - * @param angle angle of rotation - * @param scale_x zoom in x direction, (256 no zoom) - * @param scale_y zoom in y direction, (256 no zoom) - * @param pivot x,y pivot coordinates of rotation - */ -void _lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle, - uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot); - #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image_private.h new file mode 100644 index 000000000..a39ee6164 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image_private.h @@ -0,0 +1,85 @@ +/** + * @file lv_draw_image_private.h + * + */ + +#ifndef LV_DRAW_IMAGE_PRIVATE_H +#define LV_DRAW_IMAGE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_image.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_draw_image_sup_t { + lv_color_t alpha_color; + const lv_color32_t * palette; + uint32_t palette_size : 9; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Can be used by draw units to handle the decoding and + * prepare everything for the actual image rendering + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor of the image + * @param coords the absolute coordinates of the image + * @param draw_core_cb a callback to perform the actual rendering + */ +void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); + +/** + * Can be used by draw units for TILED images to handle the decoding and + * prepare everything for the actual image rendering + * @param draw_unit pointer to a draw unit + * @param draw_dsc the draw descriptor of the image + * @param coords the absolute coordinates of the image + * @param draw_core_cb a callback to perform the actual rendering + */ +void lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); + +/** + * Get the area of a rectangle if its rotated and scaled + * @param res store the coordinates here + * @param w width of the rectangle to transform + * @param h height of the rectangle to transform + * @param angle angle of rotation + * @param scale_x zoom in x direction, (256 no zoom) + * @param scale_y zoom in y direction, (256 no zoom) + * @param pivot x,y pivot coordinates of rotation + */ +void lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle, + uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_IMAGE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.c index 515fbc446..e733c40d2 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.c @@ -6,14 +6,20 @@ /********************* * INCLUDES *********************/ +#include "lv_draw_label_private.h" +#include "lv_draw_private.h" +#include "../misc/lv_area_private.h" +#include "lv_draw_vector_private.h" +#include "lv_draw_rect_private.h" #include "../core/lv_obj.h" -#include "lv_draw_label.h" #include "../misc/lv_math.h" #include "../core/lv_obj_event.h" -#include "../misc/lv_bidi.h" +#include "../misc/lv_bidi_private.h" +#include "../misc/lv_text_private.h" #include "../misc/lv_assert.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" +#include "../core/lv_global.h" /********************* * DEFINES @@ -21,6 +27,8 @@ #define LABEL_RECOLOR_PAR_LENGTH 6 #define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the "hint" if the label's y coordinates have changed more then this*/ +#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -107,7 +115,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_d return; } - if(_lv_text_is_marker(unicode_letter)) return; + if(lv_text_is_marker(unicode_letter)) return; LV_PROFILER_BEGIN; @@ -122,7 +130,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_d /*lv_draw_label needs UTF8 text so convert the Unicode character to an UTF8 string */ uint32_t letter_buf[2]; - letter_buf[0] = _lv_text_unicode_to_encoded(unicode_letter); + letter_buf[0] = lv_text_unicode_to_encoded(unicode_letter); letter_buf[1] = '\0'; const char * letter_buf_char = (const char *)letter_buf; @@ -146,7 +154,7 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ int32_t w; lv_area_t clipped_area; - bool clip_ok = _lv_area_intersect(&clipped_area, coords, draw_unit->clip_area); + bool clip_ok = lv_area_intersect(&clipped_area, coords, draw_unit->clip_area); if(!clip_ok) return; lv_text_align_t align = dsc->align; @@ -198,14 +206,14 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ pos.y += dsc->hint->y; } - uint32_t line_end = line_start + _lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, - dsc->flag); + uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, + dsc->flag); /*Go the first visible line*/ while(pos.y + line_height_font < draw_unit->clip_area->y1) { /*Go to next line*/ line_start = line_end; - line_end += _lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag); + line_end += lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag); pos.y += line_height; /*Save at the threshold coordinate*/ @@ -264,7 +272,7 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ #if LV_USE_BIDI char * bidi_txt = lv_malloc(line_end - line_start + 1); LV_ASSERT_MALLOC(bidi_txt); - _lv_bidi_process_paragraph(dsc->text + line_start, bidi_txt, line_end - line_start, base_dir, NULL, 0); + lv_bidi_process_paragraph(dsc->text + line_start, bidi_txt, line_end - line_start, base_dir, NULL, 0); #else const char * bidi_txt = dsc->text + line_start; #endif @@ -273,17 +281,17 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ uint32_t logical_char_pos = 0; if(sel_start != 0xFFFF && sel_end != 0xFFFF) { #if LV_USE_BIDI - logical_char_pos = _lv_text_encoded_get_char_id(dsc->text, line_start); - uint32_t t = _lv_text_encoded_get_char_id(bidi_txt, i); - logical_char_pos += _lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, base_dir, t, NULL); + logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start); + uint32_t t = lv_text_encoded_get_char_id(bidi_txt, i); + logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, base_dir, t, NULL); #else - logical_char_pos = _lv_text_encoded_get_char_id(dsc->text, line_start + i); + logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start + i); #endif } uint32_t letter; uint32_t letter_next; - _lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); + lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); letter_w = lv_font_get_glyph_width(font, letter, letter_next); @@ -338,7 +346,7 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ #endif /*Go to next line*/ line_start = line_end; - line_end += _lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag); + line_end += lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag); pos.x = coords->x1; /*Align to middle*/ @@ -375,7 +383,7 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, { lv_font_glyph_dsc_t g; - if(_lv_text_is_marker(letter)) /*Markers are valid letters but should not be rendered.*/ + if(lv_text_is_marker(letter)) /*Markers are valid letters but should not be rendered.*/ return; LV_PROFILER_BEGIN; @@ -398,8 +406,8 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, letter_coords.y2 = letter_coords.y1 + g.box_h - 1; /*If the letter is completely out of mask don't draw it*/ - if(_lv_area_is_out(&letter_coords, draw_unit->clip_area, 0) && - _lv_area_is_out(dsc->bg_coords, draw_unit->clip_area, 0)) { + if(lv_area_is_out(&letter_coords, draw_unit->clip_area, 0) && + lv_area_is_out(dsc->bg_coords, draw_unit->clip_area, 0)) { LV_PROFILER_END; return; } @@ -414,14 +422,14 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, uint32_t h = g.box_h; if(h * g.box_w < 64) h *= 2; /*Alloc a slightly larger buffer*/ - draw_buf = lv_draw_buf_create(g.box_w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO); + draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, g.box_w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO); LV_ASSERT_MALLOC(draw_buf); draw_buf->header.h = g.box_h; dsc->_draw_buf = draw_buf; } } - dsc->glyph_data = (void *)lv_font_get_glyph_bitmap(&g, letter, draw_buf); + dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(&g, draw_buf); dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE; } else { @@ -432,8 +440,7 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, dsc->g = &g; cb(draw_unit, dsc, NULL, NULL); - if(g.resolved_font && font->release_glyph) { - font->release_glyph(font, &g); - } + lv_font_glyph_release_draw_data(&g); + LV_PROFILER_END; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.h index f0b962802..67afaf5c7 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.h @@ -14,6 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "lv_draw.h" +#include "lv_draw_rect.h" #include "../misc/lv_bidi.h" #include "../misc/lv_text.h" #include "../misc/lv_color.h" @@ -28,23 +29,6 @@ extern "C" { * TYPEDEFS **********************/ -/** Store some info to speed up drawing of very large texts - * It takes a lot of time to get the first visible character because - * all the previous characters needs to be checked to calculate the positions. - * This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line. - * Therefore the calculations can start from here.*/ -typedef struct _lv_draw_label_hint_t { - /** Index of the line at `y` coordinate*/ - int32_t line_start; - - /** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/ - int32_t y; - - /** The 'y1' coordinate of the label when the hint was saved. - * Used to invalidate the hint if the label has moved too much.*/ - int32_t coord_y; -} lv_draw_label_hint_t; - typedef struct { lv_draw_dsc_base_t base; @@ -72,17 +56,6 @@ typedef struct { lv_draw_label_hint_t * hint; } lv_draw_label_dsc_t; -typedef struct { - void * glyph_data; /*Depends on `format` field, it could be image source or draw buf of bitmap or vector data.*/ - lv_font_glyph_format_t format; - const lv_area_t * letter_coords; - const lv_area_t * bg_coords; - const lv_font_glyph_dsc_t * g; - lv_color_t color; - lv_opa_t opa; - lv_draw_buf_t * _draw_buf; /*a shared draw buf for get_bitmap, do not use it directly, use glyph_data instead*/ -} lv_draw_glyph_dsc_t; - /** * Passed as a parameter to `lv_draw_label_iterate_characters` to * draw the characters one by one diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label_private.h new file mode 100644 index 000000000..163651da5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_draw_label_private.h + * + */ + +#ifndef LV_DRAW_LABEL_PRIVATE_H +#define LV_DRAW_LABEL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_label.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Store some info to speed up drawing of very large texts + * It takes a lot of time to get the first visible character because + * all the previous characters needs to be checked to calculate the positions. + * This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line. + * Therefore the calculations can start from here.*/ +struct lv_draw_label_hint_t { + /** Index of the line at `y` coordinate*/ + int32_t line_start; + + /** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/ + int32_t y; + + /** The 'y1' coordinate of the label when the hint was saved. + * Used to invalidate the hint if the label has moved too much.*/ + int32_t coord_y; +}; + +struct lv_draw_glyph_dsc_t { + void * glyph_data; /**< Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */ + lv_font_glyph_format_t format; + const lv_area_t * letter_coords; + const lv_area_t * bg_coords; + const lv_font_glyph_dsc_t * g; + lv_color_t color; + lv_opa_t opa; + lv_draw_buf_t * _draw_buf; /**< a shared draw buf for get_bitmap, do not use it directly, use glyph_data instead */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_LABEL_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.c index f906699c1..00fc203b1 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.c @@ -6,9 +6,10 @@ /********************* * INCLUDES *********************/ -#include +#include "lv_draw_private.h" #include "../core/lv_refr.h" #include "../misc/lv_math.h" +#include "../misc/lv_types.h" #include "../stdlib/lv_string.h" /********************* @@ -41,6 +42,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc) dsc->width = 1; dsc->opa = LV_OPA_COVER; dsc->color = lv_color_black(); + dsc->base.dsc_size = sizeof(lv_draw_line_dsc_t); } lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task) @@ -50,6 +52,9 @@ lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task) void LV_ATTRIBUTE_FAST_MEM lv_draw_line(lv_layer_t * layer, const lv_draw_line_dsc_t * dsc) { + if(dsc->width == 0) return; + if(dsc->opa <= LV_OPA_MIN) return; + LV_PROFILER_BEGIN; lv_area_t a; a.x1 = (int32_t)LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.h index f070d0fe4..72430fa79 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.h @@ -38,7 +38,7 @@ typedef struct { lv_blend_mode_t blend_mode : 2; uint8_t round_start : 1; uint8_t round_end : 1; - uint8_t raw_end : 1; /*Do not bother with perpendicular line ending if it's not visible for any reason*/ + uint8_t raw_end : 1; /**< Do not bother with perpendicular line ending if it's not visible for any reason */ } lv_draw_line_dsc_t; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.c index ed1ff2b44..3ee6b62bc 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.c @@ -6,10 +6,11 @@ /********************* * INCLUDES *********************/ -#include -#include "lv_draw_mask.h" +#include "lv_draw_mask_private.h" +#include "lv_draw_private.h" #include "../core/lv_refr.h" #include "../misc/lv_math.h" +#include "../misc/lv_types.h" #include "../stdlib/lv_string.h" /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.h index 6357647e9..6dfed79b3 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.h @@ -1,10 +1,10 @@ /** - * @file lv_draw_mask_rect.h + * @file lv_draw_mask.h * */ -#ifndef LV_DRAW_MASK_RECT_H -#define LV_DRAW_MASK_RECT_H +#ifndef LV_DRAW_MASK_H +#define LV_DRAW_MASK_H #ifdef __cplusplus extern "C" { @@ -13,7 +13,6 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_draw.h" #include "../misc/lv_color.h" #include "../misc/lv_area.h" #include "../misc/lv_style.h" @@ -22,16 +21,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ -typedef struct { - lv_draw_dsc_base_t base; - - lv_area_t area; - int32_t radius; -} lv_draw_mask_rect_dsc_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -64,4 +53,4 @@ void lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_mask_rect_dsc_t * dsc); } /*extern "C"*/ #endif -#endif /*LV_DRAW_MASK_RECT_H*/ +#endif /*LV_DRAW_MASK_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask_private.h new file mode 100644 index 000000000..040df7ebe --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask_private.h @@ -0,0 +1,51 @@ +/** + * @file lv_draw_mask_private.h + * + */ + +#ifndef LV_DRAW_MASK_PRIVATE_H +#define LV_DRAW_MASK_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_mask.h" +#include "lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ +struct lv_draw_mask_rect_dsc_t { + lv_draw_dsc_base_t base; + + lv_area_t area; + int32_t radius; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_MASK_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h new file mode 100644 index 000000000..d8244f799 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h @@ -0,0 +1,196 @@ +/** + * @file lv_draw_private.h + * + */ + +/** + * Modified by NXP in 2024 + */ + +#ifndef LV_DRAW_PRIVATE_H +#define LV_DRAW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_draw_task_t { + lv_draw_task_t * next; + + lv_draw_task_type_t type; + + /** + * The area where to draw + */ + lv_area_t area; + + /** + * The real draw area. E.g. for shadow, outline, or transformed images it's different from `area` + */ + lv_area_t _real_area; + + /** The original area which is updated*/ + lv_area_t clip_area_original; + + /** + * The clip area of the layer is saved here when the draw task is created. + * As the clip area of the layer can be changed as new draw tasks are added its current value needs to be saved. + * Therefore during drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks. + */ + lv_area_t clip_area; + +#if LV_DRAW_TRANSFORM_USE_MATRIX + /** Transform matrix to be applied when rendering the layer */ + lv_matrix_t matrix; +#endif + + volatile int state; /** int instead of lv_draw_task_state_t to be sure its atomic */ + + void * draw_dsc; + + /** + * The ID of the draw_unit which should take this task + */ + uint8_t preferred_draw_unit_id; + + /** + * Set to which extent `preferred_draw_unit_id` is good at this task. + * 80: means 20% better (faster) than software rendering + * 100: the default value + * 110: means 10% worse (slower) than software rendering + */ + uint8_t preference_score; + +}; + +struct lv_draw_mask_t { + void * user_data; +}; + +struct lv_draw_unit_t { + lv_draw_unit_t * next; + + /** + * The target_layer on which drawing should happen + */ + lv_layer_t * target_layer; + + const lv_area_t * clip_area; + + /** + * Called to try to assign a draw task to itself. + * `lv_draw_get_next_available_task` can be used to get an independent draw task. + * A draw task should be assign only if the draw unit can draw it too + * @param draw_unit pointer to the draw unit + * @param layer pointer to a layer on which the draw task should be drawn + * @return >=0: The number of taken draw task: + * 0 means the task has not yet been completed. + * 1 means a new task has been accepted. + * -1: The draw unit wanted to work on a task but couldn't do that + * due to some errors (e.g. out of memory). + * It signals that LVGL should call the dispatcher later again + * to let draw unit try to start the rendering again. + */ + int32_t (*dispatch_cb)(lv_draw_unit_t * draw_unit, lv_layer_t * layer); + + /** + * + * @param draw_unit + * @param task + * @return + */ + int32_t (*evaluate_cb)(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); + + /** + * Called to signal the unit to complete all tasks in order to return their ready status. + * This callback can be implemented in case of asynchronous task processing. + * Below is an example to show the difference between synchronous and asynchronous: + * + * Synchronous: + * LVGL thread DRAW thread HW + * + * task1 --> submit --> Receive task1 + * wait_for_finish() + * <-- task1->state = READY <-- Complete task1 + * task2 --> submit --> Receive task2 + * wait_for_finish() + * task2->state = READY <-- Complete task2 + * task3 --> submit --> Receive task3 + * wait_for_finish() + * <-- task3->state = READY <-- Complete task3 + * task4 --> submit --> Receive task4 + * wait_for_finish() + * <-- task4->state = READY <-- Complete task4 + * NO MORE TASKS + * + * + * Asynchronous: + * LVGL thread DRAW thread HW + * is IDLE + * task1 --> queue task1 + * submit --> Receive task1 + * task2 --> queue task2 is BUSY (with task1) + * task3 --> queue task3 still BUSY (with task1) + * task4 --> queue task4 becomes IDLE + * <-- task1->state = READY <-- Complete task1 + * submit --> Receive task2, task3, task4 + * NO MORE TASKS + * wait_for_finish_cb() wait_for_finish() + * <-- Complete task2, task3, task4 + * <-- task2->state = READY <-- + * <-- task3->state = READY <-- + * <-- task4->state = READY <-- + * + * @param draw_unit + * @return + */ + int32_t (*wait_for_finish_cb)(lv_draw_unit_t * draw_unit); + + /** + * Called to delete draw unit. + * @param draw_unit + * @return + */ + int32_t (*delete_cb)(lv_draw_unit_t * draw_unit); +}; + +typedef struct { + lv_draw_unit_t * unit_head; + uint32_t unit_cnt; + uint32_t used_memory_for_layers_kb; +#if LV_USE_OS + lv_thread_sync_t sync; +#else + int dispatch_req; +#endif + lv_mutex_t circle_cache_mutex; + bool task_running; +} lv_draw_global_info_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.c index 574d78a73..ec2acc57a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.c @@ -6,8 +6,9 @@ /********************* * INCLUDES *********************/ +#include "lv_draw_rect_private.h" +#include "lv_draw_private.h" #include "../core/lv_obj.h" -#include "lv_draw_rect.h" #include "../misc/lv_assert.h" #include "../core/lv_obj_event.h" #include "../stdlib/lv_string.h" @@ -118,7 +119,10 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a if(dsc->bg_image_opa <= LV_OPA_MIN || dsc->bg_image_src == NULL) has_bg_img = false; else has_bg_img = true; - if(dsc->border_opa <= LV_OPA_MIN || dsc->border_width == 0 || dsc->border_post == true) has_border = false; + if(dsc->border_opa <= LV_OPA_MIN + || dsc->border_width == 0 + || dsc->border_post == true + || dsc->border_side == LV_BORDER_SIDE_NONE) has_border = false; else has_border = true; if(dsc->outline_opa <= LV_OPA_MIN || dsc->outline_width == 0) has_outline = false; @@ -225,6 +229,7 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a bg_image_dsc->recolor_opa = dsc->bg_image_recolor_opa; bg_image_dsc->tile = dsc->bg_image_tiled; bg_image_dsc->header = header; + bg_image_dsc->clip_radius = dsc->radius; t->type = LV_DRAW_TASK_TYPE_IMAGE; lv_draw_finalize_task_creation(layer, t); } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect_private.h new file mode 100644 index 000000000..ad75b5355 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_draw_rect_private.h + * + */ + +#ifndef LV_DRAW_RECT_PRIVATE_H +#define LV_DRAW_RECT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_rect.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_RECT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.c index ae18968b5..6bf1c7c21 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.c @@ -6,8 +6,10 @@ /********************* * INCLUDES *********************/ + +#include "lv_draw_triangle_private.h" +#include "lv_draw_private.h" #include "../core/lv_obj.h" -#include "lv_draw_triangle.h" #include "../misc/lv_math.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" @@ -46,6 +48,7 @@ void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * dsc) dsc->bg_grad.stops[1].frac = 0xFF; dsc->bg_grad.stops_count = 2; dsc->bg_opa = LV_OPA_COVER; + dsc->base.dsc_size = sizeof(lv_draw_triangle_dsc_t); LV_PROFILER_END; } @@ -56,6 +59,8 @@ lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task) void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * dsc) { + if(dsc->bg_opa <= LV_OPA_MIN) return; + LV_PROFILER_BEGIN; lv_area_t a; a.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.h index b825e5311..b1ad8e58b 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.h @@ -38,7 +38,7 @@ typedef struct { /** * Initialize a triangle draw descriptor - * @param dsc pointer to a draw descriptor + * @param draw_dsc pointer to a draw descriptor */ void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * draw_dsc); @@ -52,7 +52,7 @@ lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task); /** * Create a triangle draw task * @param layer pointer to a layer - * @param dsc pointer to an initialized `lv_draw_triangle_dsc_t` variable + * @param draw_dsc pointer to an initialized `lv_draw_triangle_dsc_t` object */ void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * draw_dsc); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle_private.h new file mode 100644 index 000000000..7fc8ed5a2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle_private.h @@ -0,0 +1,43 @@ +/** + * @file lv_draw_triangle_private.h + * + */ + +#ifndef LV_DRAW_TRIANGLE_PRIVATE_H +#define LV_DRAW_TRIANGLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_triangle.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_TRIANGLE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.c index 5b8d66e99..28a08f289 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.c @@ -4,15 +4,17 @@ */ /********************* -* INCLUDES + * INCLUDES *********************/ -#include "lv_draw_vector.h" +#include "lv_draw_vector_private.h" +#include "../misc/lv_area_private.h" +#include "lv_draw_private.h" #if LV_USE_VECTOR_GRAPHIC #include "../misc/lv_ll.h" +#include "../misc/lv_types.h" #include "../stdlib/lv_string.h" -#include #include #include @@ -23,10 +25,10 @@ #define RAD_TO_DEG 57.295779513082320876798154814105f #define MATH_RADIANS(deg) ((deg) * DEG_TO_RAD) -#define MATH_DEGRESS(rad) ((rad) * RAD_TO_DEG) +#define MATH_DEGREES(rad) ((rad) * RAD_TO_DEG) /********************* -* DEFINES + * DEFINES *********************/ #ifndef M_PI @@ -44,59 +46,21 @@ } while(0) /********************** -* TYPEDEFS + * TYPEDEFS **********************/ typedef struct { lv_vector_path_t * path; lv_vector_draw_dsc_t dsc; -} _lv_vector_draw_task; +} lv_vector_draw_task; /********************** -* STATIC PROTOTYPES + * STATIC PROTOTYPES **********************/ -static bool _is_identity_or_translation(const lv_matrix_t * matrix) -{ - return (matrix->m[0][0] == 1.0f && - matrix->m[0][1] == 0.0f && - matrix->m[1][0] == 0.0f && - matrix->m[1][1] == 1.0f && - matrix->m[2][0] == 0.0f && - matrix->m[2][1] == 0.0f && - matrix->m[2][2] == 1.0f); -} - -static void _multiply_matrix(lv_matrix_t * matrix, const lv_matrix_t * mul) -{ - /*TODO: use NEON to optimize this function on ARM architecture.*/ - lv_matrix_t tmp; - - for(int y = 0; y < 3; y++) { - for(int x = 0; x < 3; x++) { - tmp.m[y][x] = (matrix->m[y][0] * mul->m[0][x]) - + (matrix->m[y][1] * mul->m[1][x]) - + (matrix->m[y][2] * mul->m[2][x]); - } - } - - lv_memcpy(matrix, &tmp, sizeof(lv_matrix_t)); -} - static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src) { - dst->fill_dsc.style = src->fill_dsc.style; - dst->fill_dsc.color = src->fill_dsc.color; - dst->fill_dsc.opa = src->fill_dsc.opa; - dst->fill_dsc.fill_rule = src->fill_dsc.fill_rule; - dst->fill_dsc.gradient.style = src->fill_dsc.gradient.style; - dst->fill_dsc.gradient.cx = src->fill_dsc.gradient.cx; - dst->fill_dsc.gradient.cy = src->fill_dsc.gradient.cy; - dst->fill_dsc.gradient.cr = src->fill_dsc.gradient.cr; - dst->fill_dsc.gradient.spread = src->fill_dsc.gradient.spread; - lv_memcpy(&(dst->fill_dsc.gradient.grad), &(src->fill_dsc.gradient.grad), sizeof(lv_grad_dsc_t)); - lv_memcpy(&(dst->fill_dsc.img_dsc), &(src->fill_dsc.img_dsc), sizeof(lv_draw_image_dsc_t)); - lv_memcpy(&(dst->fill_dsc.matrix), &(src->fill_dsc.matrix), sizeof(lv_matrix_t)); + lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t)); dst->stroke_dsc.style = src->stroke_dsc.style; dst->stroke_dsc.color = src->stroke_dsc.color; @@ -111,7 +75,7 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_ dst->stroke_dsc.gradient.cy = src->stroke_dsc.gradient.cy; dst->stroke_dsc.gradient.cr = src->stroke_dsc.gradient.cr; dst->stroke_dsc.gradient.spread = src->fill_dsc.gradient.spread; - lv_memcpy(&(dst->stroke_dsc.gradient.grad), &(src->stroke_dsc.gradient.grad), sizeof(lv_grad_dsc_t)); + lv_memcpy(&(dst->stroke_dsc.gradient), &(src->stroke_dsc.gradient), sizeof(lv_vector_gradient_t)); lv_memcpy(&(dst->stroke_dsc.matrix), &(src->stroke_dsc.matrix), sizeof(lv_matrix_t)); dst->blend_mode = src->blend_mode; @@ -119,92 +83,9 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_ lv_area_copy(&(dst->scissor_area), &(src->scissor_area)); } /********************** -* GLOBAL FUNCTIONS + * GLOBAL FUNCTIONS **********************/ -/* matrix functions */ -void lv_matrix_identity(lv_matrix_t * matrix) -{ - matrix->m[0][0] = 1.0f; - matrix->m[0][1] = 0.0f; - matrix->m[0][2] = 0.0f; - matrix->m[1][0] = 0.0f; - matrix->m[1][1] = 1.0f; - matrix->m[1][2] = 0.0f; - matrix->m[2][0] = 0.0f; - matrix->m[2][1] = 0.0f; - matrix->m[2][2] = 1.0f; -} - -void lv_matrix_translate(lv_matrix_t * matrix, float dx, float dy) -{ - if(_is_identity_or_translation(matrix)) { - /*optimization for matrix translation.*/ - matrix->m[0][2] += dx; - matrix->m[1][2] += dy; - return; - } - - lv_matrix_t tlm = {{ - {1.0f, 0.0f, dx}, - {0.0f, 1.0f, dy}, - {0.0f, 0.0f, 1.0f}, - } - }; - - _multiply_matrix(matrix, &tlm); -} - -void lv_matrix_scale(lv_matrix_t * matrix, float scale_x, float scale_y) -{ - lv_matrix_t scm = {{ - {scale_x, 0.0f, 0.0f}, - {0.0f, scale_y, 0.0f}, - {0.0f, 0.0f, 1.0f}, - } - }; - - _multiply_matrix(matrix, &scm); -} - -void lv_matrix_rotate(lv_matrix_t * matrix, float degree) -{ - float radian = degree / 180.0f * (float)M_PI; - float cos_r = cosf(radian); - float sin_r = sinf(radian); - - lv_matrix_t rtm = {{ - {cos_r, -sin_r, 0.0f}, - {sin_r, cos_r, 0.0f}, - {0.0f, 0.0f, 1.0f}, - } - }; - - _multiply_matrix(matrix, &rtm); -} - -void lv_matrix_skew(lv_matrix_t * matrix, float skew_x, float skew_y) -{ - float rskew_x = skew_x / 180.0f * (float)M_PI; - float rskew_y = skew_y / 180.0f * (float)M_PI; - float tan_x = tanf(rskew_x); - float tan_y = tanf(rskew_y); - - lv_matrix_t skm = {{ - {1.0f, tan_x, 0.0f}, - {tan_y, 1.0f, 0.0f}, - {0.0f, 0.0f, 1.0f}, - } - }; - - _multiply_matrix(matrix, &skm); -} - -void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * m) -{ - _multiply_matrix(matrix, m); -} - void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point) { float x = point->x; @@ -230,7 +111,7 @@ lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality) LV_ASSERT_MALLOC(path); lv_memzero(path, sizeof(lv_vector_path_t)); path->quality = quality; - lv_array_init(&path->ops, 8, sizeof(uint8_t)); + lv_array_init(&path->ops, 8, sizeof(lv_vector_path_op_t)); lv_array_init(&path->points, 8, sizeof(lv_fpoint_t)); return path; } @@ -259,7 +140,7 @@ void lv_vector_path_move_to(lv_vector_path_t * path, const lv_fpoint_t * p) { CHECK_AND_RESIZE_PATH_CONTAINER(path, 1); - uint8_t op = LV_VECTOR_PATH_OP_MOVE_TO; + lv_vector_path_op_t op = LV_VECTOR_PATH_OP_MOVE_TO; lv_array_push_back(&path->ops, &op); lv_array_push_back(&path->points, p); } @@ -273,7 +154,7 @@ void lv_vector_path_line_to(lv_vector_path_t * path, const lv_fpoint_t * p) CHECK_AND_RESIZE_PATH_CONTAINER(path, 1); - uint8_t op = LV_VECTOR_PATH_OP_LINE_TO; + lv_vector_path_op_t op = LV_VECTOR_PATH_OP_LINE_TO; lv_array_push_back(&path->ops, &op); lv_array_push_back(&path->points, p); } @@ -287,7 +168,7 @@ void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, con CHECK_AND_RESIZE_PATH_CONTAINER(path, 2); - uint8_t op = LV_VECTOR_PATH_OP_QUAD_TO; + lv_vector_path_op_t op = LV_VECTOR_PATH_OP_QUAD_TO; lv_array_push_back(&path->ops, &op); lv_array_push_back(&path->points, p1); lv_array_push_back(&path->points, p2); @@ -303,7 +184,7 @@ void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, co CHECK_AND_RESIZE_PATH_CONTAINER(path, 3); - uint8_t op = LV_VECTOR_PATH_OP_CUBIC_TO; + lv_vector_path_op_t op = LV_VECTOR_PATH_OP_CUBIC_TO; lv_array_push_back(&path->ops, &op); lv_array_push_back(&path->points, p1); lv_array_push_back(&path->points, p2); @@ -319,7 +200,7 @@ void lv_vector_path_close(lv_vector_path_t * path) CHECK_AND_RESIZE_PATH_CONTAINER(path, 1); - uint8_t op = LV_VECTOR_PATH_OP_CLOSE; + lv_vector_path_op_t op = LV_VECTOR_PATH_OP_CLOSE; lv_array_push_back(&path->ops, &op); } @@ -621,7 +502,7 @@ void lv_vector_dsc_delete(lv_vector_dsc_t * dsc) { if(dsc->tasks.task_list) { lv_ll_t * task_list = dsc->tasks.task_list; - _lv_vector_for_each_destroy_tasks(task_list, NULL, NULL); + lv_vector_for_each_destroy_tasks(task_list, NULL, NULL); dsc->tasks.task_list = NULL; } lv_array_deinit(&(dsc->current_dsc.stroke_dsc.dash_pattern)); @@ -666,25 +547,40 @@ void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc lv_memcpy(&(dsc->current_dsc.fill_dsc.img_dsc), img_dsc, sizeof(lv_draw_image_dsc_t)); } -void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, - lv_vector_gradient_spread_t spread) +void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2) { dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; - dsc->current_dsc.fill_dsc.gradient.spread = spread; - lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); + dsc->current_dsc.fill_dsc.gradient.x1 = x1; + dsc->current_dsc.fill_dsc.gradient.y1 = y1; + dsc->current_dsc.fill_dsc.gradient.x2 = x2; + dsc->current_dsc.fill_dsc.gradient.y2 = y2; } -void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, - float radius, lv_vector_gradient_spread_t spread) +void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius) { dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; dsc->current_dsc.fill_dsc.gradient.cx = cx; dsc->current_dsc.fill_dsc.gradient.cy = cy; dsc->current_dsc.fill_dsc.gradient.cr = radius; +} + +void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread) +{ dsc->current_dsc.fill_dsc.gradient.spread = spread; - lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); +} + +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, + uint16_t count) +{ + if(count > LV_GRADIENT_MAX_STOPS) { + LV_LOG_WARN("Gradient stops limited: %d, max: %d", count, LV_GRADIENT_MAX_STOPS); + count = LV_GRADIENT_MAX_STOPS; + } + + lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count); + dsc->current_dsc.fill_dsc.gradient.stops_count = count; } void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) @@ -754,32 +650,47 @@ void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_ dsc->current_dsc.stroke_dsc.miter_limit = miter_limit; } -void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, - lv_vector_gradient_spread_t spread) +void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2) { dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; - dsc->current_dsc.stroke_dsc.gradient.spread = spread; - lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); + dsc->current_dsc.stroke_dsc.gradient.x1 = x1; + dsc->current_dsc.stroke_dsc.gradient.y1 = y1; + dsc->current_dsc.stroke_dsc.gradient.x2 = x2; + dsc->current_dsc.stroke_dsc.gradient.y2 = y2; } -void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, - float radius, lv_vector_gradient_spread_t spread) +void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius) { dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; dsc->current_dsc.stroke_dsc.gradient.cx = cx; dsc->current_dsc.stroke_dsc.gradient.cy = cy; dsc->current_dsc.stroke_dsc.gradient.cr = radius; +} + +void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread) +{ dsc->current_dsc.stroke_dsc.gradient.spread = spread; - lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); +} + +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, + uint16_t count) +{ + if(count > LV_GRADIENT_MAX_STOPS) { + LV_LOG_WARN("Gradient stops limited: %d, max: %d", count, LV_GRADIENT_MAX_STOPS); + count = LV_GRADIENT_MAX_STOPS; + } + + lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count); + dsc->current_dsc.stroke_dsc.gradient.stops_count = count; } /* draw functions */ void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path) { lv_area_t rect; - if(!_lv_area_intersect(&rect, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) { + if(!lv_area_intersect(&rect, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) { return; } @@ -791,11 +702,11 @@ void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path if(!dsc->tasks.task_list) { dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t)); LV_ASSERT_MALLOC(dsc->tasks.task_list); - _lv_ll_init(dsc->tasks.task_list, sizeof(_lv_vector_draw_task)); + lv_ll_init(dsc->tasks.task_list, sizeof(lv_vector_draw_task)); } - _lv_vector_draw_task * new_task = (_lv_vector_draw_task *)_lv_ll_ins_tail(dsc->tasks.task_list); - lv_memset(new_task, 0, sizeof(_lv_vector_draw_task)); + lv_vector_draw_task * new_task = (lv_vector_draw_task *)lv_ll_ins_tail(dsc->tasks.task_list); + lv_memset(new_task, 0, sizeof(lv_vector_draw_task)); new_task->path = lv_vector_path_create(0); @@ -807,18 +718,18 @@ void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect) { lv_area_t r; - if(!_lv_area_intersect(&r, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) { + if(!lv_area_intersect(&r, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) { return; } if(!dsc->tasks.task_list) { dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t)); LV_ASSERT_MALLOC(dsc->tasks.task_list); - _lv_ll_init(dsc->tasks.task_list, sizeof(_lv_vector_draw_task)); + lv_ll_init(dsc->tasks.task_list, sizeof(lv_vector_draw_task)); } - _lv_vector_draw_task * new_task = (_lv_vector_draw_task *)_lv_ll_ins_tail(dsc->tasks.task_list); - lv_memset(new_task, 0, sizeof(_lv_vector_draw_task)); + lv_vector_draw_task * new_task = (lv_vector_draw_task *)lv_ll_ins_tail(dsc->tasks.task_list); + lv_memset(new_task, 0, sizeof(lv_vector_draw_task)); new_task->dsc.fill_dsc.color = dsc->current_dsc.fill_dsc.color; new_task->dsc.fill_dsc.opa = dsc->current_dsc.fill_dsc.opa; @@ -867,14 +778,14 @@ void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y) lv_matrix_skew(&(dsc->current_dsc.matrix), skew_x, skew_y); } -void _lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data) +void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data) { - _lv_vector_draw_task * task = _lv_ll_get_head(task_list); - _lv_vector_draw_task * next_task = NULL; + lv_vector_draw_task * task = lv_ll_get_head(task_list); + lv_vector_draw_task * next_task = NULL; while(task != NULL) { - next_task = _lv_ll_get_next(task_list, task); - _lv_ll_remove(task_list, task); + next_task = lv_ll_get_next(task_list, task); + lv_ll_remove(task_list, task); if(cb) { cb(data, task->path, &(task->dsc)); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.h index 675359d3d..38ce78ae1 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.h @@ -13,42 +13,43 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_draw.h" #include "../misc/lv_array.h" +#include "../misc/lv_matrix.h" +#include "lv_draw_image.h" #if LV_USE_VECTOR_GRAPHIC +#if !LV_USE_MATRIX +#error "lv_draw_vector needs LV_USE_MATRIX = 1" +#endif + /********************** * TYPEDEFS **********************/ -enum { +typedef enum { LV_VECTOR_FILL_NONZERO = 0, LV_VECTOR_FILL_EVENODD, -}; -typedef uint8_t lv_vector_fill_t; +} lv_vector_fill_t; -enum { +typedef enum { LV_VECTOR_STROKE_CAP_BUTT = 0, LV_VECTOR_STROKE_CAP_SQUARE, LV_VECTOR_STROKE_CAP_ROUND, -}; -typedef uint8_t lv_vector_stroke_cap_t; +} lv_vector_stroke_cap_t; -enum { +typedef enum { LV_VECTOR_STROKE_JOIN_MITER = 0, LV_VECTOR_STROKE_JOIN_BEVEL, LV_VECTOR_STROKE_JOIN_ROUND, -}; -typedef uint8_t lv_vector_stroke_join_t; +} lv_vector_stroke_join_t; -enum { +typedef enum { LV_VECTOR_PATH_QUALITY_MEDIUM = 0, /* default*/ LV_VECTOR_PATH_QUALITY_HIGH, LV_VECTOR_PATH_QUALITY_LOW, -}; -typedef uint8_t lv_vector_path_quality_t; +} lv_vector_path_quality_t; -enum { +typedef enum { LV_VECTOR_BLEND_SRC_OVER = 0, LV_VECTOR_BLEND_SRC_IN, LV_VECTOR_BLEND_DST_OVER, @@ -58,153 +59,42 @@ enum { LV_VECTOR_BLEND_NONE, LV_VECTOR_BLEND_ADDITIVE, LV_VECTOR_BLEND_SUBTRACTIVE, -}; -typedef uint8_t lv_vector_blend_t; +} lv_vector_blend_t; -enum { +typedef enum { LV_VECTOR_PATH_OP_MOVE_TO = 0, LV_VECTOR_PATH_OP_LINE_TO, LV_VECTOR_PATH_OP_QUAD_TO, LV_VECTOR_PATH_OP_CUBIC_TO, LV_VECTOR_PATH_OP_CLOSE, -}; -typedef uint8_t lv_vector_path_op_t; +} lv_vector_path_op_t; -enum { +typedef enum { LV_VECTOR_DRAW_STYLE_SOLID = 0, LV_VECTOR_DRAW_STYLE_PATTERN, LV_VECTOR_DRAW_STYLE_GRADIENT, -}; -typedef uint8_t lv_vector_draw_style_t; +} lv_vector_draw_style_t; -enum { +typedef enum { LV_VECTOR_GRADIENT_SPREAD_PAD = 0, LV_VECTOR_GRADIENT_SPREAD_REPEAT, LV_VECTOR_GRADIENT_SPREAD_REFLECT, -}; -typedef uint8_t lv_vector_gradient_spread_t; +} lv_vector_gradient_spread_t; -enum { +typedef enum { LV_VECTOR_GRADIENT_STYLE_LINEAR = 0, LV_VECTOR_GRADIENT_STYLE_RADIAL, -}; -typedef uint8_t lv_vector_gradient_style_t; +} lv_vector_gradient_style_t; -typedef struct { +struct lv_fpoint_t { float x; float y; -} lv_fpoint_t; - -typedef struct { - float m[3][3]; -} lv_matrix_t; - -typedef struct { - lv_vector_path_quality_t quality; - lv_array_t ops; - lv_array_t points; -} lv_vector_path_t; - -typedef struct { - lv_vector_gradient_style_t style; - lv_grad_dsc_t grad; - float cx; - float cy; - float cr; - lv_vector_gradient_spread_t spread; -} lv_vector_gradient_t; - -typedef struct { - lv_vector_draw_style_t style; - lv_color32_t color; - lv_opa_t opa; - lv_vector_fill_t fill_rule; - lv_draw_image_dsc_t img_dsc; - lv_vector_gradient_t gradient; - lv_matrix_t matrix; -} lv_vector_fill_dsc_t; - -typedef struct { - lv_vector_draw_style_t style; - lv_color32_t color; - lv_opa_t opa; - float width; - lv_array_t dash_pattern; - lv_vector_stroke_cap_t cap; - lv_vector_stroke_join_t join; - uint16_t miter_limit; - lv_vector_gradient_t gradient; - lv_matrix_t matrix; -} lv_vector_stroke_dsc_t; - -typedef struct { - lv_vector_fill_dsc_t fill_dsc; - lv_vector_stroke_dsc_t stroke_dsc; - lv_matrix_t matrix; - lv_vector_blend_t blend_mode; - lv_area_t scissor_area; -} lv_vector_draw_dsc_t; - -typedef struct { - lv_draw_dsc_base_t base; - lv_ll_t * task_list; /*draw task list.*/ -} lv_draw_vector_task_dsc_t; - -typedef struct { - lv_layer_t * layer; - lv_vector_draw_dsc_t current_dsc; - /* private data */ - lv_draw_vector_task_dsc_t tasks; -} lv_vector_dsc_t; +}; /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Set matrix to identity matrix - * @param matrix pointer to a matrix - */ -void lv_matrix_identity(lv_matrix_t * matrix); - -/** - * Translate the matrix to new position - * @param matrix pointer to a matrix - * @param tx the amount of translate in x direction - * @param tx the amount of translate in y direction - */ -void lv_matrix_translate(lv_matrix_t * matrix, float tx, float ty); - -/** - * Change the scale factor of the matrix - * @param matrix pointer to a matrix - * @param scale_x the scale factor for the X direction - * @param scale_y the scale factor for the Y direction - */ -void lv_matrix_scale(lv_matrix_t * matrix, float scale_x, float scale_y); - -/** - * Rotate the matrix with origin - * @param matrix pointer to a matrix - * @param degree angle to rotate - */ -void lv_matrix_rotate(lv_matrix_t * matrix, float degree); - -/** - * Change the skew factor of the matrix - * @param matrix pointer to a matrix - * @param skew_x the skew factor for x direction - * @param skew_y the skew factor for y direction - */ -void lv_matrix_skew(lv_matrix_t * matrix, float skew_x, float skew_y); - -/** - * Multiply two matrix and store the result to the first one - * @param matrix pointer to a matrix - * @param matrix2 pointer to another matrix - */ -void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * matrix2); - /** * Transform the coordinates of a point using given matrix * @param matrix pointer to a matrix @@ -391,24 +281,39 @@ void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc /** * Set fill linear gradient for descriptor - * @param dsc pointer to a vector graphic descriptor - * @param grad pointer to a `lv_grad_dsc_t` variable - * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format + * @param dsc pointer to a vector graphic descriptor + * @param x1 the x for start point + * @param y1 the y for start point + * @param x2 the x for end point + * @param y2 the y for end point */ -void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, - lv_vector_gradient_spread_t spread); +void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); /** - * Set fill radial gradient for descriptor - * @param dsc pointer to a vector graphic descriptor - * @param grad pointer to a `lv_grad_dsc_t` variable - * @param cx the x for center of the circle - * @param cy the y for center of the circle - * @param radius the radius for circle - * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format + + * Set fill radial gradient radius for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param cx the x for center of the circle + * @param cy the y for center of the circle + * @param radius the radius for circle */ -void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, - float radius, lv_vector_gradient_spread_t spread); +void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius); + +/** + * Set fill radial gradient spread for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format + */ +void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); + +/** + * Set fill gradient color stops for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param stops an array of `lv_gradient_stop_t` variables + * @param count the number of stops in the array, range: 0..LV_GRADIENT_MAX_STOPS + */ +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, + uint16_t count); /** * Set a matrix to current fill transformation matrix @@ -477,22 +382,37 @@ void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_ /** * Set stroke linear gradient for descriptor * @param dsc pointer to a vector graphic descriptor - * @param grad pointer to a `lv_grad_dsc_t` variable - * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format + * @param x1 the x for start point + * @param y1 the y for start point + * @param x2 the x for end point + * @param y2 the y for end point */ -void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, - lv_vector_gradient_spread_t spread); +void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); /** * Set stroke radial gradient for descriptor * @param dsc pointer to a vector graphic descriptor - * @param grad pointer to a `lv_grad_dsc_t` variable * @param cx the x for center of the circle * @param cy the y for center of the circle * @param radius the radius for circle + */ +void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius); + +/** + * Set stroke color stops for descriptor + * @param dsc pointer to a vector graphic descriptor * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format */ -void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, - float radius, lv_vector_gradient_spread_t spread); +void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); + +/** + * Set stroke color stops for descriptor + * @param dsc pointer to a vector graphic descriptor + * @param stops an array of `lv_gradient_stop_t` variables + * @param count the number of stops in the array + */ +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, + uint16_t count); + /** * Set a matrix to current stroke transformation matrix * @param dsc pointer to a vector graphic descriptor @@ -560,8 +480,6 @@ void lv_draw_vector(lv_vector_dsc_t * dsc); /* Traverser for task list */ typedef void (*vector_draw_task_cb)(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc); -void _lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data); - #endif /* LV_USE_VECTOR_GRAPHIC */ #ifdef __cplusplus diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector_private.h new file mode 100644 index 000000000..5257a301e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector_private.h @@ -0,0 +1,109 @@ +/** + * @file lv_draw_vector_private.h + * + */ + +#ifndef LV_DRAW_VECTOR_PRIVATE_H +#define LV_DRAW_VECTOR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_vector.h" + +#if LV_USE_VECTOR_GRAPHIC + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_vector_path_t { + lv_vector_path_quality_t quality; + lv_array_t ops; + lv_array_t points; +}; + +struct lv_vector_gradient_t { + lv_vector_gradient_style_t style; + lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ + uint16_t stops_count; /**< The number of used stops in the array */ + float x1; + float y1; + float x2; + float y2; + float cx; + float cy; + float cr; + lv_vector_gradient_spread_t spread; +}; + +struct lv_vector_fill_dsc_t { + lv_vector_draw_style_t style; + lv_color32_t color; + lv_opa_t opa; + lv_vector_fill_t fill_rule; + lv_draw_image_dsc_t img_dsc; + lv_vector_gradient_t gradient; + lv_matrix_t matrix; +}; + +struct lv_vector_stroke_dsc_t { + lv_vector_draw_style_t style; + lv_color32_t color; + lv_opa_t opa; + float width; + lv_array_t dash_pattern; + lv_vector_stroke_cap_t cap; + lv_vector_stroke_join_t join; + uint16_t miter_limit; + lv_vector_gradient_t gradient; + lv_matrix_t matrix; +}; + +struct lv_vector_draw_dsc_t { + lv_vector_fill_dsc_t fill_dsc; + lv_vector_stroke_dsc_t stroke_dsc; + lv_matrix_t matrix; + lv_vector_blend_t blend_mode; + lv_area_t scissor_area; +}; + +struct lv_draw_vector_task_dsc_t { + lv_draw_dsc_base_t base; + lv_ll_t * task_list; /*draw task list.*/ +}; + +struct lv_vector_dsc_t { + lv_layer_t * layer; + lv_vector_draw_dsc_t current_dsc; + /* private data */ + lv_draw_vector_task_dsc_t tasks; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_VECTOR_GRAPHIC */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_VECTOR_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.c index c1d58558a..90934c105 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_image_decoder.h" +#include "lv_image_decoder_private.h" #include "../misc/lv_assert.h" #include "../draw/lv_draw_image.h" #include "../misc/lv_ll.h" @@ -19,6 +19,7 @@ #define img_decoder_ll_p &(LV_GLOBAL_DEFAULT()->img_decoder_ll) #define img_cache_p (LV_GLOBAL_DEFAULT()->img_cache) #define img_header_cache_p (LV_GLOBAL_DEFAULT()->img_header_cache) +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) /********************** * TYPEDEFS @@ -32,25 +33,14 @@ static uint32_t img_width_to_stride(lv_image_header_t * header); /** * Get the header info of an image source, and return the a pointer to the decoder that can open it. - * @param src The image source (e.g. a filename or a pointer to a C array) + * @param dsc Image descriptor containing the source and type of the image and other info. * @param header The header of the image * @return The decoder that can open the image source or NULL if not found (or can't open it). */ -static lv_image_decoder_t * image_decoder_get_info(const void * src, lv_image_header_t * header); - -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 -static lv_cache_compare_res_t image_decoder_header_cache_compare_cb(const lv_image_header_cache_data_t * lhs, - const lv_image_header_cache_data_t * rhs); -static void image_decoder_header_cache_free_cb(lv_image_header_cache_data_t * entry, void * user_data); -#endif - -#if LV_CACHE_DEF_SIZE > 0 -static lv_cache_compare_res_t image_decoder_cache_compare_cb(const lv_image_cache_data_t * lhs, - const lv_image_cache_data_t * rhs); -static void image_decoder_cache_free_cb(lv_image_cache_data_t * entry, void * user_data); +static lv_image_decoder_t * image_decoder_get_info(lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc); -#endif + /********************** * STATIC VARIABLES **********************/ @@ -66,48 +56,34 @@ static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc); /** * Initialize the image decoder module */ -void _lv_image_decoder_init(void) +void lv_image_decoder_init(uint32_t image_cache_size, uint32_t image_header_count) { - _lv_ll_init(img_decoder_ll_p, sizeof(lv_image_decoder_t)); + lv_ll_init(img_decoder_ll_p, sizeof(lv_image_decoder_t)); -#if LV_CACHE_DEF_SIZE > 0 - img_cache_p = lv_cache_create(&lv_cache_class_lru_rb_size, - sizeof(lv_image_cache_data_t), LV_CACHE_DEF_SIZE, (lv_cache_ops_t) { - .compare_cb = (lv_cache_compare_cb_t)image_decoder_cache_compare_cb, - .create_cb = NULL, - .free_cb = (lv_cache_free_cb_t)image_decoder_cache_free_cb, - }); - -#endif - -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 - img_header_cache_p = lv_cache_create(&lv_cache_class_lru_rb_count, - sizeof(lv_image_header_cache_data_t), LV_IMAGE_HEADER_CACHE_DEF_CNT, (lv_cache_ops_t) { - .compare_cb = (lv_cache_compare_cb_t)image_decoder_header_cache_compare_cb, - .create_cb = NULL, - .free_cb = (lv_cache_free_cb_t)image_decoder_header_cache_free_cb - }); -#endif + /*Initialize the cache*/ + lv_image_cache_init(image_cache_size); + lv_image_header_cache_init(image_header_count); } /** * Deinitialize the image decoder module */ -void _lv_image_decoder_deinit(void) +void lv_image_decoder_deinit(void) { -#if LV_CACHE_DEF_SIZE > 0 lv_cache_destroy(img_cache_p, NULL); -#endif - -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 lv_cache_destroy(img_header_cache_p, NULL); -#endif - _lv_ll_clear(img_decoder_ll_p); + + lv_ll_clear(img_decoder_ll_p); } lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * header) { - lv_image_decoder_t * decoder = image_decoder_get_info(src, header); + lv_image_decoder_dsc_t dsc; + lv_memzero(&dsc, sizeof(lv_image_decoder_dsc_t)); + dsc.src = src; + dsc.src_type = lv_image_src_get_type(src); + + lv_image_decoder_t * decoder = image_decoder_get_info(&dsc, header); if(decoder == NULL) return LV_RESULT_INVALID; return LV_RESULT_OK; @@ -121,19 +97,19 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src dsc->src = src; dsc->src_type = lv_image_src_get_type(src); -#if LV_CACHE_DEF_SIZE > 0 - dsc->cache = img_cache_p; - /*Try cache first, unless we are told to ignore cache.*/ - if(!(args && args->no_cache)) { - /* - * Check the cache first - * If the image is found in the cache, just return it.*/ - if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK; + if(lv_image_cache_is_enabled()) { + dsc->cache = img_cache_p; + /*Try cache first, unless we are told to ignore cache.*/ + if(!(args && args->no_cache)) { + /* + * Check the cache first + * If the image is found in the cache, just return it.*/ + if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK; + } } -#endif /*Find the decoder that can open the image source, and get the header info in the same time.*/ - dsc->decoder = image_decoder_get_info(src, &dsc->header); + dsc->decoder = image_decoder_get_info(dsc, &dsc->header); if(dsc->decoder == NULL) return LV_RESULT_INVALID; /*Make a copy of args*/ @@ -142,6 +118,7 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src .premultiply = false, .no_cache = false, .use_indexed = false, + .flush_cache = false, }; /* @@ -151,6 +128,18 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src * */ lv_result_t res = dsc->decoder->open_cb(dsc->decoder, dsc); + /* Flush the D-Cache if enabled and the image was successfully opened */ + if(dsc->args.flush_cache && res == LV_RESULT_OK && dsc->decoded != NULL) { + lv_draw_buf_flush_cache(dsc->decoded, NULL); + LV_LOG_INFO("Flushed D-cache: src %p (%s) (W%d x H%d, data: %p cf: %d)", + src, + dsc->src_type == LV_IMAGE_SRC_FILE ? (const char *)src : "c-array", + dsc->decoded->header.w, + dsc->decoded->header.h, + (void *)dsc->decoded->data, + dsc->decoded->header.cf); + } + return res; } @@ -167,6 +156,11 @@ void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc) { if(dsc->decoder) { if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc); + + if(lv_image_cache_is_enabled() && dsc->cache && dsc->cache_entry) { + /*Decoded data is in cache, release it from cache's callback*/ + lv_cache_release(dsc->cache, dsc->cache_entry, NULL); + } } } @@ -177,7 +171,7 @@ void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc) lv_image_decoder_t * lv_image_decoder_create(void) { lv_image_decoder_t * decoder; - decoder = _lv_ll_ins_head(img_decoder_ll_p); + decoder = lv_ll_ins_head(img_decoder_ll_p); LV_ASSERT_MALLOC(decoder); if(decoder == NULL) return NULL; @@ -188,16 +182,16 @@ lv_image_decoder_t * lv_image_decoder_create(void) void lv_image_decoder_delete(lv_image_decoder_t * decoder) { - _lv_ll_remove(img_decoder_ll_p, decoder); + lv_ll_remove(img_decoder_ll_p, decoder); lv_free(decoder); } lv_image_decoder_t * lv_image_decoder_get_next(lv_image_decoder_t * decoder) { if(decoder == NULL) - return _lv_ll_get_head(img_decoder_ll_p); + return lv_ll_get_head(img_decoder_ll_p); else - return _lv_ll_get_next(img_decoder_ll_p, decoder); + return lv_ll_get_next(img_decoder_ll_p, decoder); } void lv_image_decoder_set_info_cb(lv_image_decoder_t * decoder, lv_image_decoder_info_f_t info_cb) @@ -220,12 +214,6 @@ void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decode decoder->close_cb = close_cb; } -void lv_image_decoder_set_cache_free_cb(lv_image_decoder_t * decoder, lv_cache_free_cb_t cache_free_cb) -{ - decoder->cache_free_cb = cache_free_cb; -} - -#if LV_CACHE_DEF_SIZE > 0 lv_cache_entry_t * lv_image_decoder_add_to_cache(lv_image_decoder_t * decoder, lv_image_cache_data_t * search_key, const lv_draw_buf_t * decoded, void * user_data) @@ -248,7 +236,6 @@ lv_cache_entry_t * lv_image_decoder_add_to_cache(lv_image_decoder_t * decoder, return cache_entry; } -#endif lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_draw_buf_t * decoded) { @@ -261,7 +248,8 @@ lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_d LV_LOG_TRACE("Stride mismatch"); lv_result_t res = lv_draw_buf_adjust_stride(decoded, stride_expect); if(res != LV_RESULT_OK) { - lv_draw_buf_t * aligned = lv_draw_buf_create(decoded->header.w, decoded->header.h, decoded->header.cf, stride_expect); + lv_draw_buf_t * aligned = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, decoded->header.w, decoded->header.h, + decoded->header.cf, stride_expect); if(aligned == NULL) { LV_LOG_ERROR("No memory for Stride adjust."); return NULL; @@ -285,9 +273,9 @@ lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_d lv_draw_buf_premultiply(decoded); } else { - decoded = lv_draw_buf_dup(decoded); + decoded = lv_draw_buf_dup_ex(image_cache_draw_buf_handlers, decoded); if(decoded == NULL) { - LV_LOG_ERROR("No memory for premulitplying."); + LV_LOG_ERROR("No memory for premultiplying."); return NULL; } @@ -302,22 +290,25 @@ lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_d * STATIC FUNCTIONS **********************/ -static lv_image_decoder_t * image_decoder_get_info(const void * src, lv_image_header_t * header) +static lv_image_decoder_t * image_decoder_get_info(lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { lv_memzero(header, sizeof(lv_image_header_t)); - if(src == NULL) return NULL; + const void * src = dsc->src; + lv_image_src_t src_type = dsc->src_type; - lv_image_src_t src_type = lv_image_src_get_type(src); if(src_type == LV_IMAGE_SRC_VARIABLE) { const lv_image_dsc_t * img_dsc = src; if(img_dsc->data == NULL) return NULL; } - lv_image_decoder_t * decoder; + if(src_type == LV_IMAGE_SRC_FILE) LV_LOG_TRACE("Try to find decoder for %s", (const char *)src); + else LV_LOG_TRACE("Try to find decoder for %p", src); -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 - if(src_type == LV_IMAGE_SRC_FILE) { + lv_image_decoder_t * decoder; + bool is_header_cache_enabled = lv_image_header_cache_is_enabled(); + + if(is_header_cache_enabled && src_type == LV_IMAGE_SRC_FILE) { lv_image_header_cache_data_t search_key; search_key.src_type = src_type; search_key.src = src; @@ -329,15 +320,30 @@ static lv_image_decoder_t * image_decoder_get_info(const void * src, lv_image_he *header = cached_data->header; decoder = cached_data->decoder; lv_cache_release(img_header_cache_p, entry, NULL); + + LV_LOG_TRACE("Found decoder %s in header cache", decoder->name); return decoder; } } -#endif - _LV_LL_READ(img_decoder_ll_p, decoder) { + if(src_type == LV_IMAGE_SRC_FILE) { + lv_fs_res_t fs_res = lv_fs_open(&dsc->file, src, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_ERROR("File open failed: %" LV_PRIu32, (uint32_t)fs_res); + return NULL; + } + } + + /*Search the decoders*/ + lv_image_decoder_t * decoder_prev = NULL; + LV_LL_READ(img_decoder_ll_p, decoder) { /*Info and Open callbacks are required*/ if(decoder->info_cb && decoder->open_cb) { - lv_result_t res = decoder->info_cb(decoder, src, header); + lv_fs_seek(&dsc->file, 0, LV_FS_SEEK_SET); + lv_result_t res = decoder->info_cb(decoder, dsc, header); + + if(decoder_prev) LV_LOG_TRACE("Can't open image with decoder %s. Trying next decoder.", decoder_prev->name); + if(res == LV_RESULT_OK) { if(header->stride == 0) { LV_LOG_INFO("Image decoder didn't set stride. Calculate it from width."); @@ -345,11 +351,19 @@ static lv_image_decoder_t * image_decoder_get_info(const void * src, lv_image_he } break; } + + decoder_prev = decoder; } } -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 - if(src_type == LV_IMAGE_SRC_FILE && decoder) { + if(decoder == NULL) LV_LOG_TRACE("No decoder found"); + else LV_LOG_TRACE("Found decoder %s", decoder->name); + + if(src_type == LV_IMAGE_SRC_FILE) { + lv_fs_close(&dsc->file); + } + + if(is_header_cache_enabled && src_type == LV_IMAGE_SRC_FILE && decoder) { lv_cache_entry_t * entry; lv_image_header_cache_data_t search_key; search_key.src_type = src_type; @@ -365,7 +379,6 @@ static lv_image_decoder_t * image_decoder_get_info(const void * src, lv_image_he lv_cache_release(img_header_cache_p, entry, NULL); } -#endif return decoder; } @@ -380,73 +393,6 @@ static uint32_t img_width_to_stride(lv_image_header_t * header) } } -#if LV_CACHE_DEF_SIZE > 0 || LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 -inline static lv_cache_compare_res_t image_decoder_common_compare(const void * lhs_src, lv_image_src_t lhs_src_type, - const void * rhs_src, lv_image_src_t rhs_src_type) -{ - if(lhs_src_type == rhs_src_type) { - if(lhs_src_type == LV_IMAGE_SRC_FILE) { - int32_t cmp_res = lv_strcmp(lhs_src, rhs_src); - if(cmp_res != 0) { - return cmp_res > 0 ? 1 : -1; - } - } - else if(lhs_src_type == LV_IMAGE_SRC_VARIABLE) { - if(lhs_src != rhs_src) { - return lhs_src > rhs_src ? 1 : -1; - } - } - return 0; - } - return lhs_src_type > rhs_src_type ? 1 : -1; -} -#endif - -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 -static lv_cache_compare_res_t image_decoder_header_cache_compare_cb( - const lv_image_header_cache_data_t * lhs, - const lv_image_header_cache_data_t * rhs) -{ - return image_decoder_common_compare(lhs->src, lhs->src_type, rhs->src, rhs->src_type); -} - -static void image_decoder_header_cache_free_cb(lv_image_header_cache_data_t * entry, void * user_data) -{ - LV_UNUSED(user_data); /*Unused*/ - - if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src); -} -#endif - -#if LV_CACHE_DEF_SIZE > 0 -static lv_cache_compare_res_t image_decoder_cache_compare_cb( - const lv_image_cache_data_t * lhs, - const lv_image_cache_data_t * rhs) -{ - return image_decoder_common_compare(lhs->src, lhs->src_type, rhs->src, rhs->src_type); -} - -static void image_decoder_cache_free_cb(lv_image_cache_data_t * entry, void * user_data) -{ - const lv_image_decoder_t * decoder = entry->decoder; - if(decoder == NULL) return; /* Why ? */ - - if(decoder->cache_free_cb) { - /* Decoder wants to free the cache by itself. */ - decoder->cache_free_cb(entry, user_data); - } - else { - /* Destroy the decoded draw buffer if necessary. */ - lv_draw_buf_t * decoded = (lv_draw_buf_t *)entry->decoded; - if(lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_ALLOCATED)) { - lv_draw_buf_destroy(decoded); - } - - /*Free the duplicated file name*/ - if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src); - } -} - static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc) { lv_cache_t * cache = dsc->cache; @@ -467,4 +413,3 @@ static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc) return LV_RESULT_INVALID; } -#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.h index d446eacdf..e898edc9d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.h @@ -15,7 +15,6 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" -#include #include "lv_draw_buf.h" #include "../misc/lv_fs.h" #include "../misc/lv_types.h" @@ -32,66 +31,39 @@ extern "C" { /** * Source of image.*/ -enum _lv_image_src_t { +typedef enum { LV_IMAGE_SRC_VARIABLE, /** Binary/C variable*/ LV_IMAGE_SRC_FILE, /** File in filesystem*/ LV_IMAGE_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h)*/ LV_IMAGE_SRC_UNKNOWN, /** Unknown source*/ -}; - -#ifdef DOXYGEN -typedef _lv_image_src_t lv_image_src_t; -#else -typedef uint8_t lv_image_src_t; -#endif /*DOXYGEN*/ - -/*Decoder function definitions*/ -struct _lv_image_decoder_dsc_t; -typedef struct _lv_image_decoder_dsc_t lv_image_decoder_dsc_t; - -/** - * Image decoder args. - * It determines how to decoder an image, e.g. whether to premultiply the alpha or not. - * It should be passed to lv_img_decoder_open() function. If NULL is provided, default - * args are used. - * - * Default args: - * all field are zero or false. - */ -typedef struct _lv_image_decoder_args_t { - bool stride_align; /*Whether stride should be aligned*/ - bool premultiply; /*Whether image should be premultiplied or not after decoding*/ - bool no_cache; /*When set, decoded image won't be put to cache, and decoder open will also ignore cache.*/ - bool use_indexed; /*Decoded indexed image as is. Convert to ARGB8888 if false.*/ -} lv_image_decoder_args_t; +} lv_image_src_t; /** * Get info from an image and store in the `header` - * @param src the image source. Can be a pointer to a C array or a file name (Use - * `lv_image_src_get_type` to determine the type) - * @param header store the info here + * @param decoder pointer to decoder object + * @param dsc pointer to decoder descriptor + * @param header store the info here * @return LV_RESULT_OK: info written correctly; LV_RESULT_INVALID: failed */ -typedef lv_result_t (*lv_image_decoder_info_f_t)(lv_image_decoder_t * decoder, const void * src, +typedef lv_result_t (*lv_image_decoder_info_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); /** * Open an image for decoding. Prepare it as it is required to read it later - * @param decoder pointer to the decoder the function associated with - * @param dsc pointer to decoder descriptor. `src`, `color` are already initialized in it. + * @param decoder pointer to the decoder the function associated with + * @param dsc pointer to decoder descriptor. `src`, `color` are already initialized in it. */ typedef lv_result_t (*lv_image_decoder_open_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); /** - * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`. + * Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` values to `LV_COORD_MIN` on first call. * Required only if the "open" function can't return with the whole decoded pixel array. * @param decoder pointer to the decoder the function associated with * @param dsc pointer to decoder descriptor - * @param x start x coordinate - * @param y start y coordinate - * @param len number of pixels to decode - * @param buf a buffer to store the decoded pixels - * @return LV_RESULT_OK: ok; LV_RESULT_INVALID: failed + * @param full_area input parameter. the full area to decode after enough subsequent calls + * @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding. + * the decoded area is stored here after each call. + * @return LV_RESULT_OK: ok; LV_RESULT_INVALID: failed or there is nothing left to decode */ typedef lv_result_t (*lv_image_decoder_get_area_cb_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, @@ -104,90 +76,10 @@ typedef lv_result_t (*lv_image_decoder_get_area_cb_t)(lv_image_decoder_t * decod */ typedef void (*lv_image_decoder_close_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); -struct _lv_image_decoder_t { - lv_image_decoder_info_f_t info_cb; - lv_image_decoder_open_f_t open_cb; - lv_image_decoder_get_area_cb_t get_area_cb; - lv_image_decoder_close_f_t close_cb; - - lv_cache_free_cb_t cache_free_cb; - void * user_data; -}; - -typedef struct _lv_image_decoder_cache_data_t { - lv_cache_slot_size_t slot; - - const void * src; - lv_image_src_t src_type; - - const lv_draw_buf_t * decoded; - const lv_image_decoder_t * decoder; - void * user_data; -} lv_image_cache_data_t; - -typedef struct _lv_image_decoder_header_cache_data_t { - const void * src; - lv_image_src_t src_type; - - lv_image_header_t header; - lv_image_decoder_t * decoder; -} lv_image_header_cache_data_t; - -/**Describe an image decoding session. Stores data about the decoding*/ -struct _lv_image_decoder_dsc_t { - /**The decoder which was able to open the image source*/ - lv_image_decoder_t * decoder; - - /*A copy of parameters of how this image is decoded*/ - lv_image_decoder_args_t args; - - /**The image source. A file path like "S:my_img.png" or pointer to an `lv_image_dsc_t` variable*/ - const void * src; - - /**Type of the source: file or variable. Can be set in `open` function if required*/ - lv_image_src_t src_type; - - /**Info about the opened image: color format, size, etc. MUST be set in `open` function*/ - lv_image_header_t header; - - /** Pointer to a draw buffer where the image's data (pixels) are stored in a decoded, plain format. - * MUST be set in `open` or `get_area_cb`function*/ - const lv_draw_buf_t * decoded; /*A draw buffer to described decoded image.*/ - - const lv_color32_t * palette; - uint32_t palette_size; - - /** How much time did it take to open the image. [ms] - * If not set `lv_image_cache` will measure and set the time to open*/ - uint32_t time_to_open; - - /**A text to display instead of the image when the image can't be opened. - * Can be set in `open` function or set NULL.*/ - const char * error_msg; - - lv_cache_t * cache; - - /**Point to cache entry information*/ - lv_cache_entry_t * cache_entry; - - /**Store any custom data here is required*/ - void * user_data; -}; - /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Initialize the image decoder module - */ -void _lv_image_decoder_init(void); - -/** - * Deinitialize the image decoder module - */ -void _lv_image_decoder_deinit(void); - /** * Get information about an image. * Try the created image decoder one by one. Once one is able to get info that info will be used. @@ -203,24 +95,24 @@ lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * head /** * Open an image. * Try the created image decoders one by one. Once one is able to open the image that decoder is saved in `dsc` - * @param dsc describes a decoding session. Simply a pointer to an `lv_image_decoder_dsc_t` variable. - * @param src the image source. Can be - * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register())`) - * 2) Variable: Pointer to an `lv_image_dsc_t` variable - * 3) Symbol: E.g. `LV_SYMBOL_OK` - * @param color The color of the image with `LV_COLOR_FORMAT_ALPHA_...` - * @param args args about how the image should be opened. + * @param dsc describes a decoding session. Simply a pointer to an `lv_image_decoder_dsc_t` variable. + * @param src the image source. Can be + * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register())`) + * 2) Variable: Pointer to an `lv_image_dsc_t` variable + * 3) Symbol: E.g. `LV_SYMBOL_OK` + * @param args args about how the image should be opened. * @return LV_RESULT_OK: opened the image. `dsc->decoded` and `dsc->header` are set. * LV_RESULT_INVALID: none of the registered image decoders were able to open the image. */ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args); /** - * Decode an area of the opened image + * Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` to `LV_COORD_MIN` on first call. * @param dsc image decoder descriptor - * @param full_area start X coordinate (from left) - * @param decoded_area start Y coordinate (from top) - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: an error occurred + * @param full_area input parameter. the full area to decode after enough subsequent calls + * @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding. + * the decoded area is stored here after each call. + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: an error occurred or there is nothing left to decode */ lv_result_t lv_image_decoder_get_area(lv_image_decoder_dsc_t * dsc, const lv_area_t * full_area, lv_area_t * decoded_area); @@ -278,22 +170,9 @@ void lv_image_decoder_set_get_area_cb(lv_image_decoder_t * decoder, lv_image_dec */ void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb); -/** - * Set a custom method to free cache data. - * Normally this is not needed. If the custom decoder allocates additional memory other than dsc->decoded - * draw buffer, then you need to register your own method to free it. By default the cache entry is free'ed - * in `image_decoder_cache_free_cb`. - * - * @param decoder pointer to the image decoder - * @param cache_free_cb the custom callback to free cache data. Refer to `image_decoder_cache_free_cb`. - */ -void lv_image_decoder_set_cache_free_cb(lv_image_decoder_t * decoder, lv_cache_free_cb_t cache_free_cb); - -#if LV_CACHE_DEF_SIZE > 0 lv_cache_entry_t * lv_image_decoder_add_to_cache(lv_image_decoder_t * decoder, lv_image_cache_data_t * search_key, const lv_draw_buf_t * decoded, void * user_data); -#endif /** * Check the decoded image, make any modification if decoder `args` requires. diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder_private.h new file mode 100644 index 000000000..27ef26140 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder_private.h @@ -0,0 +1,142 @@ +/** + * @file lv_image_decoder_private.h + * + */ + +#ifndef LV_IMAGE_DECODER_PRIVATE_H +#define LV_IMAGE_DECODER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_image_decoder.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Image decoder args. + * It determines how to decoder an image, e.g. whether to premultiply the alpha or not. + * It should be passed to lv_img_decoder_open() function. If NULL is provided, default + * args are used. + * + * Default args: + * all field are zero or false. + */ +struct lv_image_decoder_args_t { + bool stride_align; /**< Whether stride should be aligned */ + bool premultiply; /**< Whether image should be premultiplied or not after decoding */ + bool no_cache; /**< When set, decoded image won't be put to cache, and decoder open will also ignore cache. */ + bool use_indexed; /**< Decoded indexed image as is. Convert to ARGB8888 if false. */ + bool flush_cache; /**< Whether to flush the data cache after decoding */ +}; + +struct lv_image_decoder_t { + lv_image_decoder_info_f_t info_cb; + lv_image_decoder_open_f_t open_cb; + lv_image_decoder_get_area_cb_t get_area_cb; + lv_image_decoder_close_f_t close_cb; + + const char * name; + + void * user_data; +}; + +struct lv_image_cache_data_t { + lv_cache_slot_size_t slot; + + const void * src; + lv_image_src_t src_type; + + const lv_draw_buf_t * decoded; + const lv_image_decoder_t * decoder; + void * user_data; +}; + +struct lv_image_header_cache_data_t { + const void * src; + lv_image_src_t src_type; + + lv_image_header_t header; + lv_image_decoder_t * decoder; +}; + +/**Describe an image decoding session. Stores data about the decoding*/ +struct lv_image_decoder_dsc_t { + /**The decoder which was able to open the image source*/ + lv_image_decoder_t * decoder; + + /**A copy of parameters of how this image is decoded*/ + lv_image_decoder_args_t args; + + /**The image source. A file path like "S:my_img.png" or pointer to an `lv_image_dsc_t` variable*/ + const void * src; + + /**Type of the source: file or variable. Can be set in `open` function if required*/ + lv_image_src_t src_type; + + lv_fs_file_t file; + + /**Info about the opened image: color format, size, etc. MUST be set in `open` function*/ + lv_image_header_t header; + + /** Pointer to a draw buffer where the image's data (pixels) are stored in a decoded, plain format. + * MUST be set in `open` or `get_area_cb`function*/ + const lv_draw_buf_t * decoded; + + const lv_color32_t * palette; + uint32_t palette_size; + + /** How much time did it take to open the image. [ms] + * If not set `lv_image_cache` will measure and set the time to open*/ + uint32_t time_to_open; + + /**A text to display instead of the image when the image can't be opened. + * Can be set in `open` function or set NULL.*/ + const char * error_msg; + + lv_cache_t * cache; + + /**Point to cache entry information*/ + lv_cache_entry_t * cache_entry; + + /**Store any custom data here is required*/ + void * user_data; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the image decoder module + * @param image_cache_size Image cache size in bytes. 0 to disable cache. + * @param image_header_count Number of header cache entries. 0 to disable header cache. + */ +void lv_image_decoder_init(uint32_t image_cache_size, uint32_t image_header_count); + +/** + * Deinitialize the image decoder module + */ +void lv_image_decoder_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_DECODER_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_dsc.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_dsc.h index 68c123ea3..ecd50882e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_dsc.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_dsc.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_IMAGE_BUF_H -#define LV_IMAGE_BUF_H +#ifndef LV_IMAGE_DSC_H +#define LV_IMAGE_DSC_H #ifdef __cplusplus extern "C" { @@ -20,7 +20,7 @@ extern "C" { *********************/ /** Magic number for lvgl image, 9 means lvgl version 9 - * It must not be a valid ASCII character nor larger than 0x80. See `lv_image_src_get_type`. + * It must be neither a valid ASCII character nor larger than 0x80. See `lv_image_src_get_type`. */ #define LV_IMAGE_HEADER_MAGIC (0x19) LV_EXPORT_CONST_INT(LV_IMAGE_HEADER_MAGIC); @@ -29,7 +29,7 @@ LV_EXPORT_CONST_INT(LV_IMAGE_HEADER_MAGIC); * TYPEDEFS **********************/ -typedef enum _lv_image_flags_t { +typedef enum lv_image_flags_t { /** * For RGB map of the image data, mark if it's pre-multiplied with alpha. * For indexed image, this bit indicated palette data is pre-multiplied with alpha. @@ -70,49 +70,49 @@ typedef enum _lv_image_flags_t { typedef enum { LV_IMAGE_COMPRESS_NONE = 0, - LV_IMAGE_COMPRESS_RLE, /*LVGL custom RLE compression*/ + LV_IMAGE_COMPRESS_RLE, /**< LVGL custom RLE compression */ LV_IMAGE_COMPRESS_LZ4, } lv_image_compress_t; #if LV_BIG_ENDIAN_SYSTEM typedef struct { - uint32_t reserved_2: 16; /*Reserved to be used later*/ - uint32_t stride: 16; /*Number of bytes in a row*/ + uint32_t reserved_2: 16; /**< Reserved to be used later*/ + uint32_t stride: 16; /**< Number of bytes in a row*/ uint32_t h: 16; uint32_t w: 16; - uint32_t flags: 16; /*Image flags, see `lv_image_flags_t`*/ - uint32_t cf : 8; /*Color format: See `lv_color_format_t`*/ - uint32_t magic: 8; /*Magic number. Must be LV_IMAGE_HEADER_MAGIC*/ + uint32_t flags: 16; /**< Image flags, see `lv_image_flags_t`*/ + uint32_t cf : 8; /**< Color format: See `lv_color_format_t`*/ + uint32_t magic: 8; /**< Magic number. Must be LV_IMAGE_HEADER_MAGIC*/ } lv_image_header_t; #else typedef struct { - uint32_t magic: 8; /*Magic number. Must be LV_IMAGE_HEADER_MAGIC*/ - uint32_t cf : 8; /*Color format: See `lv_color_format_t`*/ - uint32_t flags: 16; /*Image flags, see `lv_image_flags_t`*/ + uint32_t magic: 8; /**< Magic number. Must be LV_IMAGE_HEADER_MAGIC*/ + uint32_t cf : 8; /**< Color format: See `lv_color_format_t`*/ + uint32_t flags: 16; /**< Image flags, see `lv_image_flags_t`*/ uint32_t w: 16; uint32_t h: 16; - uint32_t stride: 16; /*Number of bytes in a row*/ - uint32_t reserved_2: 16; /*Reserved to be used later*/ + uint32_t stride: 16; /**< Number of bytes in a row*/ + uint32_t reserved_2: 16; /**< Reserved to be used later*/ } lv_image_header_t; #endif typedef struct { void * buf; - uint32_t stride; /*Number of bytes in a row*/ + uint32_t stride; /**< Number of bytes in a row*/ } lv_yuv_plane_t; typedef union { - lv_yuv_plane_t yuv; /*packed format*/ + lv_yuv_plane_t yuv; /**< packed format*/ struct { lv_yuv_plane_t y; lv_yuv_plane_t u; lv_yuv_plane_t v; - } planar; /*planar format with 3 plane*/ + } planar; /**< planar format with 3 plane*/ struct { lv_yuv_plane_t y; lv_yuv_plane_t uv; - } semi_planar; /*planar format with 2 plane*/ + } semi_planar; /**< planar format with 2 plane*/ } lv_yuv_buf_t; /** @@ -138,4 +138,4 @@ typedef struct { } /*extern "C"*/ #endif -#endif /*LV_IMAGE_BUF_H*/ +#endif /*LV_IMAGE_DSC_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c index 12b37de95..e83da1ca3 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_buf_pxp.c @@ -16,6 +16,7 @@ #include "lv_draw_pxp.h" #if LV_USE_DRAW_PXP +#include "../../lv_draw_buf_private.h" #include "lv_pxp_cfg.h" #include "lv_pxp_utils.h" @@ -68,7 +69,7 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * uint16_t size = stride * lv_area_get_height(area); /* Invalidate full buffer. */ - DCACHE_CleanInvalidateByRange((uint32_t)draw_buf->data, size); + DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); return; } @@ -103,7 +104,7 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * for(uint16_t y = 0; y < area_height; y++) { const void * line_addr = buf_u8 + y * stride; - DCACHE_CleanInvalidateByRange((uint32_t)line_addr, line_size); + DEMO_CleanInvalidateCacheByAddr((void *)line_addr, line_size); } } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c index b8fd14cd8..e606e6798 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.c @@ -54,7 +54,7 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); */ static int32_t _pxp_delete(lv_draw_unit_t * draw_unit); -#if LV_USE_OS +#if LV_USE_PXP_DRAW_THREAD static void _pxp_render_thread_cb(void * ptr); #endif @@ -91,7 +91,7 @@ void lv_draw_pxp_init(void) lv_pxp_init(); -#if LV_USE_OS +#if LV_USE_PXP_DRAW_THREAD lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit); #endif } @@ -284,6 +284,9 @@ static int32_t _pxp_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc; const lv_image_dsc_t * img_dsc = draw_dsc->src; + if(draw_dsc->tile) + return 0; + if((!_pxp_src_cf_supported(img_dsc->header.cf)) || (!pxp_buf_aligned(img_dsc->data, img_dsc->header.stride))) return 0; @@ -316,18 +319,18 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_PXP); if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_PXP) - return -1; + return LV_DRAW_UNIT_IDLE; void * buf = lv_draw_layer_alloc_buf(layer); if(buf == NULL) - return -1; + return LV_DRAW_UNIT_IDLE; t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; draw_pxp_unit->base_unit.target_layer = layer; draw_pxp_unit->base_unit.clip_area = &t->clip_area; draw_pxp_unit->task_act = t; -#if LV_USE_OS +#if LV_USE_PXP_DRAW_THREAD /* Let the render thread work. */ if(draw_pxp_unit->inited) lv_thread_sync_signal(&draw_pxp_unit->sync); @@ -346,7 +349,7 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) static int32_t _pxp_delete(lv_draw_unit_t * draw_unit) { -#if LV_USE_OS +#if LV_USE_PXP_DRAW_THREAD lv_draw_pxp_unit_t * draw_pxp_unit = (lv_draw_pxp_unit_t *) draw_unit; LV_LOG_INFO("Cancel PXP draw thread."); @@ -373,7 +376,7 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) lv_draw_buf_t * draw_buf = layer->draw_buf; lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &t->area, draw_unit->clip_area)) + if(!lv_area_intersect(&draw_area, &t->area, draw_unit->clip_area)) return; /*Fully clipped, nothing to do*/ /* Make area relative to the buffer */ @@ -400,7 +403,7 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) /*Layers manage it for themselves*/ if(t->type != LV_DRAW_TASK_TYPE_LAYER) { lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area)) + if(!lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area)) return; int32_t idx = 0; @@ -411,7 +414,7 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) } lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); - rect_dsc.bg_color = lv_palette_main(idx % _LV_PALETTE_LAST); + rect_dsc.bg_color = lv_palette_main(idx % LV_PALETTE_LAST); rect_dsc.border_color = rect_dsc.bg_color; rect_dsc.bg_opa = LV_OPA_10; rect_dsc.border_opa = LV_OPA_80; @@ -442,7 +445,7 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) #endif } -#if LV_USE_OS +#if LV_USE_PXP_DRAW_THREAD static void _pxp_render_thread_cb(void * ptr) { lv_draw_pxp_unit_t * u = ptr; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c index 60873ede0..c75de3480 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c @@ -64,7 +64,7 @@ void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t blend_area; - if(!_lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area)) + if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area)) return; /*Fully clipped, nothing to do*/ _pxp_fill(draw_buf->data, &blend_area, draw_buf->header.stride, draw_buf->header.cf, dsc); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c index 9e5205667..08c0a8ad6 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c @@ -82,7 +82,7 @@ void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); if(has_transform) lv_area_copy(&blend_area, &rel_coords); - else if(!_lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area)) + else if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area)) return; /*Fully clipped, nothing to do*/ const uint8_t * src_buf = img_dsc->data; @@ -252,8 +252,8 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, dest_h = src_h * fp_scale_y + trim_y; /*Final pivot offset = scale_factor * rotation_pivot_offset + scaling_pivot_offset*/ - piv_offset_x = floor(fp_scale_x * piv_offset_x) - floor((fp_scale_x - 1) * pivot.x); - piv_offset_y = floor(fp_scale_y * piv_offset_y) - floor((fp_scale_y - 1) * pivot.y); + piv_offset_x = floorf(fp_scale_x * piv_offset_x) - floorf((fp_scale_x - 1) * pivot.x); + piv_offset_y = floorf(fp_scale_y * piv_offset_y) - floorf((fp_scale_y - 1) * pivot.y); } /*PS buffer - source image*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c index 28245f964..4ee33010d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c @@ -81,8 +81,8 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d int32_t w = lv_area_get_width(coords); int32_t h = lv_area_get_height(coords); - _lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, - &draw_dsc->pivot); + lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, + &draw_dsc->pivot); area_rot.x1 += coords->x1; area_rot.y1 += coords->y1; @@ -90,7 +90,7 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d area_rot.y2 += coords->y1; } lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return; #endif #if LV_USE_LAYER_DEBUG @@ -119,13 +119,13 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d lv_draw_fill_dsc_t fill_dsc; lv_draw_rect_dsc_init(&fill_dsc); - fill_dsc.color = lv_palette_main(idx % _LV_PALETTE_LAST); + fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); fill_dsc.opa = LV_OPA_10; lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); lv_draw_border_dsc_t border_dsc; lv_draw_border_dsc_init(&border_dsc); - border_dsc.color = lv_palette_main(idx % _LV_PALETTE_LAST); + border_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); border_dsc.opa = LV_OPA_100; border_dsc.width = 2; lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c index 539cefe50..b573b212b 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_pxp_osa.c @@ -18,11 +18,16 @@ #if LV_USE_DRAW_PXP #include "lv_pxp_utils.h" #include "../../../misc/lv_log.h" +#include "../../../osal/lv_os.h" #include "fsl_pxp.h" #if defined(SDK_OS_FREE_RTOS) #include "FreeRTOS.h" - #include "semphr.h" +#endif + +#if defined(__ZEPHYR__) + #include + #include #endif /********************* @@ -57,12 +62,19 @@ static void _pxp_run(void); */ static void _pxp_wait(void); +#if defined(__ZEPHYR__) + /** + * Interrupt handler for Zephyr IRQ + */ + static void _pxp_zephyr_irq_handler(void *); +#endif + /********************** * STATIC VARIABLES **********************/ -#if defined(SDK_OS_FREE_RTOS) - static SemaphoreHandle_t xPXPIdleSemaphore; +#if LV_USE_OS + static lv_thread_sync_t pxp_sync; #endif static volatile bool ucPXPIdle; @@ -83,20 +95,10 @@ static pxp_cfg_t _pxp_default_cfg = { void PXP_IRQHandler(void) { -#if defined(SDK_OS_FREE_RTOS) - BaseType_t xHigherPriorityTaskWoken = pdFALSE; -#endif - if(kPXP_CompleteFlag & PXP_GetStatusFlags(PXP_ID)) { PXP_ClearStatusFlags(PXP_ID, kPXP_CompleteFlag); -#if defined(SDK_OS_FREE_RTOS) - xSemaphoreGiveFromISR(xPXPIdleSemaphore, &xHigherPriorityTaskWoken); - - /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch - should be performed to ensure the interrupt returns directly to the highest - priority task. The macro used for this purpose is dependent on the port in - use and may be called portEND_SWITCHING_ISR(). */ - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#if LV_USE_OS + lv_thread_sync_signal_isr(&pxp_sync); #else ucPXPIdle = true; #endif @@ -112,24 +114,45 @@ pxp_cfg_t * pxp_get_default_cfg(void) * STATIC FUNCTIONS **********************/ +#if defined(__ZEPHYR__) +static void _pxp_zephyr_irq_handler(void *) +{ + PXP_IRQHandler(); +} +#endif + static void _pxp_interrupt_init(void) { -#if defined(SDK_OS_FREE_RTOS) - xPXPIdleSemaphore = xSemaphoreCreateBinary(); - PXP_ASSERT_MSG(xPXPIdleSemaphore, "xSemaphoreCreateBinary failed!"); +#if LV_USE_OS + if(lv_thread_sync_init(&pxp_sync) != LV_RESULT_OK) { + PXP_ASSERT_MSG(false, "Failed to init thread_sync."); + } +#endif +#if defined(__ZEPHYR__) + IRQ_CONNECT(DT_IRQN(DT_NODELABEL(pxp)), CONFIG_LV_Z_PXP_INTERRUPT_PRIORITY, _pxp_zephyr_irq_handler, NULL, 0); + irq_enable(DT_IRQN(DT_NODELABEL(pxp))); +#elif defined(SDK_OS_FREE_RTOS) NVIC_SetPriority(PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); #endif - ucPXPIdle = true; +#if !defined(__ZEPHYR__) NVIC_EnableIRQ(PXP_IRQ_ID); +#endif + + ucPXPIdle = true; } static void _pxp_interrupt_deinit(void) { +#if defined(__ZEPHYR__) + irq_disable(DT_IRQN(DT_NODELABEL(pxp))); +#else NVIC_DisableIRQ(PXP_IRQ_ID); -#if defined(SDK_OS_FREE_RTOS) - vSemaphoreDelete(xPXPIdleSemaphore); +#endif + +#if LV_USE_OS + lv_thread_sync_delete(&pxp_sync); #endif } @@ -149,12 +172,10 @@ static void _pxp_run(void) */ static void _pxp_wait(void) { -#if defined(SDK_OS_FREE_RTOS) - /* Return if PXP was never started, otherwise the semaphore will lock forever. */ if(ucPXPIdle == true) return; - - if(xSemaphoreTake(xPXPIdleSemaphore, portMAX_DELAY) == pdTRUE) +#if LV_USE_OS + if(lv_thread_sync_wait(&pxp_sync) == LV_RESULT_OK) ucPXPIdle = true; #else while(ucPXPIdle == false) { diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c index dafb0156b..ae9b59a5e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_buf_vglite.c @@ -16,6 +16,7 @@ #include "lv_draw_vglite.h" #if LV_USE_DRAW_VGLITE +#include "../../lv_draw_buf_private.h" #include "lv_vglite_buf.h" #include "lv_vglite_utils.h" @@ -33,13 +34,7 @@ * STATIC PROTOTYPES **********************/ -static void * _buf_malloc(size_t size_bytes, lv_color_format_t cf); - -static void * _buf_align(void * buf, lv_color_format_t cf); - -static void _invalidate_cache(const void * buf, uint32_t stride, lv_color_format_t cf, const lv_area_t * area); - -static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf); +static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); /********************** * STATIC VARIABLES @@ -57,39 +52,13 @@ void lv_draw_buf_vglite_init_handlers(void) { lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); - handlers->buf_malloc_cb = _buf_malloc; - handlers->align_pointer_cb = _buf_align; handlers->invalidate_cache_cb = _invalidate_cache; - handlers->width_to_stride_cb = _width_to_stride; } /********************** * STATIC FUNCTIONS **********************/ -static void * _buf_malloc(size_t size_bytes, lv_color_format_t cf) -{ - uint8_t align_bytes = vglite_get_alignment(cf); - - /*Allocate larger memory to be sure it can be aligned as needed*/ - size_bytes += align_bytes - 1; - - return lv_malloc(size_bytes); -} - -static void * _buf_align(void * buf, lv_color_format_t cf) -{ - uint8_t align_bytes = vglite_get_alignment(cf); - - uint8_t * buf_u8 = buf; - if(buf_u8) { - buf_u8 += align_bytes - 1; - buf_u8 = (uint8_t *)((lv_uintptr_t)buf_u8 & ~(align_bytes - 1)); - } - - return buf_u8; -} - static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) { const lv_image_header_t * header = &draw_buf->header; @@ -100,11 +69,11 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * uint16_t size = stride * lv_area_get_height(area); /* Invalidate full buffer. */ - DEMO_CleanInvalidateCacheByAddr((void *)buf, size); + DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); return; } - const uint8_t * buf_u8 = buf; + const uint8_t * buf_u8 = draw_buf->data; /* ARM require a 32 byte aligned address. */ uint8_t align_bytes = 32; uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); @@ -139,14 +108,4 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * } } -static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf) -{ - uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); - uint32_t width_bits = (w * bits_per_pixel + 7) & ~7; - uint32_t width_bytes = width_bits / 8; - uint8_t align_bytes = vglite_get_alignment(cf); - - return (width_bytes + align_bytes - 1) & ~(align_bytes - 1); -} - #endif /*LV_USE_DRAW_VGLITE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c index d4c951728..bf9dce96e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.c @@ -19,9 +19,7 @@ #include "lv_vglite_buf.h" #include "lv_vglite_utils.h" -#if LV_USE_PARALLEL_DRAW_DEBUG - #include "../../../core/lv_global.h" -#endif +#include "../../../core/lv_global.h" /********************* * DEFINES @@ -30,7 +28,7 @@ #define DRAW_UNIT_ID_VGLITE 2 #if LV_USE_VGLITE_DRAW_ASYNC - #define VGLITE_TASK_BUF_SIZE 10 + #define VGLITE_TASK_BUF_SIZE 100 #endif /********************** @@ -63,12 +61,19 @@ static int32_t _vglite_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * tas */ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); +/* + * Wait for VG-Lite draw unit to finish. + */ +#if LV_USE_VGLITE_DRAW_ASYNC + static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit); +#endif + /* * Delete the VGLite draw unit. */ static int32_t _vglite_delete(lv_draw_unit_t * draw_unit); -#if LV_USE_OS +#if LV_USE_VGLITE_DRAW_THREAD static void _vglite_render_thread_cb(void * ptr); #endif @@ -78,9 +83,7 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u); * STATIC VARIABLES **********************/ -#if LV_USE_PARALLEL_DRAW_DEBUG - #define _draw_info LV_GLOBAL_DEFAULT()->draw_info -#endif +#define _draw_info LV_GLOBAL_DEFAULT()->draw_info #if LV_USE_VGLITE_DRAW_ASYNC /* @@ -108,9 +111,12 @@ void lv_draw_vglite_init(void) lv_draw_vglite_unit_t * draw_vglite_unit = lv_draw_create_unit(sizeof(lv_draw_vglite_unit_t)); draw_vglite_unit->base_unit.evaluate_cb = _vglite_evaluate; draw_vglite_unit->base_unit.dispatch_cb = _vglite_dispatch; +#if LV_USE_VGLITE_DRAW_ASYNC + draw_vglite_unit->base_unit.wait_for_finish_cb = _vglite_wait_for_finish; +#endif draw_vglite_unit->base_unit.delete_cb = _vglite_delete; -#if LV_USE_OS +#if LV_USE_VGLITE_DRAW_THREAD lv_thread_init(&draw_vglite_unit->thread, LV_THREAD_PRIO_HIGH, _vglite_render_thread_cb, 2 * 1024, draw_vglite_unit); #endif } @@ -163,7 +169,7 @@ static inline bool _vglite_dest_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_L8: #endif case LV_COLOR_FORMAT_RGB565: -#if CHIPTID == 0x555 +#if CHIPID == 0x555 case LV_COLOR_FORMAT_RGB565A8: case LV_COLOR_FORMAT_RGB888: #endif @@ -212,11 +218,6 @@ static int32_t _vglite_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) return 1; case LV_DRAW_TASK_TYPE_BORDER: { - const lv_draw_border_dsc_t * draw_dsc = (lv_draw_border_dsc_t *) t->draw_dsc; - - if(draw_dsc->side != (lv_border_side_t)LV_BORDER_SIDE_FULL) - return 0; - if(t->preference_score > 90) { t->preference_score = 90; t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; @@ -259,7 +260,7 @@ static int32_t _vglite_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) #if LV_USE_VGLITE_BLIT_SPLIT || has_transform #endif - || (!vglite_buf_aligned(img_dsc->data, img_dsc->header.stride, img_dsc->header.cf)) + || (!vglite_src_buf_aligned(img_dsc->data, img_dsc->header.stride, img_dsc->header.cf)) ) return 0; @@ -287,19 +288,36 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) /* Try to get an ready to draw. */ lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_VGLITE); - if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) - return -1; + if(t == NULL) + return LV_DRAW_UNIT_IDLE; + + if(lv_draw_get_unit_count() > 1) { + /* Let the SW unit to draw this task. */ + if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) + return LV_DRAW_UNIT_IDLE; + } + else { + /* Fake unsupported tasks as ready. */ + if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) { + t->state = LV_DRAW_TASK_STATE_READY; + + /* Request a new dispatching as it can get a new task. */ + lv_draw_dispatch_request(); + + return 1; + } + } void * buf = lv_draw_layer_alloc_buf(layer); if(buf == NULL) - return -1; + return LV_DRAW_UNIT_IDLE; t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; draw_vglite_unit->base_unit.target_layer = layer; draw_vglite_unit->base_unit.clip_area = &t->clip_area; draw_vglite_unit->task_act = t; -#if LV_USE_OS +#if LV_USE_VGLITE_DRAW_THREAD /* Let the render thread work. */ if(draw_vglite_unit->inited) lv_thread_sync_signal(&draw_vglite_unit->sync); @@ -316,9 +334,22 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) return 1; } +#if LV_USE_VGLITE_DRAW_ASYNC +static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit) +{ + lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; + draw_vglite_unit->wait_for_finish = true; + + if(draw_vglite_unit->inited) + lv_thread_sync_signal(&draw_vglite_unit->sync); + + return 1; +} +#endif + static int32_t _vglite_delete(lv_draw_unit_t * draw_unit) { -#if LV_USE_OS +#if LV_USE_VGLITE_DRAW_THREAD lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; LV_LOG_INFO("Cancel VGLite draw thread."); @@ -333,7 +364,7 @@ static int32_t _vglite_delete(lv_draw_unit_t * draw_unit) #else LV_UNUSED(draw_unit); - return 0; + return 1; #endif } @@ -356,11 +387,11 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) lv_area_copy(&draw_area, &t->area); lv_area_move(&draw_area, -layer->buf_area.x1, -layer->buf_area.y1); - if(!_lv_area_intersect(&draw_area, &draw_area, &clip_area)) + if(!lv_area_intersect(&draw_area, &draw_area, &clip_area)) return; /*Fully clipped, nothing to do*/ - /* Invalidate the drawing area */ - lv_draw_buf_invalidate_cache(draw_buf, &draw_area); + if(_draw_info.unit_cnt > 1) + lv_draw_buf_invalidate_cache(draw_buf, &draw_area); /* Set scissor area, excluding the split blit case */ #if LV_USE_VGLITE_BLIT_SPLIT @@ -404,7 +435,7 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) /*Layers manage it for themselves*/ if(t->type != LV_DRAW_TASK_TYPE_LAYER) { lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area)) + if(!lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area)) return; int32_t idx = 0; @@ -415,7 +446,7 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) } lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); - rect_dsc.bg_color = lv_palette_main(idx % _LV_PALETTE_LAST); + rect_dsc.bg_color = lv_palette_main(idx % LV_PALETTE_LAST); rect_dsc.border_color = rect_dsc.bg_color; rect_dsc.bg_opa = LV_OPA_10; rect_dsc.border_opa = LV_OPA_80; @@ -447,27 +478,46 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) } #if LV_USE_VGLITE_DRAW_ASYNC -static inline void _vglite_queue_task(lv_draw_task_t * task_act) +static inline void _vglite_queue_task(lv_draw_task_t * task) { - _draw_task_buf[_tail].task = task_act; + VGLITE_ASSERT_MSG(((_tail + 1) % VGLITE_TASK_BUF_SIZE) != _head, "VGLite task buffer full."); + + _draw_task_buf[_tail].task = task; _draw_task_buf[_tail].flushed = false; _tail = (_tail + 1) % VGLITE_TASK_BUF_SIZE; } -static inline void _vglite_signal_task_ready(lv_draw_task_t * task_act) +static inline void _vglite_signal_task_ready(lv_draw_task_t * task) +{ + /* Signal the ready state to dispatcher. */ + task->state = LV_DRAW_TASK_STATE_READY; + _head = (_head + 1) % VGLITE_TASK_BUF_SIZE; + + /* No need to cleanup the tasks in buffer as we advance with the _head. */ +} + +static inline void _vglite_signal_all_task_ready(void) +{ + int end = (_head <= _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE; + + for(int i = _head; i < end; i++) { + lv_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; + + _vglite_signal_task_ready(task); + } +} + +static inline void _vglite_signal_flushed_task_ready(void) { if(vglite_cmd_buf_is_flushed()) { - int end = (_head < _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE; + int end = (_head <= _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE; for(int i = _head; i < end; i++) { - /* Previous flushed tasks are ready now. */ if(_draw_task_buf[i % VGLITE_TASK_BUF_SIZE].flushed) { lv_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; - /* Signal the ready state to dispatcher. */ - task->state = LV_DRAW_TASK_STATE_READY; - _head = (_head + 1) % VGLITE_TASK_BUF_SIZE; - /* No need to cleanup the tasks in buffer as we advance with the _head. */ + _vglite_signal_task_ready(task); + } else { /* Those tasks have been flushed now. */ @@ -475,13 +525,10 @@ static inline void _vglite_signal_task_ready(lv_draw_task_t * task_act) } } } - - if(task_act) - VGLITE_ASSERT_MSG(_tail != _head, "VGLite task buffer full."); } #endif -#if LV_USE_OS +#if LV_USE_VGLITE_DRAW_THREAD static void _vglite_render_thread_cb(void * ptr) { lv_draw_vglite_unit_t * u = ptr; @@ -495,9 +542,9 @@ static void _vglite_render_thread_cb(void * ptr) #if LV_USE_VGLITE_DRAW_ASYNC /* * Wait for sync if _draw_task_buf is empty. - * The thread will have to run as much as there are pending tasks. + * The thread will have to run to complete any pending tasks. */ - && _head == _tail + && !u->wait_for_finish #endif ) { if(u->exit_status) @@ -518,16 +565,14 @@ static void _vglite_render_thread_cb(void * ptr) _vglite_execute_drawing(u); } #if LV_USE_VGLITE_DRAW_ASYNC - else { - /* - * Update the flush status for last pending tasks. - * vg_lite_flush() will early return if there is nothing to submit. - */ - vglite_run(); + if(u->wait_for_finish) { + u->wait_for_finish = false; + vglite_wait_for_finish(); + _vglite_signal_all_task_ready(); + } + else { /* u->task_act */ + _vglite_signal_flushed_task_ready(); } -#endif -#if LV_USE_VGLITE_DRAW_ASYNC - _vglite_signal_task_ready((void *)u->task_act); #else /* Signal the ready state to dispatcher. */ u->task_act->state = LV_DRAW_TASK_STATE_READY; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.h index fe3cdfbc2..93b18cd7e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite.h @@ -23,7 +23,9 @@ extern "C" { #include "../../../lv_conf_internal.h" #if LV_USE_DRAW_VGLITE -#include "../../sw/lv_draw_sw.h" +#include "../../lv_draw_private.h" +#include "../../sw/lv_draw_sw_private.h" +#include "../../../misc/lv_area_private.h" /********************* * DEFINES @@ -33,7 +35,12 @@ extern "C" { * TYPEDEFS **********************/ -typedef lv_draw_sw_unit_t lv_draw_vglite_unit_t; +typedef struct lv_draw_vglite_unit { + lv_draw_sw_unit_t; +#if LV_USE_VGLITE_DRAW_ASYNC + volatile bool wait_for_finish; +#endif +} lv_draw_vglite_unit_t; /********************** * GLOBAL PROTOTYPES diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_border.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_border.c index eb8c93bae..db762fb61 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_border.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_border.c @@ -30,6 +30,9 @@ * DEFINES *********************/ +/*** Define maximum numbers of rectangles needed to clip partial borders ***/ +#define MAX_NUM_RECTANGLES 4 + /********************** * TYPEDEFS **********************/ @@ -88,7 +91,7 @@ void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_ lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clipped_coords; - if(!_lv_area_intersect(&clipped_coords, &inward_coords, &clip_area)) + if(!lv_area_intersect(&clipped_coords, &inward_coords, &clip_area)) return; /*Fully clipped, nothing to do*/ _vglite_draw_border(&inward_coords, &clip_area, dsc); @@ -132,6 +135,53 @@ static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip vg_lite_identity(&matrix); int32_t line_width = dsc->width; + lv_border_side_t border_side = dsc->side; + + if(border_side == LV_BORDER_SIDE_FULL) + border_side = LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT | LV_BORDER_SIDE_RIGHT; + + uint32_t num_rect = 0; + vg_lite_rectangle_t rect[MAX_NUM_RECTANGLES]; + int32_t rect_width = coords->x2 - coords->x1; + int32_t rect_height = coords->y2 - coords->y1; + int32_t shortest_side = LV_MIN(rect_width, rect_height); + int32_t final_radius = LV_MIN(radius, shortest_side / 2); + + if(border_side & LV_BORDER_SIDE_TOP) { + rect[num_rect].x = coords->x1 - ceil(line_width / 2.0f); + rect[num_rect].y = coords->y1 - ceil(line_width / 2.0f); + rect[num_rect].width = coords->x2 - coords->x1 + line_width; + rect[num_rect].height = final_radius + ceil(line_width / 2.0f); + num_rect++; + } + + if(border_side & LV_BORDER_SIDE_LEFT) { + rect[num_rect].x = coords->x1 - ceil(line_width / 2.0f); + rect[num_rect].y = coords->y1 - ceil(line_width / 2.0f); + rect[num_rect].width = final_radius + ceil(line_width / 2.0f); + rect[num_rect].height = coords->y2 - coords->y1 + line_width + 1; + num_rect++; + } + + if(border_side & LV_BORDER_SIDE_RIGHT) { + rect[num_rect].x = coords->x2 - final_radius + 1; + rect[num_rect].y = coords->y1 - ceil(line_width / 2.0f); + rect[num_rect].width = final_radius + ceil(line_width / 2.0f); + rect[num_rect].height = coords->y2 - coords->y1 + line_width + 1; + num_rect++; + } + + if(border_side & LV_BORDER_SIDE_BOTTOM) { + rect[num_rect].x = coords->x1 - ceil(line_width / 2.0f); + rect[num_rect].y = coords->y2 - final_radius + 1; + rect[num_rect].width = coords->x2 - coords->x1 + line_width; + rect[num_rect].height = final_radius + ceil(line_width / 2.0f); + num_rect++; + } + + /*** Enable scissor and apply scissor rects ***/ + VGLITE_CHECK_ERROR(vg_lite_enable_scissor()); + VGLITE_CHECK_ERROR(vg_lite_scissor_rects(vgbuf, num_rect, rect)); /*** Draw border ***/ VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH)); @@ -145,6 +195,9 @@ static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip vglite_run(); VGLITE_CHECK_ERROR(vg_lite_clear_path(&path)); + + /*** Disable scissor ***/ + VGLITE_CHECK_ERROR(vg_lite_disable_scissor()); } #endif /*LV_USE_DRAW_VGLITE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_fill.c index bf066859e..97089ce55 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_fill.c @@ -82,7 +82,7 @@ void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clipped_coords; - if(!_lv_area_intersect(&clipped_coords, &relative_coords, &clip_area)) + if(!lv_area_intersect(&clipped_coords, &relative_coords, &clip_area)) return; /*Fully clipped, nothing to do*/ /* diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_img.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_img.c index b7ee0560c..49fdffaff 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_img.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_img.c @@ -146,7 +146,7 @@ void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); if(has_transform) lv_area_copy(&blend_area, &relative_coords); - else if(!_lv_area_intersect(&blend_area, &relative_coords, &clip_area)) + else if(!lv_area_intersect(&blend_area, &relative_coords, &clip_area)) return; /*Fully clipped, nothing to do*/ const void * src_buf = img_dsc->data; @@ -213,7 +213,7 @@ static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * static void _move_buf_close_to_area(void ** buf, lv_area_t * area, uint32_t stride, lv_color_format_t cf) { uint8_t ** buf_u8 = (uint8_t **)buf; - uint8_t align_bytes = vglite_get_alignment(cf); + uint8_t align_bytes = vglite_get_stride_alignment(cf); uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); uint16_t align_pixels = align_bytes * 8 / bits_per_pixel; @@ -381,7 +381,7 @@ static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * /* Path to draw */ int32_t path_data[RECT_PATH_DATA_MAX_SIZE]; uint32_t path_data_size; - vglite_create_rect_path_data(path_data, &path_data_size, 0, coords); + vglite_create_rect_path_data(path_data, &path_data_size, dsc->clip_radius, coords); vg_lite_quality_t path_quality = VG_LITE_MEDIUM; vg_lite_path_t path; @@ -399,7 +399,9 @@ static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; /* Pattern matrix */ - vg_lite_matrix_t * vgmatrix = vglite_get_matrix(); + vg_lite_matrix_t vgmatrix; + vg_lite_identity(&vgmatrix); + vg_lite_translate((vg_lite_float_t)dsc->image_area.x1, (vg_lite_float_t)dsc->image_area.y1, &vgmatrix); /* Blend mode */ vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode); @@ -407,12 +409,12 @@ static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * vg_lite_color_t vgcol = _vglite_recolor(dsc); /* Filter */ - bool has_trasform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - vg_lite_filter_t filter = has_trasform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; + bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); + vg_lite_filter_t filter = has_transform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; /* Draw Pattern */ VGLITE_CHECK_ERROR(vg_lite_draw_pattern(dst_vgbuf, &path, VG_LITE_FILL_NON_ZERO, &path_matrix, - src_vgbuf, vgmatrix, vgblend, VG_LITE_PATTERN_REPEAT, + src_vgbuf, &vgmatrix, vgblend, VG_LITE_PATTERN_REPEAT, 0, vgcol, filter)); } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_label.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_label.c index 9c9dbe4a9..9af7c6837 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_label.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_label.c @@ -20,6 +20,7 @@ #include "lv_vglite_matrix.h" #include "lv_vglite_utils.h" +#include "../../lv_draw_label_private.h" #include "../../../stdlib/lv_string.h" /********************* @@ -101,7 +102,7 @@ static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t lv_layer_t * layer = draw_unit->target_layer; lv_area_t blend_area; - if(!_lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, draw_unit->clip_area)) + if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, draw_unit->clip_area)) return; lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); @@ -118,34 +119,21 @@ static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t mask_area.x2 = mask_width - 1; mask_area.y2 = mask_height - 1; - if(!vglite_buf_aligned(mask_buf, mask_stride, LV_COLOR_FORMAT_A8)) { - /* Draw a placeholder rectangle*/ - lv_draw_border_dsc_t border_draw_dsc; - lv_draw_border_dsc_init(&border_draw_dsc); - border_draw_dsc.opa = glyph_draw_dsc->opa; - border_draw_dsc.color = glyph_draw_dsc->color; - border_draw_dsc.width = 1; - lv_draw_vglite_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords); - } - else { - /* Set src_vgbuf structure. */ - vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8); + /* Set src_vgbuf structure. */ + vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8); - /* Set vgmatrix. */ - vglite_set_translation_matrix(&blend_area); + /* Set vgmatrix. */ + vglite_set_translation_matrix(&blend_area); - lv_draw_buf_invalidate_cache(draw_buf, &mask_area); + lv_draw_buf_invalidate_cache(draw_buf, &mask_area); - _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa); - } + _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa); } break; case LV_FONT_GLYPH_FORMAT_IMAGE: { #if LV_USE_IMGFONT - lv_draw_img_dsc_t img_dsc; - lv_draw_img_dsc_init(&img_dsc); - img_dsc.angle = 0; - img_dsc.zoom = LV_ZOOM_NONE; + lv_draw_image_dsc_t img_dsc; + lv_draw_image_dsc_init(&img_dsc); img_dsc.opa = glyph_draw_dsc->opa; img_dsc.src = glyph_draw_dsc->glyph_data; lv_draw_vglite_img(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_layer.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_layer.c index 65283d0e2..ce3f59ea5 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_layer.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_layer.c @@ -18,9 +18,7 @@ #if LV_USE_DRAW_VGLITE #include "../../../stdlib/lv_string.h" -#if LV_USE_PARALLEL_DRAW_DEBUG - #include "../../../core/lv_global.h" -#endif +#include "../../../core/lv_global.h" /********************* * DEFINES @@ -38,9 +36,7 @@ * STATIC VARIABLES **********************/ -#if LV_USE_PARALLEL_DRAW_DEBUG - #define _draw_info LV_GLOBAL_DEFAULT()->draw_info -#endif +#define _draw_info LV_GLOBAL_DEFAULT()->draw_info /********************** * MACROS @@ -62,13 +58,15 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t if(draw_buf == NULL) return; - const lv_area_t area_to_draw = { - .x1 = 0, - .y1 = 0, - .x2 = draw_buf->header.w - 1, - .y2 = draw_buf->header.h - 1 - }; - lv_draw_buf_invalidate_cache(draw_buf, &area_to_draw); + if(_draw_info.unit_cnt > 1) { + const lv_area_t area_to_draw = { + .x1 = 0, + .y1 = 0, + .x2 = draw_buf->header.w - 1, + .y2 = draw_buf->header.h - 1 + }; + lv_draw_buf_invalidate_cache(draw_buf, &area_to_draw); + } lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; new_draw_dsc.src = draw_buf; @@ -84,8 +82,8 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t int32_t w = lv_area_get_width(coords); int32_t h = lv_area_get_height(coords); - _lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, - &draw_dsc->pivot); + lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, + &draw_dsc->pivot); area_rot.x1 += coords->x1; area_rot.y1 += coords->y1; @@ -93,7 +91,7 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t area_rot.y2 += coords->y1; } lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return; #endif #if LV_USE_LAYER_DEBUG @@ -122,13 +120,13 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t lv_draw_fill_dsc_t fill_dsc; lv_draw_rect_dsc_init(&fill_dsc); - fill_dsc.color = lv_palette_main(idx % _LV_PALETTE_LAST); + fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); fill_dsc.opa = LV_OPA_10; lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); lv_draw_border_dsc_t border_dsc; lv_draw_border_dsc_init(&border_dsc); - border_dsc.color = lv_palette_main(idx % _LV_PALETTE_LAST); + border_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); border_dsc.opa = LV_OPA_100; border_dsc.width = 2; lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_line.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_line.c index d458375c5..f70c02b20 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_line.c @@ -71,7 +71,7 @@ void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * clip_area.y1 = LV_MIN(dsc->p1.y, dsc->p2.y) - dsc->width / 2; clip_area.y2 = LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width / 2; - if(!_lv_area_intersect(&clip_area, &clip_area, draw_unit->clip_area)) + if(!lv_area_intersect(&clip_area, &clip_area, draw_unit->clip_area)) return; /*Fully clipped, nothing to do*/ lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c index 0de169dc0..4f72f3aff 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_triangle.c @@ -76,7 +76,7 @@ void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_ lv_area_move(&coords, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clipped_coords; - if(!_lv_area_intersect(&clipped_coords, &coords, &clip_area)) + if(!lv_area_intersect(&clipped_coords, &coords, &clip_area)) return; /* Fully clipped, nothing to do */ _vglite_draw_triangle(&coords, &clip_area, dsc); @@ -134,10 +134,13 @@ static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * cl /* Gradient Setup */ vg_lite_uint32_t cnt = LV_MAX(dsc->bg_grad.stops_count, LV_GRADIENT_MAX_STOPS); + lv_opa_t bg_opa; + for(uint8_t i = 0; i < cnt; i++) { stops[i] = dsc->bg_grad.stops[i].frac; + bg_opa = LV_OPA_MIX2(dsc->bg_grad.stops[i].opa, dsc->bg_opa); - col32[i] = lv_color_to_32(dsc->bg_grad.stops[i].color, dsc->bg_grad.stops[i].opa); + col32[i] = lv_color_to_32(dsc->bg_grad.stops[i].color, bg_opa); colors[i] = vglite_get_color(col32[i], true); } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.c index 7e923cefc..b3afa5a40 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.c @@ -104,6 +104,13 @@ void vglite_run(void) #endif } +#if LV_USE_VGLITE_DRAW_ASYNC +void vglite_wait_for_finish(void) +{ + VGLITE_CHECK_ERROR(vg_lite_finish()); +} +#endif + vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient) { vg_lite_color_t vg_col32; @@ -218,7 +225,7 @@ vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf) return vg_buffer_format; } -uint8_t vglite_get_alignment(lv_color_format_t cf) +uint8_t vglite_get_stride_alignment(lv_color_format_t cf) { uint8_t align_bytes = LV_COLOR_DEPTH / 8 * 16; /*16 pixels*/ @@ -226,20 +233,12 @@ uint8_t vglite_get_alignment(lv_color_format_t cf) case LV_COLOR_FORMAT_I1: case LV_COLOR_FORMAT_I2: case LV_COLOR_FORMAT_I4: - /* - * VGLite alignment require 8 bytes. - * But ARM clean and invalidate cache needs 32 bytes address alignment. - */ - align_bytes = 32; + align_bytes = 8; break; case LV_COLOR_FORMAT_I8: case LV_COLOR_FORMAT_A8: case LV_COLOR_FORMAT_L8: - /* - * VGLite alignment require 16 bytes. - * But ARM clean and invalidate cache needs 32 bytes address alignment. - */ - align_bytes = 32; + align_bytes = 16; break; case LV_COLOR_FORMAT_RGB565: align_bytes = 32; @@ -261,18 +260,16 @@ uint8_t vglite_get_alignment(lv_color_format_t cf) return align_bytes; } -bool vglite_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf) +bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf) { - uint8_t align_bytes = vglite_get_alignment(cf); - /* No alignment requirement for destination buffer when using mode VG_LITE_LINEAR */ /* Test for pointer alignment */ - if((uintptr_t)buf % align_bytes) + if((uintptr_t)buf % LV_ATTRIBUTE_MEM_ALIGN_SIZE) return false; /* Test for stride alignment */ - if(stride == 0 || stride % align_bytes) + if(stride == 0 || stride % vglite_get_stride_alignment(cf)) return false; return true; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.h index 814276223..6615c4c79 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_utils.h @@ -95,6 +95,14 @@ bool vglite_cmd_buf_is_flushed(void); */ void vglite_run(void); +/** + * Wait for VG-Lite finish. + * + */ +#if LV_USE_VGLITE_DRAW_ASYNC +void vglite_wait_for_finish(void); +#endif + /** * Get vglite color. Premultiplies (if not hw already) and swizzles the given * LVGL 32bit color to obtain vglite color. @@ -128,17 +136,17 @@ vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode); vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf); /** - * Get vglite buffer alignment. + * Get vglite stride alignment. * * @param[in] cf Color format * * @retval Alignment requirement in bytes * */ -uint8_t vglite_get_alignment(lv_color_format_t cf); +uint8_t vglite_get_stride_alignment(lv_color_format_t cf); /** - * Check memory and stride alignment. + * Check source start address and stride alignment. * * @param[in] buf Buffer address * @param[in] stride Stride of buffer in bytes @@ -147,7 +155,7 @@ uint8_t vglite_get_alignment(lv_color_format_t cf); * @retval true Alignment OK * */ -bool vglite_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf); +bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.c index 1d5a796d6..039b147a7 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.c @@ -8,6 +8,7 @@ *********************/ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D +#include "../../lv_draw_buf_private.h" /********************* * DEFINES @@ -81,23 +82,19 @@ void lv_draw_dave2d_init(void) draw_dave2d_unit->idx = DRAW_UNIT_ID_DAVE2D; result = lv_dave2d_init(); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); #if LV_USE_OS lv_result_t res; res = lv_mutex_init(&xd2Semaphore); - if(LV_RESULT_OK != res) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == res); draw_dave2d_unit->pd2Mutex = &xd2Semaphore; #endif draw_dave2d_unit->d2_handle = _d2_handle; draw_dave2d_unit->renderbuffer = _renderbuffer; - _lv_ll_init(&_ll_Dave2D_Tasks, 4); + lv_ll_init(&_ll_Dave2D_Tasks, 4); #if LV_USE_OS lv_thread_init(&draw_dave2d_unit->thread, LV_THREAD_PRIO_HIGH, _dave2d_render_thread_cb, 8 * 1024, draw_dave2d_unit); @@ -111,10 +108,10 @@ void lv_draw_dave2d_init(void) static void lv_draw_buf_dave2d_init_handlers(void) { - lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); #if defined(RENESAS_CORTEX_M85) #if (BSP_CFG_DCACHE_ENABLED) + lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); handlers->invalidate_cache_cb = _dave2d_buf_invalidate_cache_cb; #endif #endif @@ -160,76 +157,52 @@ static void _dave2d_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, lv_result_t status; status = lv_mutex_lock(&xd2Semaphore); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif d2_u32 src_blend_mode = d2_getblendmodesrc(_d2_handle); d2_u32 dst_blend_mode = d2_getblendmodedst(_d2_handle); result = d2_selectrenderbuffer(_d2_handle, _blit_renderbuffer); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_setblendmode(_d2_handle, d2_bm_one, d2_bm_zero); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); // Generate render operations result = d2_framebuffer(_d2_handle, (uint16_t *)dest_buf, DISPLAY_HSIZE_INPUT0, DISPLAY_BUFFER_STRIDE_PIXELS_INPUT0, DISPLAY_VSIZE_INPUT0, lv_draw_dave2d_cf_fb_get()); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_cliprect(_d2_handle, (d2_border)dest_area->x1, (d2_border)dest_area->y1, (d2_border)dest_area->x2, (d2_border)dest_area->y2); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_setblitsrc(_d2_handle, (void *) src_buf, (d2_s32)src_w, (d2_s32)src_w, (d2_s32)src_h, lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(color_format)); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_blitcopy(_d2_handle, (d2_s32)src_w, (d2_s32)src_h, (d2_blitpos)src_area->x1, (d2_blitpos)src_area->y1, D2_FIX4(dest_w), D2_FIX4(dest_h), D2_FIX4(dest_area->x1), D2_FIX4(dest_area->y1), 0); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); // Execute render operations result = d2_executerenderbuffer(_d2_handle, _blit_renderbuffer, 0); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result) ; result = d2_flushframe(_d2_handle); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_selectrenderbuffer(_d2_handle, _renderbuffer); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_setblendmode(_d2_handle, src_blend_mode, dst_blend_mode); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK != result); #if LV_USE_OS status = lv_mutex_unlock(&xd2Semaphore); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } @@ -259,7 +232,6 @@ static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) else #endif { - __NOP(); } ret = 0; break; @@ -373,25 +345,24 @@ static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * lv_draw_task_t * t = NULL; t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); + while(t && t->preferred_draw_unit_id != DRAW_UNIT_ID_DAVE2D) { + t->state = LV_DRAW_TASK_STATE_READY; + t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); + } - /* Return 0 is no selection, some tasks can be supported by other units. */ if(t == NULL) { #if (0 == D2_RENDER_EACH_OPERATION) - if(false == _lv_ll_is_empty(&_ll_Dave2D_Tasks)) { + if(false == lv_ll_is_empty(&_ll_Dave2D_Tasks)) { ref_count = 0; dave2d_execute_dlist_and_flush(); } #endif - return 0; - } - - if(t->preferred_draw_unit_id != DRAW_UNIT_ID_DAVE2D) { - return 0; + return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } void * buf = lv_draw_layer_alloc_buf(layer); if(buf == NULL) { - return -1; + return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } #if (0 == D2_RENDER_EACH_OPERATION) @@ -403,7 +374,7 @@ static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * } lv_draw_task_t ** p_new_list_entry; - p_new_list_entry = _lv_ll_ins_tail(&_ll_Dave2D_Tasks); + p_new_list_entry = lv_ll_ins_tail(&_ll_Dave2D_Tasks); *p_new_list_entry = t; #endif @@ -459,15 +430,15 @@ static void execute_drawing(lv_draw_dave2d_unit_t * u) { /*Render the draw task*/ lv_draw_task_t * t = u->task_act; - lv_layer_t * layer = u->base_unit.target_layer; #if defined(RENESAS_CORTEX_M85) #if (BSP_CFG_DCACHE_ENABLED) + lv_layer_t * layer = u->base_unit.target_layer; lv_area_t clipped_area; int32_t x; int32_t y; - _lv_area_intersect(&clipped_area, &t->area, u->base_unit.clip_area); + lv_area_intersect(&clipped_area, &t->area, u->base_unit.clip_area); x = 0 - u->base_unit.target_layer->buf_area.x1; y = 0 - u->base_unit.target_layer->buf_area.y1; @@ -537,7 +508,7 @@ static d2_s32 lv_dave2d_init(void) /* bind the hardware */ result = d2_inithw(_d2_handle, 0); if(result != D2_OK) { - LV_LOG_ERROR("Could NOT d2_inithw\n"); + LV_LOG_ERROR("Could NOT d2_inithw"); d2_closedevice(_d2_handle); return result; } @@ -555,14 +526,14 @@ static d2_s32 lv_dave2d_init(void) /* set blocksize for default displaylist */ result = d2_setdlistblocksize(_d2_handle, 25); if(D2_OK != result) { - LV_LOG_ERROR("Could NOT d2_setdlistblocksize\n"); + LV_LOG_ERROR("Could NOT d2_setdlistblocksize"); d2_closedevice(_d2_handle); return result; } _blit_renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20); if(!_blit_renderbuffer) { - LV_LOG_ERROR("NO renderbuffer\n"); + LV_LOG_ERROR("NO renderbuffer"); d2_closedevice(_d2_handle); return D2_NOMEMORY; @@ -570,7 +541,7 @@ static d2_s32 lv_dave2d_init(void) _renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20); if(!_renderbuffer) { - LV_LOG_ERROR("NO renderbuffer\n"); + LV_LOG_ERROR("NO renderbuffer"); d2_closedevice(_d2_handle); return D2_NOMEMORY; @@ -578,7 +549,7 @@ static d2_s32 lv_dave2d_init(void) result = d2_selectrenderbuffer(_d2_handle, _renderbuffer); if(D2_OK != result) { - LV_LOG_ERROR("Could NOT d2_selectrenderbuffer\n"); + LV_LOG_ERROR("Could NOT d2_selectrenderbuffer"); d2_closedevice(_d2_handle); } @@ -591,9 +562,7 @@ void dave2d_execute_dlist_and_flush(void) lv_result_t status; status = lv_mutex_lock(&xd2Semaphore); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif d2_s32 result; @@ -602,33 +571,25 @@ void dave2d_execute_dlist_and_flush(void) // Execute render operations result = d2_executerenderbuffer(_d2_handle, _renderbuffer, 0); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_flushframe(_d2_handle); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_selectrenderbuffer(_d2_handle, _renderbuffer); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); - while(false == _lv_ll_is_empty(&_ll_Dave2D_Tasks)) { - p_list_entry = _lv_ll_get_tail(&_ll_Dave2D_Tasks); + while(false == lv_ll_is_empty(&_ll_Dave2D_Tasks)) { + p_list_entry = lv_ll_get_tail(&_ll_Dave2D_Tasks); p_list_entry1 = *p_list_entry; p_list_entry1->state = LV_DRAW_TASK_STATE_READY; - _lv_ll_remove(&_ll_Dave2D_Tasks, p_list_entry); + lv_ll_remove(&_ll_Dave2D_Tasks, p_list_entry); lv_free(p_list_entry); } #if LV_USE_OS status = lv_mutex_unlock(&xd2Semaphore); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.h b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.h index 0058518d4..186f57a75 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d.h @@ -1,3 +1,8 @@ +/** + * @file lv_draw_dave2d.h + * + */ + #ifndef LV_DRAW_DAVE2D_H #define LV_DRAW_DAVE2D_H diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c index c703bbe61..03775387a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c @@ -16,7 +16,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc int32_t x; int32_t y; - if(!_lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return; x = 0 - u->base_unit.target_layer->buf_area.x1; y = 0 - u->base_unit.target_layer->buf_area.y1; @@ -40,9 +40,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif #if D2_RENDER_EACH_OPERATION @@ -60,9 +58,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc result = d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2, (d2_border)clipped_area.y2); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); if(360 <= LV_ABS(dsc->start_angle - dsc->end_angle)) { d2_rendercircle(u->d2_handle, @@ -131,7 +127,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc arc_area.y1 = arc_centre.y - dsc->radius; } - draw_arc = _lv_area_intersect(&clip_arc, &arc_area, &clipped_area); + draw_arc = lv_area_intersect(&clip_arc, &arc_area, &clipped_area); if(draw_arc) { @@ -145,9 +141,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc (d2_s32)(sin_end << 1), -(d2_s32)(cos_end << 1), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); if(dsc->rounded) { lv_point_t start_coord; @@ -185,9 +179,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_border.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_border.c index 70763332e..6033251df 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_border.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_border.c @@ -55,15 +55,13 @@ static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t int32_t y; bool is_common; - is_common = _lv_area_intersect(&clip_area, outer_area, u->base_unit.clip_area); + is_common = lv_area_intersect(&clip_area, outer_area, u->base_unit.clip_area); if(!is_common) return; #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif local_outer_area = *outer_area; @@ -151,9 +149,7 @@ static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } @@ -161,7 +157,6 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ const lv_area_t * orig_inner_area, int32_t rout, int32_t rin, lv_color_t color, lv_opa_t opa) { -#if LV_DRAW_SW_COMPLEX /*Get clipped draw area which is the real draw area. *It is always the same or inside `coords`*/ lv_area_t draw_area; @@ -175,14 +170,12 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ outer_area = *orig_outer_area; inner_area = *orig_inner_area; - if(!_lv_area_intersect(&draw_area, &outer_area, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&draw_area, &outer_area, u->base_unit.clip_area)) return; #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif x = 0 - u->base_unit.target_layer->buf_area.x1; @@ -292,7 +285,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ arc_area.x2 = core_area.x1; arc_area.y2 = core_area.y1; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); result = d2_renderwedge(u->d2_handle, @@ -305,9 +298,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ (d2_s32) D2_FIX16((int16_t) -1),//( 270 Degrees (d2_s32) D2_FIX16(0), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } } @@ -321,7 +312,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ arc_area.x2 = core_area.x1; arc_area.y2 = core_area.y2 + rout; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -335,9 +326,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ (d2_s32) D2_FIX16(0), //180 degrees (d2_s32) D2_FIX16(1), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } } @@ -359,7 +348,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ arc_area.x2 = core_area.x2 + rout; arc_area.y2 = core_area.y1; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -373,9 +362,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ (d2_s32) D2_FIX16(0),// 0 degrees (d2_s32) D2_FIX16(-1), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } } @@ -389,7 +376,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ arc_area.x2 = core_area.x2 + rout; arc_area.y2 = core_area.y2 + rout; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -403,9 +390,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ (d2_s32) D2_FIX16(1),// 90 degrees (d2_s32) D2_FIX16(0), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } } } @@ -422,12 +407,9 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif -#endif /*LV_DRAW_SW_COMPLEX*/ } #endif /*LV_USE_DRAW_DAVE2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c index 3f9599165..e2ffcd9fe 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c @@ -14,15 +14,13 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d lv_point_t arc_centre; - is_common = _lv_area_intersect(&draw_area, coords, u->base_unit.clip_area); + is_common = lv_area_intersect(&draw_area, coords, u->base_unit.clip_area); if(!is_common) return; #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif lv_area_copy(&coordinates, coords); @@ -63,7 +61,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d if(a1 < a2) { /* TODO */ - __BKPT(0); + LV_ASSERT(0); y0 = 0.0f;//silence the compiler warning y3 = 0.0f; @@ -81,7 +79,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d } else if(LV_GRAD_DIR_HOR == dsc->grad.dir) { /* TODO */ - __BKPT(0); + LV_ASSERT(0); float x1; float x2; @@ -99,7 +97,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d if(a1 < a2) { /* TODO */ - __BKPT(0); + LV_ASSERT(0); x0 = 0.0f;//silence the compiler warning x3 = 0.0f; @@ -153,9 +151,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d (d2_point) D2_FIX4(arc_centre.y), (d2_width) D2_FIX4(radius), (d2_width) D2_FIX4(0)); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } else { @@ -169,7 +165,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d arc_area.x2 = coordinates.x1 + radius; arc_area.y2 = coordinates.y1 + radius; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -185,9 +181,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d (d2_s32) D2_FIX16((int16_t) -1),//( 270 Degrees (d2_s32) D2_FIX16(0), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } arc_centre.x = coordinates.x2 - radius; @@ -198,7 +192,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d arc_area.x2 = coordinates.x2; arc_area.y2 = coordinates.y1 + radius; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -212,9 +206,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d (d2_s32) D2_FIX16(0),// 0 degrees (d2_s32) D2_FIX16(-1), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } arc_centre.x = coordinates.x2 - radius; @@ -225,7 +217,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d arc_area.x2 = coordinates.x2; arc_area.y2 = coordinates.y2; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -239,9 +231,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d (d2_s32) D2_FIX16(1),// 90 degrees (d2_s32) D2_FIX16(0), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } arc_centre.x = coordinates.x1 + radius; @@ -252,7 +242,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d arc_area.x2 = coordinates.x1 + radius; arc_area.y2 = coordinates.y2; - if(_lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { + if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); @@ -266,9 +256,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d (d2_s32) D2_FIX16(0), //180 degrees (d2_s32) D2_FIX16(1), flags); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } /* reset the clip rectangle */ @@ -280,27 +268,21 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d (d2_width)D2_FIX4(coordinates.y1), (d2_width)D2_FIX4(lv_area_get_width(&coordinates) - (2 * radius)), (d2_width)D2_FIX4(lv_area_get_height(&coordinates))); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_renderbox(u->d2_handle, (d2_width)D2_FIX4(coordinates.x1), (d2_width)D2_FIX4(coordinates.y1 + radius), (d2_width)D2_FIX4(radius), (d2_width)D2_FIX4(lv_area_get_height(&coordinates) - (2 * radius))); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); result = d2_renderbox(u->d2_handle, (d2_width)D2_FIX4(coordinates.x2 - radius), (d2_width)D2_FIX4(coordinates.y1 + radius), (d2_width)D2_FIX4(radius), (d2_width)D2_FIX4(lv_area_get_height(&coordinates) - (2 * radius))); - if(D2_OK != result) { - __BKPT(0); - } + LV_ASSERT(D2_OK == result); } } @@ -319,9 +301,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_image.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_image.c index 7c55b6d3d..dc001151a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_image.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_image.c @@ -40,10 +40,10 @@ void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image const lv_area_t * coords) { if(!draw_dsc->tile) { - _lv_draw_image_normal_helper((lv_draw_unit_t *)draw_unit, draw_dsc, coords, img_draw_core); + lv_draw_image_normal_helper((lv_draw_unit_t *)draw_unit, draw_dsc, coords, img_draw_core); } else { - _lv_draw_image_tiled_helper((lv_draw_unit_t *)draw_unit, draw_dsc, coords, img_draw_core); + lv_draw_image_tiled_helper((lv_draw_unit_t *)draw_unit, draw_dsc, coords, img_draw_core); } } @@ -85,9 +85,7 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif buffer_area = u->base_unit.target_layer->buf_area; @@ -225,11 +223,9 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d } else if(LV_BLEND_MODE_SUBTRACTIVE == draw_dsc->blend_mode) { /**< Subtract the foreground from the background*/ /* TODO */ - __NOP(); } else { //LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/ /* TODO */ - __NOP(); } lv_point_t p[4] = { //Points in clockwise order @@ -321,9 +317,7 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_label.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_label.c index b36b2cf8f..f5760e623 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_label.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_label.c @@ -30,7 +30,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ letter_coords = *glyph_draw_dsc->letter_coords; bool is_common; - is_common = _lv_area_intersect(&clip_area, glyph_draw_dsc->letter_coords, u->clip_area); + is_common = lv_area_intersect(&clip_area, glyph_draw_dsc->letter_coords, u->clip_area); if(!is_common) return; x = 0 - unit->base_unit.target_layer->buf_area.x1; @@ -42,9 +42,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(unit->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif #if D2_RENDER_EACH_OPERATION @@ -155,9 +153,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ #if LV_USE_OS status = lv_mutex_unlock(unit->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_line.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_line.c index b23aa8b98..ef188eb4a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_line.c @@ -6,9 +6,7 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d lv_area_t clip_line; d2_u32 mode; - d2_s32 result; lv_area_t buffer_area; - uint32_t res; lv_value_precise_t p1_x; lv_value_precise_t p1_y; lv_value_precise_t p2_x; @@ -22,15 +20,13 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d clip_line.y2 = LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width / 2; bool is_common; - is_common = _lv_area_intersect(&clip_line, &clip_line, u->base_unit.clip_area); + is_common = lv_area_intersect(&clip_line, &clip_line, u->base_unit.clip_area); if(!is_common) return; #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif buffer_area = u->base_unit.target_layer->buf_area; @@ -49,7 +45,7 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d if(dashed) { /* TODO */ - __BKPT(0); + LV_ASSERT(0); } #if D2_RENDER_EACH_OPERATION @@ -88,9 +84,7 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c index 928da567d..fe94a9a40 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c @@ -8,7 +8,7 @@ void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * u, const lv_draw_mask_rect int32_t x; int32_t y; - if(!_lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return; x = 0 - u->base_unit.target_layer->buf_area.x1; y = 0 - u->base_unit.target_layer->buf_area.y1; @@ -21,9 +21,7 @@ void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * u, const lv_draw_mask_rect #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif #ifdef D2_RENDER_EACH_OPERATION @@ -51,9 +49,7 @@ void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * u, const lv_draw_mask_rect #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif } #endif //LV_USE_DRAW_DAVE2D diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c index ad21b9c2a..502200797 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c @@ -15,14 +15,12 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d tri_area.x2 = LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); tri_area.y2 = LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - if(!_lv_area_intersect(&clipped_area, &tri_area, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&clipped_area, &tri_area, u->base_unit.clip_area)) return; #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } + LV_ASSERT(LV_RESULT_OK == status); #endif x = 0 - u->base_unit.target_layer->buf_area.x1; @@ -112,7 +110,7 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d if(a1 < a2) { /* TODO */ - __BKPT(0); + LV_ASSERT(0); y0 = 0.0f;//silence the compiler warning y3 = 0.0f; @@ -129,7 +127,7 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d } else if(LV_GRAD_DIR_HOR == dsc->bg_grad.dir) { /* TODO */ - __BKPT(0); + LV_ASSERT(0); } d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_grad.stops[0].color)); @@ -168,10 +166,7 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); - if(LV_RESULT_OK != status) { - __BKPT(0); - } - + LV_ASSERT(LV_RESULT_OK == status); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c index c62a19439..98fb80609 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c @@ -45,7 +45,7 @@ d2_color lv_draw_dave2d_lv_colour_to_d2_colour(lv_color_t color) /*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ switch(LV_COLOR_DEPTH) { case(8): - __BKPT(0); + LV_ASSERT(0); break; case(16): break; @@ -113,7 +113,7 @@ d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format) break; default: - __BKPT(0); + LV_ASSERT(0); break; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.c b/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.c index cbb555d94..c155ac114 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.c @@ -6,16 +6,16 @@ /********************* * INCLUDES *********************/ -#include "../lv_draw.h" +#include "../lv_draw_private.h" #if LV_USE_DRAW_SDL #include LV_SDL_INCLUDE_PATH -#include - #include "lv_draw_sdl.h" -#include "../../core/lv_refr.h" +#include "../../core/lv_refr_private.h" #include "../../display/lv_display_private.h" #include "../../stdlib/lv_string.h" #include "../../drivers/sdl/lv_sdl_window.h" +#include "../../misc/cache/lv_cache_entry_private.h" +#include "../../misc/lv_area_private.h" /********************* * DEFINES @@ -40,7 +40,7 @@ static void execute_drawing(lv_draw_sdl_unit_t * u); static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); -static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data); +static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data); /********************** * GLOBAL PROTOTYPES @@ -92,7 +92,12 @@ static lv_cache_compare_res_t sdl_texture_cache_compare_cb(const cache_data_t * return lhs_dsc_size > rhs_dsc_size ? 1 : -1; } - int cmp_res = memcmp(lhs->draw_dsc, rhs->draw_dsc, lhs->draw_dsc->dsc_size); + const uint8_t * left_draw_dsc = (const uint8_t *)lhs->draw_dsc; + const uint8_t * right_draw_dsc = (const uint8_t *)rhs->draw_dsc; + left_draw_dsc += sizeof(lv_draw_dsc_base_t); + right_draw_dsc += sizeof(lv_draw_dsc_base_t); + + int cmp_res = lv_memcmp(left_draw_dsc, right_draw_dsc, lhs->draw_dsc->dsc_size - sizeof(lv_draw_dsc_base_t)); if(cmp_res != 0) { return cmp_res > 0 ? 1 : -1; @@ -112,6 +117,7 @@ void lv_draw_sdl_init(void) .create_cb = (lv_cache_create_cb_t)sdl_texture_cache_create_cb, .free_cb = (lv_cache_free_cb_t)sdl_texture_cache_free_cb, }); + lv_cache_set_name(draw_sdl_unit->texture_cache, "SDL_TEXTURE"); } /********************** @@ -129,7 +135,7 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_SDL); if(t == NULL) return -1; - lv_display_t * disp = _lv_refr_get_disp_refreshing(); + lv_display_t * disp = lv_refr_get_disp_refreshing(); SDL_Texture * texture = layer_get_texture(layer); if(layer != disp->layer_head && texture == NULL) { void * buf = lv_draw_layer_alloc_buf(layer); @@ -168,24 +174,36 @@ static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) return 0; } -static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data) +static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data) { lv_draw_task_t * task = u->task_act; lv_layer_t dest_layer; lv_memzero(&dest_layer, sizeof(dest_layer)); + + int32_t texture_w = lv_area_get_width(&task->_real_area); + int32_t texture_h = lv_area_get_height(&task->_real_area); + lv_draw_buf_t draw_buf; dest_layer.draw_buf = &draw_buf; - lv_draw_buf_init(dest_layer.draw_buf, lv_area_get_width(&task->area), lv_area_get_height(&task->area), + lv_draw_buf_init(dest_layer.draw_buf, texture_w, texture_h, LV_COLOR_FORMAT_ARGB8888, LV_STRIDE_AUTO, sdl_render_buf, sizeof(sdl_render_buf)); dest_layer.color_format = LV_COLOR_FORMAT_ARGB8888; - dest_layer.buf_area = task->area; - dest_layer._clip_area = task->area; + + dest_layer.buf_area = task->_real_area; + dest_layer._clip_area = task->_real_area; + dest_layer.phy_clip_area = task->_real_area; lv_memzero(sdl_render_buf, lv_area_get_size(&dest_layer.buf_area) * 4 + 100); - lv_display_t * disp = _lv_refr_get_disp_refreshing(); + lv_display_t * disp = lv_refr_get_disp_refreshing(); + + lv_obj_t * obj = ((lv_draw_dsc_base_t *)task->draw_dsc)->obj; + bool original_send_draw_task_event = false; + if(obj) { + original_send_draw_task_event = lv_obj_has_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + lv_obj_remove_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + } - SDL_Texture * texture = NULL; switch(task->type) { case LV_DRAW_TASK_TYPE_FILL: { lv_draw_fill_dsc_t * fill_dsc = task->draw_dsc; @@ -201,7 +219,7 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data) } break; case LV_DRAW_TASK_TYPE_BORDER: { - lv_draw_border_dsc_t * border_dsc = task->draw_dsc;; + lv_draw_border_dsc_t * border_dsc = task->draw_dsc; lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); rect_dsc.base.user_data = lv_sdl_window_get_renderer(disp); @@ -214,25 +232,55 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data) lv_draw_rect(&dest_layer, &rect_dsc, &task->area); break; } + case LV_DRAW_TASK_TYPE_BOX_SHADOW: { + lv_draw_box_shadow_dsc_t * box_shadow_dsc = task->draw_dsc; + lv_draw_rect_dsc_t rect_dsc; + lv_draw_rect_dsc_init(&rect_dsc); + rect_dsc.base.user_data = lv_sdl_window_get_renderer(disp); + rect_dsc.bg_opa = LV_OPA_0; + rect_dsc.radius = box_shadow_dsc->radius; + rect_dsc.bg_color = box_shadow_dsc->color; + rect_dsc.shadow_opa = box_shadow_dsc->opa; + rect_dsc.shadow_width = box_shadow_dsc->width; + rect_dsc.shadow_spread = box_shadow_dsc->spread; + rect_dsc.shadow_offset_x = box_shadow_dsc->ofs_x; + rect_dsc.shadow_offset_y = box_shadow_dsc->ofs_y; + lv_draw_rect(&dest_layer, &rect_dsc, &task->area); + break; + } case LV_DRAW_TASK_TYPE_LABEL: { lv_draw_label_dsc_t label_dsc; - lv_draw_label_dsc_init(&label_dsc); lv_memcpy(&label_dsc, task->draw_dsc, sizeof(label_dsc)); label_dsc.base.user_data = lv_sdl_window_get_renderer(disp); lv_draw_label(&dest_layer, &label_dsc, &task->area); } break; + case LV_DRAW_TASK_TYPE_ARC: { + lv_draw_arc_dsc_t arc_dsc; + lv_memcpy(&arc_dsc, task->draw_dsc, sizeof(arc_dsc)); + arc_dsc.base.user_data = lv_sdl_window_get_renderer(disp); + lv_draw_arc(&dest_layer, &arc_dsc); + } + break; + case LV_DRAW_TASK_TYPE_LINE: { + lv_draw_line_dsc_t line_dsc; + lv_memcpy(&line_dsc, task->draw_dsc, sizeof(line_dsc)); + line_dsc.base.user_data = lv_sdl_window_get_renderer(disp); + lv_draw_line(&dest_layer, &line_dsc); + } + break; + case LV_DRAW_TASK_TYPE_TRIANGLE: { + lv_draw_triangle_dsc_t triangle_dsc; + lv_memcpy(&triangle_dsc, task->draw_dsc, sizeof(triangle_dsc)); + triangle_dsc.base.user_data = lv_sdl_window_get_renderer(disp); + lv_draw_triangle(&dest_layer, &triangle_dsc); + } + break; case LV_DRAW_TASK_TYPE_IMAGE: { - lv_draw_image_dsc_t * image_dsc = task->draw_dsc; - const char * path = image_dsc->src; - SDL_Surface * surface = IMG_Load(&path[2]); - if(surface == NULL) { - fprintf(stderr, "could not load image: %s\n", IMG_GetError()); - return false; - } - - SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp); - texture = SDL_CreateTextureFromSurface(renderer, surface); + lv_draw_image_dsc_t image_dsc; + lv_memcpy(&image_dsc, task->draw_dsc, sizeof(image_dsc)); + image_dsc.base.user_data = lv_sdl_window_get_renderer(disp); + lv_draw_image(&dest_layer, &image_dsc, &task->area); break; } default: @@ -246,36 +294,29 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data) } } - SDL_Rect rect; - rect.x = dest_layer.buf_area.x1; - rect.y = dest_layer.buf_area.y1; - rect.w = lv_area_get_width(&dest_layer.buf_area); - rect.h = lv_area_get_height(&dest_layer.buf_area); - - if(texture == NULL) { - texture = SDL_CreateTexture(lv_sdl_window_get_renderer(disp), SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STATIC, rect.w, rect.h); - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - SDL_UpdateTexture(texture, NULL, sdl_render_buf, rect.w * 4); - } - else { - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - } + SDL_Texture * texture = SDL_CreateTexture(lv_sdl_window_get_renderer(disp), SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STATIC, texture_w, texture_h); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + SDL_UpdateTexture(texture, NULL, sdl_render_buf, texture_w * 4); lv_draw_dsc_base_t * base_dsc = task->draw_dsc; - data->draw_dsc = lv_malloc(base_dsc->dsc_size); - lv_memcpy((void *)data->draw_dsc, base_dsc, base_dsc->dsc_size); - data->w = lv_area_get_width(&task->area); - data->h = lv_area_get_height(&task->area); - data->texture = texture; + cache_data->draw_dsc = lv_malloc(base_dsc->dsc_size); + lv_memcpy((void *)cache_data->draw_dsc, base_dsc, base_dsc->dsc_size); + cache_data->w = texture_w; + cache_data->h = texture_h; + cache_data->texture = texture; + + if(obj) { + lv_obj_update_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, original_send_draw_task_event); + } return true; } static void blend_texture_layer(lv_draw_sdl_unit_t * u) { - lv_display_t * disp = _lv_refr_get_disp_refreshing(); + lv_display_t * disp = lv_refr_get_disp_refreshing(); SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp); SDL_Rect clip_rect; @@ -285,13 +326,18 @@ static void blend_texture_layer(lv_draw_sdl_unit_t * u) clip_rect.h = lv_area_get_height(u->base_unit.clip_area); lv_draw_task_t * t = u->task_act; - SDL_Rect rect; - rect.x = t->area.x1; - rect.y = t->area.y1; - rect.w = lv_area_get_width(&t->area); - rect.h = lv_area_get_height(&t->area); - lv_draw_image_dsc_t * draw_dsc = t->draw_dsc; + SDL_Rect rect; + rect.w = (lv_area_get_width(&t->area) * draw_dsc->scale_x) / 256; + rect.h = (lv_area_get_height(&t->area) * draw_dsc->scale_y) / 256; + + rect.x = -draw_dsc->pivot.x; + rect.y = -draw_dsc->pivot.y; + rect.x = (rect.x * draw_dsc->scale_x) / 256; + rect.y = (rect.y * draw_dsc->scale_y) / 256; + rect.x += t->area.x1 + draw_dsc->pivot.x; + rect.y += t->area.y1 + draw_dsc->pivot.y; + lv_layer_t * src_layer = (lv_layer_t *)draw_dsc->src; SDL_Texture * src_texture = layer_get_texture(src_layer); @@ -299,21 +345,24 @@ static void blend_texture_layer(lv_draw_sdl_unit_t * u) SDL_SetTextureBlendMode(src_texture, SDL_BLENDMODE_BLEND); SDL_SetRenderTarget(renderer, layer_get_texture(u->base_unit.target_layer)); SDL_RenderSetClipRect(renderer, &clip_rect); - SDL_RenderCopy(renderer, src_texture, NULL, &rect); + + SDL_Point center = {draw_dsc->pivot.x, draw_dsc->pivot.y}; + SDL_RenderCopyEx(renderer, src_texture, NULL, &rect, draw_dsc->rotation / 10, ¢er, SDL_FLIP_NONE); + // SDL_RenderCopy(renderer, src_texture, NULL, &rect); + SDL_DestroyTexture(src_texture); SDL_RenderSetClipRect(renderer, NULL); } static void draw_from_cached_texture(lv_draw_sdl_unit_t * u) { - lv_draw_task_t * t = u->task_act; cache_data_t data_to_find; data_to_find.draw_dsc = (lv_draw_dsc_base_t *)t->draw_dsc; - data_to_find.w = lv_area_get_width(&t->area); - data_to_find.h = lv_area_get_height(&t->area); + data_to_find.w = lv_area_get_width(&t->_real_area); + data_to_find.h = lv_area_get_height(&t->_real_area); data_to_find.texture = NULL; /*user_data stores the renderer to differentiate it from SW rendered tasks. @@ -321,16 +370,29 @@ static void draw_from_cached_texture(lv_draw_sdl_unit_t * u) void * user_data_saved = data_to_find.draw_dsc->user_data; data_to_find.draw_dsc->user_data = NULL; + /*img_dsc->image_area is an absolute coordinate so it's different + *for the same image on a different position. So make it relative before using for cache. */ + if(t->type == LV_DRAW_TASK_TYPE_IMAGE) { + lv_draw_image_dsc_t * img_dsc = (lv_draw_image_dsc_t *)data_to_find.draw_dsc; + lv_area_move(&img_dsc->image_area, -t->area.x1, -t->area.y1); + } + lv_cache_entry_t * entry_cached = lv_cache_acquire_or_create(u->texture_cache, &data_to_find, u); + if(t->type == LV_DRAW_TASK_TYPE_IMAGE) { + lv_draw_image_dsc_t * img_dsc = (lv_draw_image_dsc_t *)data_to_find.draw_dsc; + lv_area_move(&img_dsc->image_area, t->area.x1, t->area.y1); + } + if(!entry_cached) { return; } + data_to_find.draw_dsc->user_data = user_data_saved; cache_data_t * data_cached = lv_cache_entry_get_data(entry_cached); SDL_Texture * texture = data_cached->texture; - lv_display_t * disp = _lv_refr_get_disp_refreshing(); + lv_display_t * disp = lv_refr_get_disp_refreshing(); SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp); lv_layer_t * dest_layer = u->base_unit.target_layer; @@ -344,52 +406,59 @@ static void draw_from_cached_texture(lv_draw_sdl_unit_t * u) SDL_SetRenderTarget(renderer, layer_get_texture(dest_layer)); - lv_draw_image_dsc_t * draw_dsc = lv_draw_task_get_image_dsc(t); - if(draw_dsc) { - lv_area_t image_area; - image_area.x1 = 0; - image_area.y1 = 0; - image_area.x2 = draw_dsc->header.w - 1; - image_area.y2 = draw_dsc->header.h - 1; + rect.x = t->_real_area.x1 - dest_layer->buf_area.x1; + rect.y = t->_real_area.y1 - dest_layer->buf_area.y1; + rect.w = data_cached->w; + rect.h = data_cached->h; - lv_area_move(&image_area, t->area.x1 - dest_layer->buf_area.x1, t->area.y1 - dest_layer->buf_area.y1); - rect.x = image_area.x1; - rect.y = image_area.y1; - rect.w = lv_area_get_width(&image_area); - rect.h = lv_area_get_height(&image_area); - - SDL_RenderSetClipRect(renderer, &clip_rect); - SDL_RenderCopy(renderer, texture, NULL, &rect); - } - else { - rect.x = t->area.x1 - dest_layer->buf_area.x1; - rect.y = t->area.y1 - dest_layer->buf_area.y1; - rect.w = lv_area_get_width(&t->area); - rect.h = lv_area_get_height(&t->area); - - SDL_RenderSetClipRect(renderer, &clip_rect); - SDL_RenderCopy(renderer, texture, NULL, &rect); - } + SDL_RenderSetClipRect(renderer, &clip_rect); + SDL_RenderCopy(renderer, texture, NULL, &rect); SDL_RenderSetClipRect(renderer, NULL); lv_cache_release(u->texture_cache, entry_cached, u); + + /*Do not cache label's with local text as the text will be freed*/ + if(t->type == LV_DRAW_TASK_TYPE_LABEL) { + lv_draw_label_dsc_t * label_dsc = t->draw_dsc; + if(label_dsc->text_local) { + lv_cache_drop(u->texture_cache, &data_to_find, NULL); + } + } } static void execute_drawing(lv_draw_sdl_unit_t * u) { lv_draw_task_t * t = u->task_act; - if(t->type == LV_DRAW_TASK_TYPE_BOX_SHADOW) return; - if(t->type == LV_DRAW_TASK_TYPE_LINE) return; - if(t->type == LV_DRAW_TASK_TYPE_TRIANGLE) return; + if(t->type == LV_DRAW_TASK_TYPE_FILL) { + lv_draw_fill_dsc_t * fill_dsc = t->draw_dsc; + if(fill_dsc->radius == 0 && fill_dsc->grad.dir == LV_GRAD_DIR_NONE) { + SDL_Rect rect; + lv_layer_t * layer = u->base_unit.target_layer; + lv_area_t fill_area = t->area; + lv_area_intersect(&fill_area, &fill_area, u->base_unit.clip_area); + + rect.x = fill_area.x1 - layer->buf_area.x1; + rect.y = fill_area.y1 - layer->buf_area.y1; + rect.w = lv_area_get_width(&fill_area); + rect.h = lv_area_get_height(&fill_area); + lv_display_t * disp = lv_refr_get_disp_refreshing(); + SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, fill_dsc->color.red, fill_dsc->color.green, fill_dsc->color.blue, fill_dsc->opa); + SDL_RenderSetClipRect(renderer, NULL); + SDL_RenderFillRect(renderer, &rect); + return; + } + } if(t->type == LV_DRAW_TASK_TYPE_LAYER) { blend_texture_layer(u); + return; } - else { - draw_from_cached_texture(u); - } + + draw_from_cached_texture(u); } static SDL_Texture * layer_get_texture(lv_layer_t * layer) diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.h b/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.h index b394ecca8..d9b061de1 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sdl/lv_draw_sdl.h @@ -22,6 +22,12 @@ extern "C" { #include "../../misc/lv_color.h" #include "../../display/lv_display.h" #include "../../osal/lv_os.h" +#include "../../draw/lv_draw_label.h" +#include "../../draw/lv_draw_rect.h" +#include "../../draw/lv_draw_arc.h" +#include "../../draw/lv_draw_image.h" +#include "../../draw/lv_draw_triangle.h" +#include "../../draw/lv_draw_line.h" /********************* * DEFINES @@ -38,14 +44,6 @@ typedef struct { lv_cache_t * texture_cache; } lv_draw_sdl_unit_t; -#if LV_DRAW_SW_SHADOW_CACHE_SIZE -typedef struct { - uint8_t cache[LV_DRAW_SW_SHADOW_CACHE_SIZE * LV_DRAW_SW_SHADOW_CACHE_SIZE]; - int32_t cache_size; - int32_t cache_r; -} lv_draw_sw_shadow_cache_t; -#endif - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/arm2d/lv_draw_sw_arm2d.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/arm2d/lv_draw_sw_arm2d.h index 3f16382f7..77c6cc4de 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/arm2d/lv_draw_sw_arm2d.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/arm2d/lv_draw_sw_arm2d.h @@ -17,6 +17,7 @@ extern "C" { *********************/ #include "../../../lv_conf_internal.h" +#include "../../../misc/lv_area_private.h" #if LV_USE_DRAW_ARM2D_SYNC @@ -37,7 +38,7 @@ extern "C" { *********************/ #ifndef LV_DRAW_SW_RGB565_SWAP #define LV_DRAW_SW_RGB565_SWAP(__buf_ptr, __buf_size_px) \ - _lv_draw_sw_rgb565_swap_helium((__buf_ptr), (__buf_size_px)) + lv_draw_sw_rgb565_swap_helium((__buf_ptr), (__buf_size_px)) #endif #ifndef LV_DRAW_SW_IMAGE @@ -49,7 +50,7 @@ extern "C" { __blend_area, \ __draw_unit, \ __draw_dsc) \ - _lv_draw_sw_image_helium( (__transformed), \ + lv_draw_sw_image_helium( (__transformed), \ (__cf), \ (uint8_t *)(__src_buf), \ (__img_coords), \ @@ -61,7 +62,7 @@ extern "C" { #ifndef LV_DRAW_SW_RGB565_RECOLOR #define LV_DRAW_SW_RGB565_RECOLOR(__src_buf, __blend_area, __color, __opa) \ - _lv_draw_sw_image_recolor_rgb565( (__src_buf), \ + lv_draw_sw_image_recolor_rgb565( (__src_buf), \ &(__blend_area), \ (__color), \ (__opa)) @@ -73,7 +74,7 @@ extern "C" { __color, \ __opa, \ __cf) \ - _lv_draw_sw_image_recolor_rgb888( (__src_buf), \ + lv_draw_sw_image_recolor_rgb888( (__src_buf), \ &(__blend_area), \ (__color), \ (__opa), \ @@ -161,14 +162,14 @@ extern void arm_2d_helper_swap_rgb16(uint16_t * phwBuffer, uint32_t wCount); } \ } while(0); -static inline lv_result_t _lv_draw_sw_rgb565_swap_helium(void * buf, uint32_t buf_size_px) +static inline lv_result_t lv_draw_sw_rgb565_swap_helium(void * buf, uint32_t buf_size_px) { arm_2d_helper_swap_rgb16((uint16_t *)buf, buf_size_px); return LV_RESULT_OK; } -static inline lv_result_t _lv_draw_sw_image_helium( - bool is_transform, +static inline lv_result_t lv_draw_sw_image_helium( + bool is_transform, lv_color_format_t src_cf, const uint8_t *src_buf, const lv_area_t * coords, @@ -217,7 +218,7 @@ static inline lv_result_t _lv_draw_sw_image_helium( /* ------------- prepare parameters for arm-2d APIs - BEGIN --------- */ lv_area_t blend_area; - if(!_lv_area_intersect(&blend_area, des_area, draw_unit->clip_area)) { + if(!lv_area_intersect(&blend_area, des_area, draw_unit->clip_area)) { break; } @@ -241,17 +242,17 @@ static inline lv_result_t _lv_draw_sw_image_helium( // des_size.iWidth = (int16_t)des_w; // des_size.iHeight = (int16_t)des_h; // } while(0); -// +// // arm_2d_size_t copy_size = { // .iWidth = MIN(des_size.iWidth, src_size.iWidth), // .iHeight = MIN(des_size.iHeight, src_size.iHeight), // }; -// +// // int32_t des_stride = lv_draw_buf_width_to_stride( -// lv_area_get_width(&layer->buf_area), +// lv_area_get_width(&layer->buf_area), // des_cf); // uint8_t *des_buf_moved = (uint8_t *)lv_draw_layer_go_to_xy( -// layer, +// layer, // blend_area.x1 - layer->buf_area.x1, // blend_area.y1 - layer->buf_area.y1); uint8_t *des_buf = (uint8_t *)lv_draw_layer_go_to_xy(layer, 0, 0); @@ -524,7 +525,7 @@ static inline lv_result_t _lv_draw_sw_image_helium( return result; } -static inline lv_result_t _lv_draw_sw_image_recolor_rgb565( +static inline lv_result_t lv_draw_sw_image_recolor_rgb565( const uint8_t *src_buf, const lv_area_t * blend_area, lv_color_t color, @@ -548,7 +549,7 @@ static inline lv_result_t _lv_draw_sw_image_recolor_rgb565( return LV_RESULT_OK; } -static inline lv_result_t _lv_draw_sw_image_recolor_rgb888( +static inline lv_result_t lv_draw_sw_image_recolor_rgb888( const uint8_t *src_buf, const lv_area_t * blend_area, lv_color_t color, diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/arm2d/lv_blend_arm2d.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/arm2d/lv_blend_arm2d.h index 5640bde34..0eb29b853 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/arm2d/lv_blend_arm2d.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/arm2d/lv_blend_arm2d.h @@ -29,168 +29,178 @@ extern "C" { #elif defined(__IS_COMPILER_GCC__) #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" #endif + + +#if ARM_2D_VERSION < 10106ul +#error Please upgrade to Arm-2D v1.1.6 or above +#endif + +#ifndef LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF +#define LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF 1 +#endif + /********************* * DEFINES *********************/ #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ - _lv_color_blend_to_rgb565_arm2d(dsc) + lv_color_blend_to_rgb565_arm2d(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ - _lv_color_blend_to_rgb565_with_opa_arm2d(dsc) + lv_color_blend_to_rgb565_with_opa_arm2d(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ - _lv_color_blend_to_rgb565_with_mask_arm2d(dsc) + lv_color_blend_to_rgb565_with_mask_arm2d(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_color_blend_to_rgb565_mix_mask_opa_arm2d(dsc) + lv_color_blend_to_rgb565_mix_mask_opa_arm2d(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_arm2d(dsc) + lv_rgb565_blend_normal_to_rgb565_arm2d(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(dsc) + lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(dsc) + lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc) + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_arm2d(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_arm2d(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_arm2d(dsc) + lv_argb8888_blend_normal_to_rgb565_arm2d(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_with_opa_arm2d(dsc) + lv_argb8888_blend_normal_to_rgb565_with_opa_arm2d(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_with_mask_arm2d(dsc) + lv_argb8888_blend_normal_to_rgb565_with_mask_arm2d(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc) + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_arm2d(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_arm2d(dsc, dst_px_size) + lv_color_blend_to_rgb888_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_with_opa_arm2d(dsc, dst_px_size) + lv_color_blend_to_rgb888_with_opa_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_with_mask_arm2d(dsc, dst_px_size) + lv_color_blend_to_rgb888_with_mask_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) + lv_color_blend_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_arm2d(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_arm2d(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_arm2d(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_arm2d(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_with_opa_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d(dsc, dst_px_size) #endif /********************** @@ -201,7 +211,7 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -static inline lv_result_t _lv_color_blend_to_rgb565_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); @@ -212,7 +222,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_arm2d(_lv_draw_sw_blend_fill return LV_RESULT_OK; } -static inline lv_result_t _lv_color_blend_to_rgb565_with_opa_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); @@ -224,7 +234,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_with_opa_arm2d(_lv_draw_sw_b return LV_RESULT_OK; } -static inline lv_result_t _lv_color_blend_to_rgb565_with_mask_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); @@ -237,7 +247,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_with_mask_arm2d(_lv_draw_sw_ return LV_RESULT_OK; } -static inline lv_result_t _lv_color_blend_to_rgb565_mix_mask_opa_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t stride = (dsc->dest_stride) / sizeof(uint16_t); @@ -251,7 +261,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_mix_mask_opa_arm2d(_lv_draw_ return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; @@ -265,7 +275,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_arm2d(_lv_draw_sw_bl return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); @@ -279,7 +289,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_opa_arm2d(_lv_d return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); @@ -295,31 +305,26 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_mask_arm2d(_lv_ return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); int16_t src_stride = dsc->src_stride / sizeof(uint16_t); - __arm_2d_impl_gray8_colour_filling_with_opacity((uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - 0x00, - 255 - dsc->opa); - - __arm_2d_impl_rgb565_src_msk_copy((uint16_t *)dsc->src_buf, - src_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - (uint16_t *)dsc->dest_buf, - des_stride, - &draw_size); + __arm_2d_impl_rgb565_tile_copy_with_src_mask_and_opacity((uint16_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { if(src_px_size == 3) { return LV_RESULT_INVALID; @@ -338,7 +343,48 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_arm2d(_lv_draw_sw_bl return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + if(src_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); + if(NULL == tmp_buf) { + return LV_RESULT_INVALID; + } + +#if !LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF + __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)tmp_buf, + des_stride, + &draw_size); + + __arm_2d_impl_rgb565_tile_copy_opacity(tmp_buf, + des_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#else + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#endif + lv_free(tmp_buf); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { if(src_px_size == 3) { @@ -354,39 +400,7 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_opa_arm2d(_lv_d return LV_RESULT_INVALID; } - __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, - src_stride, - (uint16_t *)tmp_buf, - des_stride, - &draw_size); - - __arm_2d_impl_rgb565_tile_copy_opacity(tmp_buf, - des_stride, - (uint16_t *)dsc->dest_buf, - des_stride, - &draw_size, - dsc->opa); - - lv_free(tmp_buf); - return LV_RESULT_OK; -} - -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - if(src_px_size == 3) { - return LV_RESULT_INVALID; - } - - arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; - int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); - int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - - uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); - if(NULL == tmp_buf) { - return LV_RESULT_INVALID; - } - +#if !LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, src_stride, (uint16_t *)tmp_buf, @@ -401,13 +415,23 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_mask_arm2d(_lv_ (uint16_t *)dsc->dest_buf, des_stride, &draw_size); +#else + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); +#endif lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { if(src_px_size == 3) { return LV_RESULT_INVALID; @@ -422,211 +446,107 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_arm2d(_ return LV_RESULT_INVALID; } +#if !LV_ARM2D_XRGB888_ALPHA_ALWAYS_FF __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, src_stride, (uint16_t *)tmp_buf, des_stride, &draw_size); - __arm_2d_impl_gray8_colour_filling_with_opacity((uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - 0x00, - 255 - dsc->opa); - - __arm_2d_impl_rgb565_src_msk_copy(tmp_buf, - des_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - (uint16_t *)dsc->dest_buf, - des_stride, - &draw_size); + __arm_2d_impl_rgb565_tile_copy_with_src_mask_and_opacity(tmp_buf, + des_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#else + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); +#endif lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); - if(NULL == tmp_buf) { - return LV_RESULT_INVALID; - } + __arm_2d_impl_ccca8888_to_rgb565((uint32_t *)dsc->src_buf, + src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); - __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, - src_stride, - (uint16_t *)tmp_buf, - des_stride, - &draw_size); - - __arm_2d_impl_rgb565_src_chn_msk_copy(tmp_buf, - des_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - (uint16_t *)dsc->dest_buf, - des_stride, - &draw_size); - - lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); - if(NULL == tmp_buf) { - return LV_RESULT_INVALID; - } - uint8_t * tmp_msk = (uint8_t *)lv_malloc(des_stride * dsc->dest_h); - if(NULL == tmp_msk) { - lv_free(tmp_buf); - return LV_RESULT_INVALID; - } - - /* get rgb565 */ - __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, - src_stride, - (uint16_t *)tmp_buf, - des_stride, - &draw_size); - - lv_memzero(tmp_msk, des_stride * dsc->dest_h); - - /* get mask */ - __arm_2d_impl_gray8_colour_filling_channel_mask_opacity(tmp_msk, - des_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_opacity((uint32_t *)dsc->src_buf, src_stride, + (uint16_t *)dsc->dest_buf, + des_stride, &draw_size, - 0xFF, dsc->opa); - __arm_2d_impl_rgb565_src_msk_copy(tmp_buf, - des_stride, - tmp_msk, - des_stride, - &draw_size, - (uint16_t *)dsc->dest_buf, - des_stride, - &draw_size); - - lv_free(tmp_msk); - lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_mask_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); - if(NULL == tmp_buf) { - return LV_RESULT_INVALID; - } - uint8_t * tmp_msk = (uint8_t *)lv_malloc(des_stride * dsc->dest_h); - if(NULL == tmp_msk) { - lv_free(tmp_buf); - return LV_RESULT_INVALID; - } + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size); - /* get rgb565 */ - __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, - src_stride, - (uint16_t *)tmp_buf, - des_stride, - &draw_size); - - lv_memzero(tmp_msk, des_stride * dsc->dest_h); - - /* get mask */ - __arm_2d_impl_gray8_colour_filling_channel_mask(tmp_msk, - des_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - 0xFF); - - __arm_2d_impl_rgb565_masks_copy(tmp_buf, - des_stride, - tmp_msk, - des_stride, - &draw_size, - (uint16_t *)dsc->dest_buf, - des_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - &draw_size); - - lv_free(tmp_msk); - lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc) { arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; int16_t des_stride = dsc->dest_stride / sizeof(uint16_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - uint16_t * tmp_buf = (uint16_t *)lv_malloc(dsc->dest_stride * dsc->dest_h); - if(NULL == tmp_buf) { - return LV_RESULT_INVALID; - } - uint8_t * tmp_msk = (uint8_t *)lv_malloc(des_stride * dsc->dest_h); - if(NULL == tmp_msk) { - lv_free(tmp_buf); - return LV_RESULT_INVALID; - } + __arm_2d_impl_ccca8888_tile_copy_to_rgb565_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint16_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); - /* get rgb565 */ - __arm_2d_impl_cccn888_to_rgb565((uint32_t *)dsc->src_buf, - src_stride, - (uint16_t *)tmp_buf, - des_stride, - &draw_size); - - lv_memzero(tmp_msk, des_stride * dsc->dest_h); - - /* get mask */ - __arm_2d_impl_gray8_colour_filling_channel_mask_opacity(tmp_msk, - des_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - 0xFF, - dsc->opa); - - __arm_2d_impl_rgb565_masks_copy(tmp_buf, - des_stride, - tmp_msk, - des_stride, - &draw_size, - (uint16_t *)dsc->dest_buf, - des_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - &draw_size); - - lv_free(tmp_msk); - lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_color_blend_to_rgb888_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) { if(dst_px_size == 3) { return LV_RESULT_INVALID; @@ -641,8 +561,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_arm2d(_lv_draw_sw_blend_fill } -static inline lv_result_t _lv_color_blend_to_rgb888_with_opa_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { return LV_RESULT_INVALID; @@ -658,8 +578,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_with_opa_arm2d(_lv_draw_sw_b return LV_RESULT_OK; } -static inline lv_result_t _lv_color_blend_to_rgb888_with_mask_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -677,8 +597,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_with_mask_arm2d(_lv_draw_sw_ return LV_RESULT_OK; } -static inline lv_result_t _lv_color_blend_to_rgb888_mix_mask_opa_arm2d(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -697,8 +617,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_mix_mask_opa_arm2d(_lv_draw_ return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -719,8 +639,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_arm2d(_lv_draw_sw_bl } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -754,8 +674,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_opa_arm2d(_lv_d return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -790,8 +710,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_mask_arm2d(_lv_ return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -813,28 +733,23 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_arm2d(_ des_stride, &draw_size); - __arm_2d_impl_gray8_colour_filling_with_opacity((uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - 0x00, - 255 - dsc->opa); - - __arm_2d_impl_cccn888_src_msk_copy(tmp_buf, - des_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - (uint32_t *)dsc->dest_buf, - des_stride, - &draw_size); + __arm_2d_impl_cccn888_tile_copy_with_src_mask_and_opacity(tmp_buf, + des_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); lv_free(tmp_buf); return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, + uint32_t src_px_size) { if((dst_px_size == 3) || (src_px_size == 3)) { return LV_RESULT_INVALID; @@ -853,8 +768,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_arm2d(_lv_draw_sw_bl return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) { if((dst_px_size == 3) || (src_px_size == 3)) { return LV_RESULT_INVALID; @@ -874,8 +789,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_opa_arm2d(_lv_d return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) { if((dst_px_size == 3) || (src_px_size == 3)) { return LV_RESULT_INVALID; @@ -896,8 +811,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_mask_arm2d(_lv_ return LV_RESULT_OK; } -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) { if((dst_px_size == 3) || (src_px_size == 3)) { return LV_RESULT_INVALID; @@ -907,25 +822,20 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_arm2d(_ int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - __arm_2d_impl_gray8_colour_filling_with_opacity((uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - 0x00, - 255 - dsc->opa); - - __arm_2d_impl_cccn888_src_msk_copy((uint32_t *)dsc->src_buf, - src_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - (uint32_t *)dsc->dest_buf, - des_stride, - &draw_size); + __arm_2d_impl_cccn888_tile_copy_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { @@ -936,61 +846,39 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_arm2d(_lv_draw_sw_ int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - __arm_2d_impl_cccn888_src_chn_msk_copy((uint32_t *)dsc->src_buf, - src_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - (uint32_t *)dsc->dest_buf, - des_stride, - &draw_size); + __arm_2d_impl_ccca8888_to_cccn888((uint32_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + if(dst_px_size == 3) { + return LV_RESULT_INVALID; + } + + arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; + int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); + int16_t src_stride = dsc->src_stride / sizeof(uint32_t); + + __arm_2d_impl_ccca8888_tile_copy_to_cccn888_with_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); + + return LV_RESULT_OK; +} + +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { - if(dst_px_size == 3) { - return LV_RESULT_INVALID; - } - - arm_2d_size_t draw_size = {dsc->dest_w, dsc->dest_h}; - int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); - int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - - uint8_t * tmp_msk = (uint8_t *)lv_malloc(des_stride * dsc->dest_h); - if(NULL == tmp_msk) { - return LV_RESULT_INVALID; - } - - lv_memzero(tmp_msk, des_stride * dsc->dest_h); - - /* get mask */ - __arm_2d_impl_gray8_colour_filling_channel_mask_opacity(tmp_msk, - des_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - 0xFF, - dsc->opa); - - __arm_2d_impl_cccn888_src_msk_copy((uint32_t *)dsc->src_buf, - src_stride, - tmp_msk, - des_stride, - &draw_size, - (uint32_t *)dsc->dest_buf, - des_stride, - &draw_size); - - lv_free(tmp_msk); - return LV_RESULT_OK; -} - -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ if(dst_px_size == 3) { return LV_RESULT_INVALID; @@ -1000,23 +888,20 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_mask_arm2d(_l int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - __arm_2d_impl_cccn888_src_chn_msk_des_msk_copy((uint32_t *)dsc->src_buf, - src_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - (uint32_t *)dsc->dest_buf, - des_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - &draw_size); + __arm_2d_impl_ccca8888_tile_copy_to_cccn888_with_src_mask((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size); return LV_RESULT_OK; } -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { if(dst_px_size == 3) { return LV_RESULT_INVALID; @@ -1026,23 +911,15 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_arm2d int16_t des_stride = dsc->dest_stride / sizeof(uint32_t); int16_t src_stride = dsc->src_stride / sizeof(uint32_t); - __arm_2d_impl_gray8_colour_filling_with_opacity((uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - 0x00, - 255 - dsc->opa); - - __arm_2d_impl_cccn888_src_chn_msk_des_msk_copy((uint32_t *)dsc->src_buf, - src_stride, - (uint32_t *)((uintptr_t)(dsc->src_buf) + 3), - src_stride, - &draw_size, - (uint32_t *)dsc->dest_buf, - des_stride, - (uint8_t *)dsc->mask_buf, - dsc->mask_stride, - &draw_size, - &draw_size); + __arm_2d_impl_ccca8888_tile_copy_to_cccn888_with_src_mask_and_opacity((uint32_t *)dsc->src_buf, + src_stride, + (uint8_t *)dsc->mask_buf, + dsc->mask_stride, + &draw_size, + (uint32_t *)dsc->dest_buf, + des_stride, + &draw_size, + dsc->opa); return LV_RESULT_OK; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.S b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.S index ec054e87e..4304d7406 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.S +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.S @@ -17,7 +17,6 @@ reciprocal: .text .syntax unified -.altmacro .p2align 2 TMP .req r0 @@ -32,118 +31,158 @@ MASK_STRIDE .req r8 H .req r9 OPA .req r10 RCP .req r11 -S_B .qn q0 -S_G .qn q1 -S_R .qn q2 -S_A .qn q3 -D_B .qn q4 -D_G .qn q5 -D_R .qn q6 -D_A .qn q7 -N .qn q0 -V .qn q1 -R .qn q2 -L .qn q4 -.macro conv_888_to_565 reg - vsri.8 reg&_R, reg&_G, #5 - vshr.u8 reg&_G, reg&_G, #2 - vshr.u8 reg&_B, reg&_B, #3 - vsli.8 reg&_B, reg&_G, #5 -.endm +S_B .req q0 +S_G .req q1 +S_R .req q2 +S_A .req q3 +D_B .req q4 +D_G .req q5 +D_R .req q6 +D_A .req q7 +N .req q0 +V .req q1 +R .req q2 +L .req q4 +S_565 .req q0 +D_565 .req q1 +S_L .req q2 +D_L .req q4 +D_T .req q5 +BITMASK .req q6 -@ 16bpp is stored on R & B -.macro ldst op, bpp, mem, reg, areg, cvt, alt_index, wb -.if bpp == 0 -.if (reg == S) || (wb&1) @ exclude reg == D and ! - ldr TMP, [mem&_ADDR] - vdup.8 reg&_B, TMP +.macro ldst st, op, bpp, mem, reg, areg, cvt, alt_index, wb, aligned +.if \bpp == 0 +.if \cvt + ldr TMP, [\mem\()_ADDR] + bfi TMP, TMP, #2, #8 + bfi TMP, TMP, #3, #16 + lsr TMP, TMP, #8 + vdup.16 \reg\()_565, TMP +.else + ldr TMP, [\mem\()_ADDR] + vdup.8 \reg\()_B, TMP lsr TMP, #8 - vdup.8 reg&_G, TMP + vdup.8 \reg\()_G, TMP lsr TMP, #8 - vdup.8 reg&_R, TMP -.if cvt && (wb&1) - conv_888_to_565 reg + vdup.8 \reg\()_R, TMP .endif -.endif -.elseif bpp == 8 - v&op&rb.8 reg&_A, [mem&_ADDR], #16 -.elseif bpp == 16 -.if cvt && (op == st) - conv_888_to_565 reg -.endif -.if alt_index - v&op&rb.8 reg&_B, [mem&_ADDR, areg&_A] - add mem&_ADDR, #1 - v&op&rb.8 reg&_R, [mem&_ADDR, areg&_A] +.elseif \bpp == 8 +.if \cvt + v\op\()rb.u16 \reg\()_A, [\mem\()_ADDR], #8 .else - v&op&rb.8 reg&_B, [mem&_ADDR, reg&_A] - add mem&_ADDR, #1 - v&op&rb.8 reg&_R, [mem&_ADDR, reg&_A] + v\op\()rb.8 \reg\()_A, [\mem\()_ADDR], #16 .endif -.if cvt && (op == ld) - vshl.u8 reg&_G, reg&_R, #5 - vsri.u8 reg&_G, reg&_B, #3 - vshl.u8 reg&_B, reg&_B, #3 - vsri.u8 reg&_R, reg&_R, #5 - vsri.u8 reg&_G, reg&_G, #6 - vsri.u8 reg&_B, reg&_B, #5 +.elseif \bpp == 16 +.if \cvt +.if \st + vsri.8 \reg\()_R, \reg\()_G, #5 + vshr.u8 \reg\()_G, \reg\()_G, #2 + vshr.u8 \reg\()_B, \reg\()_B, #3 + vsli.8 \reg\()_B, \reg\()_G, #5 .endif -.if wb&0 - add mem&_ADDR, #31 +.if \alt_index + v\op\()rb.8 \reg\()_B, [\mem\()_ADDR, S_B] + v\op\()rb.8 \reg\()_R, [\mem\()_ADDR, S_G] .else - sub mem&_ADDR, #1 + v\op\()rb.8 \reg\()_B, [\mem\()_ADDR, \reg\()_A] + add \mem\()_ADDR, #1 + v\op\()rb.8 \reg\()_R, [\mem\()_ADDR, \reg\()_A] .endif -.elseif bpp >= 24 -.if alt_index || (bpp >= 31) - v&op&rb.8 reg&_B, [mem&_ADDR, areg&_A] - add mem&_ADDR, #1 - v&op&rb.8 reg&_G, [mem&_ADDR, areg&_A] - add mem&_ADDR, #1 - v&op&rb.8 reg&_R, [mem&_ADDR, areg&_A] +.if \st == 0 + vshl.u8 \reg\()_G, \reg\()_R, #5 + vsri.u8 \reg\()_G, \reg\()_B, #3 + vshl.u8 \reg\()_B, \reg\()_B, #3 + vsri.u8 \reg\()_R, \reg\()_R, #5 + vsri.u8 \reg\()_G, \reg\()_G, #6 + vsri.u8 \reg\()_B, \reg\()_B, #5 +.endif +.ifc \wb, ! +.if \alt_index + add \mem\()_ADDR, #32 .else - v&op&rb.8 reg&_B, [mem&_ADDR, reg&_A] - add mem&_ADDR, #1 - v&op&rb.8 reg&_G, [mem&_ADDR, reg&_A] - add mem&_ADDR, #1 - v&op&rb.8 reg&_R, [mem&_ADDR, reg&_A] + add \mem\()_ADDR, #31 .endif -.if (bpp == 32) || (bpp == 31) && (op == st) - add mem&_ADDR, #1 - v&op&rb.8 reg&_A, [mem&_ADDR, areg&_A] +.elseif \alt_index == 0 + sub \mem\()_ADDR, #1 .endif -.if wb&0 - .if bpp == 24 - add mem&_ADDR, #46 - .elseif (bpp == 32) || (bpp == 31) && (op == st) - add mem&_ADDR, #61 +.else @ cvt +.ifc \wb, ! + v\op\()rh.16 \reg\()_565, [\mem\()_ADDR], #16 +.else + v\op\()rh.16 \reg\()_565, [\mem\()_ADDR] +.endif +.endif +.elseif \bpp == 24 +.if \alt_index == 1 + v\op\()rb.8 \reg\()_B, [\mem\()_ADDR, S_B] + v\op\()rb.8 \reg\()_G, [\mem\()_ADDR, S_G] + v\op\()rb.8 \reg\()_R, [\mem\()_ADDR, S_R] +.elseif \alt_index == 2 + v\op\()rb.8 \reg\()_B, [\mem\()_ADDR, S_R] + v\op\()rb.8 \reg\()_G, [\mem\()_ADDR, S_A] + v\op\()rb.8 \reg\()_R, [\mem\()_ADDR, D_A] +.else + v\op\()rb.8 \reg\()_B, [\mem\()_ADDR, \reg\()_A] + add \mem\()_ADDR, #1 + v\op\()rb.8 \reg\()_G, [\mem\()_ADDR, \reg\()_A] + add \mem\()_ADDR, #1 + v\op\()rb.8 \reg\()_R, [\mem\()_ADDR, \reg\()_A] +.endif +.ifc \wb, ! +.if \alt_index + add \mem\()_ADDR, #48 +.else + add \mem\()_ADDR, #46 +.endif +.elseif \alt_index == 0 + sub \mem\()_ADDR, #2 +.endif +.elseif \aligned + v\op\()40.8 {\reg\()_B, \reg\()_G, \reg\()_R, \reg\()_A}, [\mem\()_ADDR] + v\op\()41.8 {\reg\()_B, \reg\()_G, \reg\()_R, \reg\()_A}, [\mem\()_ADDR] + v\op\()42.8 {\reg\()_B, \reg\()_G, \reg\()_R, \reg\()_A}, [\mem\()_ADDR] + v\op\()43.8 {\reg\()_B, \reg\()_G, \reg\()_R, \reg\()_A}, [\mem\()_ADDR]\wb +.else + v\op\()rb.8 \reg\()_B, [\mem\()_ADDR, \areg\()_A] + add \mem\()_ADDR, #1 + v\op\()rb.8 \reg\()_G, [\mem\()_ADDR, \areg\()_A] + add \mem\()_ADDR, #1 + v\op\()rb.8 \reg\()_R, [\mem\()_ADDR, \areg\()_A] +.if (\bpp == 32) || (\bpp == 31) && \st + add \mem\()_ADDR, #1 + v\op\()rb.8 \reg\()_A, [\mem\()_ADDR, \areg\()_A] +.endif +.ifc \wb, ! + .if (\bpp == 32) || (\bpp == 31) && \st + add \mem\()_ADDR, #61 .else - add mem&_ADDR, #62 + add \mem\()_ADDR, #62 .endif .else - .if (bpp == 32) || (bpp == 31) && (op == st) - sub mem&_ADDR, #3 + .if (\bpp == 32) || (\bpp == 31) && \st + sub \mem\()_ADDR, #3 .else - sub mem&_ADDR, #2 + sub \mem\()_ADDR, #2 .endif .endif .endif .endm -.macro load_index bpp, reg, areg -.if bpp > 0 +.macro load_index bpp, reg, areg, aligned +.if (\bpp > 0) && ((\bpp < 31) || (\aligned == 0)) mov TMP, #0 -.endif -.if bpp == 8 - vidup.u8 reg&_A, TMP, #1 -.elseif bpp == 16 - vidup.u8 reg&_A, TMP, #2 -.elseif bpp == 24 - vidup.u8 reg&_A, TMP, #1 +.if \bpp == 8 + vidup.u8 \reg\()_A, TMP, #1 +.elseif \bpp == 16 + vidup.u8 \reg\()_A, TMP, #2 +.elseif \bpp == 24 + vidup.u8 \reg\()_A, TMP, #1 mov TMP, #3 - vmul.i8 reg&_A, reg&_A, TMP -.elseif bpp >= 31 - vidup.u8 areg&_A, TMP, #4 + vmul.u8 \reg\()_A, \reg\()_A, TMP +.else + vidup.u8 \areg\()_A, TMP, #4 +.endif .endif .endm @@ -153,89 +192,227 @@ L .qn q4 ldr DST_H, [r0, #12] ldr DST_STRIDE, [r0, #16] ldr SRC_ADDR, [r0, #20] -.if src_bpp > 0 +.if \src_bpp > 0 ldr SRC_STRIDE, [r0, #24] .endif -.if mask +.if \mask ldr MASK_ADDR, [r0, #28] ldr MASK_STRIDE, [r0, #32] .endif -.if opa +.if \opa ldr OPA, [r0] -.else - mov OPA, #0xFF .endif +.if (\src_bpp <= 16) && (\dst_bpp == 16) +.if \opa || \mask + mov TMP, #0xF81F + movt TMP, #0x7E0 + vdup.32 BITMASK, TMP +.endif + add TMP, DST_W, #0x7 + bic TMP, TMP, #0x7 +.else add TMP, DST_W, #0xF bic TMP, TMP, #0xF -.if dst_bpp == 32 +.endif +.if \dst_bpp == 32 ldr RCP, =(reciprocal - 8) .endif -.if dst_bpp == 16 +.if \dst_bpp == 16 sub DST_STRIDE, DST_STRIDE, TMP, lsl #1 -.elseif dst_bpp == 24 +.elseif \dst_bpp == 24 sub DST_STRIDE, DST_STRIDE, TMP sub DST_STRIDE, DST_STRIDE, TMP, lsl #1 -.elseif dst_bpp >= 31 +.elseif \dst_bpp >= 31 sub DST_STRIDE, DST_STRIDE, TMP, lsl #2 .endif -.if mask +.if \mask sub MASK_STRIDE, MASK_STRIDE, TMP .endif -.if src_bpp == 0 - .if mask || opa - ldst ld, src_bpp, SRC, S, D, 0, 0 +.if \src_bpp == 0 +.if \mask || \opa + .if \dst_bpp > 16 + ldst 0, ld, \src_bpp, SRC, S, D, 0, 0 vmov.u8 S_A, #0xFF .else - ldst ld, src_bpp, SRC, D, S, (dst_bpp == 16), 0 - vmov.u8 D_A, #0xFF + ldst 0, ld, \src_bpp, SRC, S, D, 1, 0 + vmovlb.u16 S_L, S_565 + vsli.32 S_L, S_L, #16 + vand S_L, S_L, BITMASK .endif .else - .if src_bpp == 16 + .if \dst_bpp > 16 + ldst 0, ld, \src_bpp, SRC, D, S, 0, 0 + .else + ldst 0, ld, \src_bpp, SRC, D, S, 1, 0 + .endif +.endif +.else + .if \src_bpp == 16 sub SRC_STRIDE, SRC_STRIDE, TMP, lsl #1 - .elseif src_bpp == 24 + .elseif \src_bpp == 24 sub SRC_STRIDE, SRC_STRIDE, TMP sub SRC_STRIDE, SRC_STRIDE, TMP, lsl #1 - .elseif src_bpp >= 31 + .elseif \src_bpp >= 31 sub SRC_STRIDE, SRC_STRIDE, TMP, lsl #2 .endif .endif -.if (src_bpp < 32) && (mask == 0) && (opa == 0) - .if (src_bpp == 31) || (dst_bpp < 31) - load_index src_bpp, S, S - .endif - .if (dst_bpp < 31) && (dst_bpp != src_bpp) - load_index dst_bpp, D, D - .else - load_index dst_bpp, S, S - vmov.u8 D_A, #0xFF - .endif +.if (\src_bpp < 32) && (\mask == 0) && (\opa == 0) && !((\src_bpp <= 16) && (\dst_bpp == 16)) +@ 16 to 31/32 or reverse: index @ q0, q1 +@ 24 to 31/32 or reverse: index @ q0, q1, q2 +@ 16 to 24 or reverse: 16 index @ q0, q1, 24 index @ q2, q3, q7 +@ 31 to 31/32: index @ q3 (tail only) + mov TMP, #0 +.if (\src_bpp == 16) || (\dst_bpp == 16) + vidup.u8 S_B, TMP, #2 + mov TMP, #1 + vadd.u8 S_G, S_B, TMP +.if (\src_bpp == 24) || (\dst_bpp == 24) + vshl.u8 S_R, S_B, #1 + vadd.u8 S_R, S_R, S_B + vshr.u8 S_R, S_R, #1 + vadd.u8 S_A, S_R, TMP + vadd.u8 D_A, S_A, TMP +.endif +.elseif (\src_bpp == 24) || (\dst_bpp == 24) + vidup.u8 S_B, TMP, #1 + mov TMP, #3 + vmul.u8 S_B, S_B, TMP + mov TMP, #1 + vadd.u8 S_G, S_B, TMP + vadd.u8 S_R, S_G, TMP +.endif +.if \dst_bpp >= 31 + load_index \dst_bpp, D, S, 0 + vmov.u8 D_A, #0xFF +.endif .endif .endm .macro vqrdmulh_u8 Qd, Qn, Qm @ 1 bit precision loss - vmulh.u8 Qd, Qn, Qm - vqshl.u8 Qd, Qd, #1 + vmulh.u8 \Qd, \Qn, \Qm + vqshl.u8 \Qd, \Qd, #1 .endm .macro premult mem, alpha - vrmulh.u8 mem&_B, mem&_B, alpha - vrmulh.u8 mem&_G, mem&_G, alpha - vrmulh.u8 mem&_R, mem&_R, alpha + vrmulh.u8 \mem\()_B, \mem\()_B, \alpha + vrmulh.u8 \mem\()_G, \mem\()_G, \alpha + vrmulh.u8 \mem\()_R, \mem\()_R, \alpha +.endm + +.macro blend_565 p + vmovl\p\().u16 D_L, D_565 + vsli.32 D_L, D_L, #16 + vand D_L, D_L, BITMASK + vsub.u32 D_T, S_L, D_L + vmovl\p\().u16 D_A, S_A + vmul.u32 D_T, D_T, D_A + vshr.u32 D_T, D_T, #5 + vadd.u32 D_L, D_L, D_T + vand D_L, D_L, BITMASK + vshr.u32 D_T, D_L, #16 + vorr D_L, D_L, D_T + vmovn\p\().u32 D_565, D_L +.endm + +.macro late_init src_bpp, dst_bpp, mask, opa, mode +.if (\src_bpp <= 16) && (\dst_bpp == 16) && (\mask == 0) +.if \opa == 2 + mov TMP, #0x7BEF + vdup.16 BITMASK, TMP +.if \src_bpp == 0 + vshr.u16 S_L, S_565, #1 + vand S_L, S_L, BITMASK +.endif +.elseif \opa == 1 + vdup.16 S_A, OPA + mov TMP, #4 + vadd.u16 S_A, S_A, TMP + vshr.u16 S_A, S_A, #3 +.endif +.endif .endm .macro blend src_bpp, dst_bpp, mask, opa, mode -.if (mask == 0) && (opa == 2) && (dst_bpp < 32) +.if (\mask == 0) && (\opa == 2) +.if (\src_bpp <= 16) && (\dst_bpp == 16) +.if \src_bpp > 0 + vshr.u16 S_L, S_565, #1 + vand S_L, S_L, BITMASK +.endif + vshr.u16 D_L, D_565, #1 + vand D_L, D_L, BITMASK + vadd.u16 D_565, S_L, D_L +.else vhadd.u8 D_B, D_B, S_B vhadd.u8 D_G, D_G, S_G vhadd.u8 D_R, D_R, S_R +.endif +.elseif (\src_bpp <= 16) && (\dst_bpp == 16) + lsl lr, #1 +.if \src_bpp > 0 + vmovlb.u16 S_L, S_565 + vsli.32 S_L, S_L, #16 + vand S_L, S_L, BITMASK +.endif + blend_565 b +.if \src_bpp > 0 + vmovlt.u16 S_L, S_565 + vsli.32 S_L, S_L, #16 + vand S_L, S_L, BITMASK +.endif + blend_565 t + lsr lr, #1 .else -.if dst_bpp < 32 +.if \dst_bpp < 32 +.if (\opa == 0) && (\mask == 0) + vmov.u8 D_A, #0xFF + mov TMP, #0 + vabav.u8 TMP, S_A, D_A + cbnz TMP, 91f + vmov D_B, S_B + vmov D_G, S_G + vmov D_R, S_R + b 88f +91: +.endif vmvn D_A, S_A premult S, S_A premult D, D_A .else vpush {d0-d5} + vmov.u8 S_B, #0xFF + vmov.u8 S_G, #0 + mov TMP, #0 + vabav.u8 TMP, S_A, S_B + cbz TMP, 91f @ if(fg.alpha == 255 + mov TMP, #0 + vabav.u8 TMP, D_A, S_G + cbnz TMP, 90f @ || bg.alpha == 0) +91: + vpop {d8-d13} @ return fg; + vmov.u8 D_A, #0xFF + b 88f +90: + mov TMP, #0 + vabav.u8 TMP, S_A, S_G + cmp TMP, #2 @ if(fg.alpha <= LV_OPA_MIN) + itt le @ return bg; + vpople {d0-d5} + ble 88f + mov TMP, #0 + vabav.u8 TMP, D_A, S_B @ if (bg.alpha == 255) + cbnz TMP, 89f @ return lv_color_mix32(fg, bg); + vpop {d0-d5} + vmvn D_A, S_A + premult S, S_A + premult D, D_A + vqadd.u8 D_B, D_B, S_B + vqadd.u8 D_G, D_G, S_G + vqadd.u8 D_R, D_R, S_R + vmov.u8 D_A, #0xFF + b 88f +89: vmvn N, S_A vmvn D_A, D_A vrmulh.u8 D_A, N, D_A @@ -261,191 +438,242 @@ L .qn q4 vqadd.u8 D_G, D_G, S_G vqadd.u8 D_R, D_R, S_R .endif -.if dst_bpp == 31 +.if \dst_bpp == 31 vmov.u8 D_A, #0xFF .endif +88: .endm .macro blend_line src_bpp, dst_bpp, mask, opa, mode - wlstp.8 lr, DST_W, 1f +.if (\src_bpp < 31) && (\dst_bpp < 31) + blend_block \src_bpp, \dst_bpp, \mask, \opa, \mode, DST_W, 0 +.else + bics TMP, DST_W, #0xF + beq 87f + blend_block \src_bpp, \dst_bpp, \mask, \opa, \mode, TMP, 1 +87: + ands TMP, DST_W, #0xF + beq 86f + blend_block \src_bpp, \dst_bpp, \mask, \opa, \mode, TMP, 0 +86: +.endif +.endm + +.macro blend_block src_bpp, dst_bpp, mask, opa, mode, w, aligned +.if (\src_bpp <= 16) && (\dst_bpp == 16) + wlstp.16 lr, \w, 1f +.else + wlstp.8 lr, \w, 1f +.endif 2: -.if (src_bpp < 32) && (mask == 0) && (opa == 0) +.if (\src_bpp < 32) && (\mask == 0) && (\opa == 0) @ no blend -@ dst index: db < 31 ? (db == sb ? S : D) : S -@ src index: sb < 31 && db >= 31 ? D(reload) : S - .if (src_bpp < 31) && (dst_bpp >= 31) - load_index src_bpp, D, D - .endif - .if src_bpp == 0 - ldst st, dst_bpp, DST, D, S, 0, 0, ! - .elseif (src_bpp == dst_bpp) || (src_bpp == 31) && (dst_bpp == 32) - .if dst_bpp < 31 - .if src_bpp < 31 - ldst ld, src_bpp, SRC, D, S, 0, 1, ! + .if \src_bpp == 0 + ldst 1, st, \dst_bpp, DST, D, S, 0, 1, !, \aligned + .elseif (\src_bpp == \dst_bpp) || (\src_bpp == 31) && (\dst_bpp == 32) + .if \dst_bpp < 31 + .if \src_bpp < 31 + ldst 0, ld, \src_bpp, SRC, D, S, 0, 1, !, \aligned .else - ldst ld, src_bpp, SRC, D, S, 0, 0, ! + ldst 0, ld, \src_bpp, SRC, D, S, 0, 1, !, \aligned .endif - ldst st, dst_bpp, DST, D, S, 0, 1, ! + ldst 1, st, \dst_bpp, DST, D, S, 0, 1, !, \aligned .else - ldst ld, src_bpp, SRC, D, S, 0, 0, ! - ldst st, dst_bpp, DST, D, S, 0, 0, ! + ldst 0, ld, \src_bpp, SRC, D, S, 0, 1, !, \aligned + ldst 1, st, \dst_bpp, DST, D, S, 0, 1, !, \aligned .endif .else - .if (dst_bpp < 31) && (src_bpp < 31) - ldst ld, src_bpp, SRC, D, S, 1, 1, ! + .if (\dst_bpp < 31) && (\src_bpp < 31) + ldst 0, ld, \src_bpp, SRC, D, S, 1, 2, !, \aligned + ldst 1, st, \dst_bpp, DST, D, S, 1, 2, !, \aligned .else - ldst ld, src_bpp, SRC, D, S, 1, 0, ! + ldst 0, ld, \src_bpp, SRC, D, S, 1, 1, !, \aligned + ldst 1, st, \dst_bpp, DST, D, S, 1, 1, !, \aligned .endif - .if (src_bpp < 31) && (dst_bpp >= 31) - vmov.u8 D_A, #0xFF - .endif - ldst st, dst_bpp, DST, D, S, 1, 0, ! .endif -.elseif src_bpp < 32 +.elseif (\src_bpp <= 16) && (\dst_bpp == 16) + .if \src_bpp > 0 + ldst 0, ld, \src_bpp, SRC, S, D, 0, 0, !, \aligned + .endif + ldst 0, ld, \dst_bpp, DST, D, S, 0, 0, , \aligned + .if \mask + ldst 0, ld, 8, MASK, S, D, 1, 0, ! + .if \opa == 2 + vshr.u16 S_A, S_A, #1 + .elseif \opa == 1 + vmul.u16 S_A, S_A, OPA + vshr.u16 S_A, S_A, #8 + .endif + mov TMP, #4 + vadd.u16 S_A, S_A, TMP + vshr.u16 S_A, S_A, #3 + .endif + blend \src_bpp, \dst_bpp, \mask, \opa, \mode + ldst 1, st, \dst_bpp, DST, D, S, 0, 0, !, \aligned +.elseif \src_bpp < 32 @ no src_a - load_index src_bpp, S, D - ldst ld, src_bpp, SRC, S, D, 1, 0, ! - load_index dst_bpp, D, S - ldst ld, dst_bpp, DST, D, S, 1, 0 - .if mask - ldst ld, 8, MASK, S, D, 1, 0, ! - .if opa == 2 +.if \src_bpp > 0 + load_index \src_bpp, S, D, \aligned + ldst 0, ld, \src_bpp, SRC, S, D, 1, 0, !, \aligned +.elseif (\opa == 1) || \mask + vpush {d0-d5} +.endif + load_index \dst_bpp, D, S, \aligned + ldst 0, ld, \dst_bpp, DST, D, S, 1, 0, , \aligned + .if \mask + ldst 0, ld, 8, MASK, S, D, 0, 0, !, \aligned + .if \opa == 2 vshr.u8 S_A, S_A, #1 - .elseif opa == 1 - .if dst_bpp == 32 + .elseif \opa == 1 + .if \dst_bpp == 32 vpush {d14-d15} .endif vdup.8 D_A, OPA vrmulh.u8 S_A, S_A, D_A - .if dst_bpp == 32 + .if \dst_bpp == 32 vpop {d14-d15} .endif .endif - .elseif opa == 1 + .elseif \opa == 1 vdup.8 S_A, OPA .endif - blend src_bpp, dst_bpp, mask, opa, mode - .if (dst_bpp == 32) || mask || (opa == 1) - load_index dst_bpp, D, S + blend \src_bpp, \dst_bpp, \mask, \opa, \mode +.if (\src_bpp == 0) && ((\opa == 1) || \mask) + vpop {d0-d5} +.endif + .if (\dst_bpp == 32) || \mask || (\opa == 1) + load_index \dst_bpp, D, S, \aligned .endif - ldst st, dst_bpp, DST, D, S, 1, 0, ! + ldst 1, st, \dst_bpp, DST, D, S, 1, 0, !, \aligned .else -@ src_a (+mask) (+opa) - load_index dst_bpp, D, S - ldst ld, dst_bpp, DST, D, S, 1, 0 - .if dst_bpp == 32 +@ src_a (+\mask) (+\opa) + load_index \dst_bpp, D, S, \aligned + ldst 0, ld, \dst_bpp, DST, D, S, 1, 0, , \aligned + .if (\dst_bpp == 32) && (\mask || \opa || (\aligned == 0)) vpush {d14-d15} .endif - load_index src_bpp, S, D - ldst ld, src_bpp, SRC, S, D, 1, 0, ! - .if mask == 0 - .if opa + load_index \src_bpp, S, D, \aligned + ldst 0, ld, \src_bpp, SRC, S, D, 1, 0, !, \aligned + .if \mask == 0 + .if \opa vdup.8 D_A, OPA vrmulh.u8 S_A, S_A, D_A .endif .else - ldst ld, 8, MASK, D, S, 1, 0, ! + ldst 0, ld, 8, MASK, D, S, 0, 0, !, \aligned vrmulh.u8 S_A, S_A, D_A - .if opa + .if \opa vdup.8 D_A, OPA vrmulh.u8 S_A, S_A, D_A .endif .endif - .if dst_bpp == 32 + .if (\dst_bpp == 32) && (\mask || \opa || (\aligned == 0)) vpop {d14-d15} .endif - blend src_bpp, dst_bpp, mask, opa, mode - load_index dst_bpp, D, S - ldst st, dst_bpp, DST, D, S, 1, 0, ! + blend \src_bpp, \dst_bpp, \mask, \opa, \mode + load_index \dst_bpp, D, S, \aligned + ldst 1, st, \dst_bpp, DST, D, S, 1, 0, !, \aligned .endif letp lr, 2b 1: .endm -.macro enter +.macro enter complex push {r4-r11, lr} +.if \complex vpush {d8-d15} +.endif .endm -.macro exit +.macro exit complex +.if \complex vpop {d8-d15} +.endif pop {r4-r11, pc} .endm .macro preload mem, bpp -.if bpp >= 31 - pld [mem&_ADDR, DST_W, lsl #2] -.elseif bpp == 24 +.if \bpp >= 31 + pld [\mem\()_ADDR, DST_W, lsl #2] +.elseif \bpp == 24 add TMP, DST_W, DST_W, lsl #1 - pld [mem&_ADDR, TMP] -.elseif bpp == 16 - pld [mem&_ADDR, DST_W, lsl #1] -.elseif bpp == 8 - pld [mem&_ADDR, DST_W] + pld [\mem\()_ADDR, TMP] +.elseif \bpp == 16 + pld [\mem\()_ADDR, DST_W, lsl #1] +.elseif \bpp == 8 + pld [\mem\()_ADDR, DST_W] .endif .endm .macro next src_bpp, mask add DST_ADDR, DST_ADDR, DST_STRIDE -.if src_bpp > 0 +.if \src_bpp > 0 add SRC_ADDR, SRC_ADDR, SRC_STRIDE .endif -.if mask +.if \mask add MASK_ADDR, MASK_ADDR, MASK_STRIDE .endif .endm .macro blender src_bpp, dst_bpp, mask, opa, mode - enter - init src_bpp, dst_bpp, mask, opa +.if (\src_bpp <= 16) && (\dst_bpp == 16) && (\opa == 0) && (\mask == 0) + enter 0 +.else + enter 1 +.endif + init \src_bpp, \dst_bpp, \mask, \opa movs H, DST_H beq 0f - preload SRC, src_bpp -.if mask || opa || (src_bpp == 32) - preload DST, dst_bpp + preload SRC, \src_bpp +.if \mask || \opa || (\src_bpp == 32) + preload DST, \dst_bpp .endif -.if opa && (src_bpp < 32) && (dst_bpp < 32) +.if \opa && (\src_bpp < 32) && (\dst_bpp < 32) 4: @ 50% OPA can be accelerated (OPA == 0x7F/0x80) add TMP, OPA, #1 tst TMP, #0x7E bne 3f - blend_line src_bpp, dst_bpp, mask, 2, mode - next src_bpp, mask + late_init \src_bpp, \dst_bpp, \mask, 2, \mode + blend_line \src_bpp, \dst_bpp, \mask, 2, \mode + next \src_bpp, \mask subs H, #1 bne 4b b 0f .endif 3: - blend_line src_bpp, dst_bpp, mask, opa, mode - next src_bpp, mask + late_init \src_bpp, \dst_bpp, \mask, \opa, \mode + blend_line \src_bpp, \dst_bpp, \mask, \opa, \mode + next \src_bpp, \mask subs H, #1 bne 3b 0: - exit +.if (\src_bpp <= 16) && (\dst_bpp == 16) && (\opa == 0) && (\mask == 0) + exit 0 +.else + exit 1 +.endif .ltorg .endm .macro export name, src_bpp, dst_bpp, mask, opa, mode .thumb_func -.func name -.global name -name&: - blender src_bpp, dst_bpp, mask, opa, mode -.endfunc +.global \name +\name\(): + blender \src_bpp, \dst_bpp, \mask, \opa, \mode .endm .macro export_set src, dst, src_bpp, dst_bpp, mode -.if src == color - export lv_&src&_blend_to_&dst&_helium, src_bpp, dst_bpp, 0, 0, mode - export lv_&src&_blend_to_&dst&_with_opa_helium, src_bpp, dst_bpp, 0, 1, mode - export lv_&src&_blend_to_&dst&_with_mask_helium, src_bpp, dst_bpp, 1, 0, mode - export lv_&src&_blend_to_&dst&_mix_mask_opa_helium, src_bpp, dst_bpp, 1, 1, mode +.ifc \src, color + export lv_\src\()_blend_to_\dst\()_helium, \src_bpp, \dst_bpp, 0, 0, \mode + export lv_\src\()_blend_to_\dst\()_with_opa_helium, \src_bpp, \dst_bpp, 0, 1, \mode + export lv_\src\()_blend_to_\dst\()_with_mask_helium, \src_bpp, \dst_bpp, 1, 0, \mode + export lv_\src\()_blend_to_\dst\()_mix_mask_opa_helium, \src_bpp, \dst_bpp, 1, 1, \mode .else - export lv_&src&_blend_&mode&_to_&dst&_helium, src_bpp, dst_bpp, 0, 0, mode - export lv_&src&_blend_&mode&_to_&dst&_with_opa_helium, src_bpp, dst_bpp, 0, 1, mode - export lv_&src&_blend_&mode&_to_&dst&_with_mask_helium, src_bpp, dst_bpp, 1, 0, mode - export lv_&src&_blend_&mode&_to_&dst&_mix_mask_opa_helium, src_bpp, dst_bpp, 1, 1, mode + export lv_\src\()_blend_\mode\()_to_\dst\()_helium, \src_bpp, \dst_bpp, 0, 0, \mode + export lv_\src\()_blend_\mode\()_to_\dst\()_with_opa_helium, \src_bpp, \dst_bpp, 0, 1, \mode + export lv_\src\()_blend_\mode\()_to_\dst\()_with_mask_helium, \src_bpp, \dst_bpp, 1, 0, \mode + export lv_\src\()_blend_\mode\()_to_\dst\()_mix_mask_opa_helium, \src_bpp, \dst_bpp, 1, 1, \mode .endif .endm diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.h index f8964e9d9..69b999efc 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/helium/lv_blend_helium.h @@ -41,242 +41,242 @@ extern "C" { #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ - _lv_color_blend_to_rgb565_helium(dsc) + lv_color_blend_to_rgb565_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ - _lv_color_blend_to_rgb565_with_opa_helium(dsc) + lv_color_blend_to_rgb565_with_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ - _lv_color_blend_to_rgb565_with_mask_helium(dsc) + lv_color_blend_to_rgb565_with_mask_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_color_blend_to_rgb565_mix_mask_opa_helium(dsc) + lv_color_blend_to_rgb565_mix_mask_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_helium(dsc) + lv_rgb565_blend_normal_to_rgb565_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_with_opa_helium(dsc) + lv_rgb565_blend_normal_to_rgb565_with_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_with_mask_helium(dsc) + lv_rgb565_blend_normal_to_rgb565_with_mask_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(dsc) + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_with_opa_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_with_opa_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_with_mask_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_with_mask_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_helium(dsc) + lv_argb8888_blend_normal_to_rgb565_helium(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_with_opa_helium(dsc) + lv_argb8888_blend_normal_to_rgb565_with_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_with_mask_helium(dsc) + lv_argb8888_blend_normal_to_rgb565_with_mask_helium(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(dsc) + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_helium(dsc, dst_px_size) + lv_color_blend_to_rgb888_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_with_opa_helium(dsc, dst_px_size) + lv_color_blend_to_rgb888_with_opa_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_with_mask_helium(dsc, dst_px_size) + lv_color_blend_to_rgb888_with_mask_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) + lv_color_blend_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_helium(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_helium(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_helium(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_helium(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_with_opa_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_with_mask_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888 #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888(dsc) \ - _lv_color_blend_to_argb8888_helium(dsc) + lv_color_blend_to_argb8888_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA(dsc) \ - _lv_color_blend_to_argb8888_with_opa_helium(dsc) + lv_color_blend_to_argb8888_with_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK(dsc) \ - _lv_color_blend_to_argb8888_with_mask_helium(dsc) + lv_color_blend_to_argb8888_with_mask_helium(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - _lv_color_blend_to_argb8888_mix_mask_opa_helium(dsc) + lv_color_blend_to_argb8888_mix_mask_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_helium(dsc) + lv_rgb565_blend_normal_to_argb8888_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_with_opa_helium(dsc) + lv_rgb565_blend_normal_to_argb8888_with_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_with_mask_helium(dsc) + lv_rgb565_blend_normal_to_argb8888_with_mask_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(dsc) + lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_with_opa_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_with_opa_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_with_mask_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_with_mask_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_helium(dsc) + lv_argb8888_blend_normal_to_argb8888_helium(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_with_opa_helium(dsc) + lv_argb8888_blend_normal_to_argb8888_with_opa_helium(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_with_mask_helium(dsc) + lv_argb8888_blend_normal_to_argb8888_with_mask_helium(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(dsc) + lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(dsc) #endif /********************** @@ -299,7 +299,7 @@ typedef struct { **********************/ extern void lv_color_blend_to_rgb565_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -314,7 +314,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_helium(_lv_draw_sw_blend_fil } extern void lv_color_blend_to_rgb565_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_with_opa_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -329,7 +329,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_with_opa_helium(_lv_draw_sw_ } extern void lv_color_blend_to_rgb565_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_with_mask_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -345,7 +345,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_with_mask_helium(_lv_draw_sw } extern void lv_color_blend_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_mix_mask_opa_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -362,7 +362,7 @@ static inline lv_result_t _lv_color_blend_to_rgb565_mix_mask_opa_helium(_lv_draw } extern void lv_rgb565_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -377,7 +377,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_helium(_lv_draw_sw_b } extern void lv_rgb565_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -393,7 +393,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_opa_helium(_lv_ } extern void lv_rgb565_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -410,7 +410,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_mask_helium(_lv } extern void lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -429,8 +429,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium( extern void lv_rgb888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -451,8 +451,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_helium(_lv_draw_sw_b extern void lv_rgb888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -474,8 +474,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_opa_helium(_lv_ extern void lv_rgb888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -498,8 +498,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_mask_helium(_lv extern void lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -522,7 +522,7 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium( } extern void lv_argb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -537,7 +537,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_helium(_lv_draw_sw } extern void lv_argb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -553,7 +553,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_opa_helium(_l } extern void lv_argb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -570,7 +570,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_mask_helium(_ } extern void lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -589,7 +589,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_heliu extern void lv_color_blend_to_rgb888_helium(asm_dsc_t * dsc); extern void lv_color_blend_to_xrgb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_helium(_lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_helium(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -609,8 +609,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_helium(_lv_draw_sw_blend_fil extern void lv_color_blend_to_rgb888_with_opa_helium(asm_dsc_t * dsc); extern void lv_color_blend_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_with_opa_helium(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -631,8 +631,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_with_opa_helium(_lv_draw_sw_ extern void lv_color_blend_to_rgb888_with_mask_helium(asm_dsc_t * dsc); extern void lv_color_blend_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_with_mask_helium(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -654,8 +654,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_with_mask_helium(_lv_draw_sw extern void lv_color_blend_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_color_blend_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_mix_mask_opa_helium(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -678,8 +678,8 @@ static inline lv_result_t _lv_color_blend_to_rgb888_mix_mask_opa_helium(_lv_draw extern void lv_rgb565_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); extern void lv_rgb565_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -700,8 +700,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_helium(_lv_draw_sw_b extern void lv_rgb565_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); extern void lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -723,8 +723,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_opa_helium(_lv_ extern void lv_rgb565_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); extern void lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -747,8 +747,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_mask_helium(_lv extern void lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -774,9 +774,9 @@ extern void lv_rgb888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); extern void lv_rgb888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -809,8 +809,8 @@ extern void lv_rgb888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); extern void lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -844,8 +844,8 @@ extern void lv_rgb888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); extern void lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -880,8 +880,8 @@ extern void lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc extern void lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -915,8 +915,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium( extern void lv_argb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); extern void lv_argb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -937,8 +937,8 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_helium(_lv_draw_sw extern void lv_argb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); extern void lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -960,8 +960,8 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_opa_helium(_l extern void lv_argb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); extern void lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -984,8 +984,8 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_mask_helium(_ extern void lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1008,7 +1008,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_heliu } extern void lv_color_blend_to_argb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_argb8888_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1023,7 +1023,7 @@ static inline lv_result_t _lv_color_blend_to_argb8888_helium(_lv_draw_sw_blend_f } extern void lv_color_blend_to_argb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_with_opa_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_argb8888_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1038,7 +1038,7 @@ static inline lv_result_t _lv_color_blend_to_argb8888_with_opa_helium(_lv_draw_s } extern void lv_color_blend_to_argb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_with_mask_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_argb8888_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1054,7 +1054,7 @@ static inline lv_result_t _lv_color_blend_to_argb8888_with_mask_helium(_lv_draw_ } extern void lv_color_blend_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_mix_mask_opa_helium(_lv_draw_sw_blend_fill_dsc_t * dsc) +static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1071,7 +1071,7 @@ static inline lv_result_t _lv_color_blend_to_argb8888_mix_mask_opa_helium(_lv_dr } extern void lv_rgb565_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1086,7 +1086,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_helium(_lv_draw_sw } extern void lv_rgb565_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1102,7 +1102,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_with_opa_helium(_l } extern void lv_rgb565_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1119,7 +1119,7 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_with_mask_helium(_ } extern void lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1138,8 +1138,8 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_heliu extern void lv_rgb888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1160,8 +1160,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_helium(_lv_draw_sw extern void lv_rgb888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1183,8 +1183,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_opa_helium(_l extern void lv_rgb888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1207,8 +1207,8 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_mask_helium(_ extern void lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); extern void lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1231,7 +1231,7 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_heliu } extern void lv_argb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1246,7 +1246,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_helium(_lv_draw_ } extern void lv_argb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1262,7 +1262,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_opa_helium( } extern void lv_argb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_mask_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1279,7 +1279,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_mask_helium } extern void lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(_lv_draw_sw_blend_image_dsc_t * dsc) +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.c index 9ceee3b1c..6f48eba64 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_blend.c * */ @@ -6,11 +6,28 @@ /********************* * INCLUDES *********************/ +#include "../../../misc/lv_area_private.h" +#include "lv_draw_sw_blend_private.h" +#include "../../lv_draw_private.h" #include "../lv_draw_sw.h" -#include "lv_draw_sw_blend_to_rgb565.h" -#include "lv_draw_sw_blend_to_argb8888.h" -#include "lv_draw_sw_blend_to_rgb888.h" - +#if LV_DRAW_SW_SUPPORT_L8 + #include "lv_draw_sw_blend_to_l8.h" +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + #include "lv_draw_sw_blend_to_al88.h" +#endif +#if LV_DRAW_SW_SUPPORT_RGB565 + #include "lv_draw_sw_blend_to_rgb565.h" +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 + #include "lv_draw_sw_blend_to_argb8888.h" +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + #include "lv_draw_sw_blend_to_rgb888.h" +#endif +#if LV_DRAW_SW_SUPPORT_I1 + #include "lv_draw_sw_blend_to_i1.h" +#endif #if LV_USE_DRAW_SW /********************* @@ -43,14 +60,14 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * if(blend_dsc->mask_buf && blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_TRANSP) return; lv_area_t blend_area; - if(!_lv_area_intersect(&blend_area, blend_dsc->blend_area, draw_unit->clip_area)) return; + if(!lv_area_intersect(&blend_area, blend_dsc->blend_area, draw_unit->clip_area)) return; LV_PROFILER_BEGIN; lv_layer_t * layer = draw_unit->target_layer; - uint32_t layer_stride_byte = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format); + uint32_t layer_stride_byte = layer->draw_buf->header.stride; if(blend_dsc->src_buf == NULL) { - _lv_draw_sw_blend_fill_dsc_t fill_dsc; + lv_draw_sw_blend_fill_dsc_t fill_dsc; fill_dsc.dest_w = lv_area_get_width(&blend_area); fill_dsc.dest_h = lv_area_get_height(&blend_area); fill_dsc.dest_stride = layer_stride_byte; @@ -61,9 +78,11 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) fill_dsc.mask_buf = NULL; else fill_dsc.mask_buf = blend_dsc->mask_buf; + + fill_dsc.relative_area = blend_area; + lv_area_move(&fill_dsc.relative_area, -layer->buf_area.x1, -layer->buf_area.y1); fill_dsc.dest_buf = lv_draw_layer_go_to_xy(layer, blend_area.x1 - layer->buf_area.x1, blend_area.y1 - layer->buf_area.y1); - if(fill_dsc.mask_buf) { fill_dsc.mask_stride = blend_dsc->mask_stride == 0 ? lv_area_get_width(blend_dsc->mask_area) : blend_dsc->mask_stride; fill_dsc.mask_buf += fill_dsc.mask_stride * (blend_area.y1 - blend_dsc->mask_area->y1) + @@ -71,34 +90,57 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * } switch(layer->color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 case LV_COLOR_FORMAT_RGB565: lv_draw_sw_blend_color_to_rgb565(&fill_dsc); break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 case LV_COLOR_FORMAT_ARGB8888: lv_draw_sw_blend_color_to_argb8888(&fill_dsc); break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: lv_draw_sw_blend_color_to_rgb888(&fill_dsc, 3); break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 case LV_COLOR_FORMAT_XRGB8888: lv_draw_sw_blend_color_to_rgb888(&fill_dsc, 4); break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + lv_draw_sw_blend_color_to_l8(&fill_dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + lv_draw_sw_blend_color_to_al88(&fill_dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + lv_draw_sw_blend_color_to_i1(&fill_dsc); + break; +#endif default: break; } } else { - if(!_lv_area_intersect(&blend_area, &blend_area, blend_dsc->src_area)) { + if(!lv_area_intersect(&blend_area, &blend_area, blend_dsc->src_area)) { LV_PROFILER_END; return; } - if(blend_dsc->mask_area && !_lv_area_intersect(&blend_area, &blend_area, blend_dsc->mask_area)) { + if(blend_dsc->mask_area && !lv_area_intersect(&blend_area, &blend_area, blend_dsc->mask_area)) { LV_PROFILER_END; return; } - _lv_draw_sw_blend_image_dsc_t image_dsc; + lv_draw_sw_blend_image_dsc_t image_dsc; image_dsc.dest_w = lv_area_get_width(&blend_area); image_dsc.dest_h = lv_area_get_height(&blend_area); image_dsc.dest_stride = layer_stride_byte; @@ -109,11 +151,12 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * image_dsc.src_color_format = blend_dsc->src_color_format; const uint8_t * src_buf = blend_dsc->src_buf; - uint32_t src_px_size = lv_color_format_get_size(blend_dsc->src_color_format); + uint32_t src_px_size = lv_color_format_get_bpp(blend_dsc->src_color_format); src_buf += image_dsc.src_stride * (blend_area.y1 - blend_dsc->src_area->y1); - src_buf += (blend_area.x1 - blend_dsc->src_area->x1) * src_px_size; + src_buf += ((blend_area.x1 - blend_dsc->src_area->x1) * src_px_size) >> 3; image_dsc.src_buf = src_buf; + if(blend_dsc->mask_buf == NULL) image_dsc.mask_buf = NULL; else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) image_dsc.mask_buf = NULL; else image_dsc.mask_buf = blend_dsc->mask_buf; @@ -125,23 +168,52 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * (blend_area.x1 - blend_dsc->mask_area->x1); } + image_dsc.relative_area = blend_area; + lv_area_move(&image_dsc.relative_area, -layer->buf_area.x1, -layer->buf_area.y1); + + image_dsc.src_area = *blend_dsc->src_area; + lv_area_move(&image_dsc.src_area, -layer->buf_area.x1, -layer->buf_area.y1); + image_dsc.dest_buf = lv_draw_layer_go_to_xy(layer, blend_area.x1 - layer->buf_area.x1, blend_area.y1 - layer->buf_area.y1); switch(layer->color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 case LV_COLOR_FORMAT_RGB565: case LV_COLOR_FORMAT_RGB565A8: lv_draw_sw_blend_image_to_rgb565(&image_dsc); break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 case LV_COLOR_FORMAT_ARGB8888: lv_draw_sw_blend_image_to_argb8888(&image_dsc); break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: lv_draw_sw_blend_image_to_rgb888(&image_dsc, 3); break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 case LV_COLOR_FORMAT_XRGB8888: lv_draw_sw_blend_image_to_rgb888(&image_dsc, 4); break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + lv_draw_sw_blend_image_to_l8(&image_dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + lv_draw_sw_blend_image_to_al88(&image_dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + lv_draw_sw_blend_image_to_i1(&image_dsc); + break; +#endif default: break; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.h index c1b1edca0..1528cacc3 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend.h @@ -28,47 +28,6 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct { - const lv_area_t * blend_area; /**< The area with absolute coordinates to draw on `layer->buf` - * will be clipped to `layer->clip_area` */ - const void * src_buf; /**< Pointer to an image to blend. If set `fill_color` is ignored */ - uint32_t src_stride; - lv_color_format_t src_color_format; - const lv_area_t * src_area; - lv_opa_t opa; /**< The overall opacity*/ - lv_color_t color; /**< Fill color*/ - const lv_opa_t * mask_buf; /**< NULL if ignored, or an alpha mask to apply on `blend_area`*/ - lv_draw_sw_mask_res_t mask_res; /**< The result of the previous mask operation */ - const lv_area_t * mask_area; /**< The area of `mask_buf` with absolute coordinates*/ - int32_t mask_stride; - lv_blend_mode_t blend_mode; /**< E.g. LV_BLEND_MODE_ADDITIVE*/ -} lv_draw_sw_blend_dsc_t; - -typedef struct { - void * dest_buf; - int32_t dest_w; - int32_t dest_h; - int32_t dest_stride; - const lv_opa_t * mask_buf; - int32_t mask_stride; - lv_color_t color; - lv_opa_t opa; -} _lv_draw_sw_blend_fill_dsc_t; - -typedef struct { - void * dest_buf; - int32_t dest_w; - int32_t dest_h; - int32_t dest_stride; - const lv_opa_t * mask_buf; - int32_t mask_stride; - const void * src_buf; - int32_t src_stride; - lv_color_format_t src_color_format; - lv_opa_t opa; - lv_blend_mode_t blend_mode; -} _lv_draw_sw_blend_image_dsc_t; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_private.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_private.h new file mode 100644 index 000000000..532f4c966 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_private.h @@ -0,0 +1,92 @@ +/** + * @file lv_draw_sw_blend_private.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_PRIVATE_H +#define LV_DRAW_SW_BLEND_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw_blend.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_draw_sw_blend_dsc_t { + const lv_area_t * blend_area; /**< The area with absolute coordinates to draw on `layer->buf` + * will be clipped to `layer->clip_area` */ + const void * src_buf; /**< Pointer to an image to blend. If set `fill_color` is ignored */ + uint32_t src_stride; + lv_color_format_t src_color_format; + const lv_area_t * src_area; + lv_opa_t opa; /**< The overall opacity*/ + lv_color_t color; /**< Fill color*/ + const lv_opa_t * mask_buf; /**< NULL if ignored, or an alpha mask to apply on `blend_area`*/ + lv_draw_sw_mask_res_t mask_res; /**< The result of the previous mask operation */ + const lv_area_t * mask_area; /**< The area of `mask_buf` with absolute coordinates*/ + int32_t mask_stride; + lv_blend_mode_t blend_mode; /**< E.g. LV_BLEND_MODE_ADDITIVE*/ +}; + +struct lv_draw_sw_blend_fill_dsc_t { + void * dest_buf; + int32_t dest_w; + int32_t dest_h; + int32_t dest_stride; + const lv_opa_t * mask_buf; + int32_t mask_stride; + lv_color_t color; + lv_opa_t opa; + lv_area_t relative_area; +}; + +struct lv_draw_sw_blend_image_dsc_t { + void * dest_buf; + int32_t dest_w; + int32_t dest_h; + int32_t dest_stride; + const lv_opa_t * mask_buf; + int32_t mask_stride; + const void * src_buf; + int32_t src_stride; + lv_color_format_t src_color_format; + lv_opa_t opa; + lv_blend_mode_t blend_mode; + lv_area_t relative_area; /**< The blend area relative to the layer's buffer area. */ + lv_area_t src_area; /**< The original src area. */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c new file mode 100644 index 000000000..9c3194c20 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c @@ -0,0 +1,1036 @@ +/** + * @file lv_draw_sw_blend_al88.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_to_al88.h" +#if LV_USE_DRAW_SW + +#if LV_DRAW_SW_SUPPORT_AL88 + +#include "lv_draw_sw_blend_private.h" +#include "../../../misc/lv_math.h" +#include "../../../display/lv_display.h" +#include "../../../core/lv_refr.h" +#include "../../../misc/lv_color.h" +#include "../../../stdlib/lv_string.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + #include "neon/lv_blend_neon.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM + #include "helium/lv_blend_helium.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #include LV_DRAW_SW_ASM_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_color16a_t fg_saved; + lv_color16a_t bg_saved; + lv_color16a_t res_saved; + lv_opa_t res_alpha_saved; + lv_opa_t ratio_saved; +} lv_color_mix_alpha_cache_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +#if LV_DRAW_SW_SUPPORT_L8 + static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_I1 + static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + + static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, int32_t bit_idx); +#endif + +static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +#if LV_DRAW_SW_SUPPORT_RGB565 + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, + const uint8_t src_px_size); +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +static void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cache); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel(lv_color16a_t * dest, lv_color16a_t src, + lv_blend_mode_t mode, lv_color_mix_alpha_cache_t * cache); + +static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); + +static inline bool lv_color16a_eq(lv_color16a_t c1, lv_color16a_t c2); + +static inline lv_color16a_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color_mix16a(lv_color16a_t fg, lv_color16a_t bg); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_16a_16a_mix(lv_color16a_t src, lv_color16a_t * dest, + lv_color_mix_alpha_cache_t * cache); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_AL88 + #define LV_DRAW_SW_COLOR_BLEND_TO_AL88(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_AL88_WITH_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_AL88_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_AL88_WITH_MASK + #define LV_DRAW_SW_COLOR_BLEND_TO_AL88_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_AL88_MIX_MASK_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_AL88_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88 + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_WITH_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_WITH_MASK + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88 + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_WITH_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_WITH_MASK + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88 + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_WITH_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_WITH_MASK + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88 + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88 + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_al88(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + const lv_opa_t * mask = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + int32_t dest_stride = dsc->dest_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x; + int32_t y; + + LV_UNUSED(w); + LV_UNUSED(h); + LV_UNUSED(x); + LV_UNUSED(y); + LV_UNUSED(opa); + LV_UNUSED(mask); + LV_UNUSED(mask_stride); + LV_UNUSED(dest_stride); + + /*Simple fill*/ + if(mask == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_AL88(dsc)) { + lv_color16a_t color16a; + color16a.lumi = lv_color_luminance(dsc->color); + color16a.alpha = 255; + lv_color16a_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w - 16; x += 16) { + dest_buf[x + 0] = color16a; + dest_buf[x + 1] = color16a; + dest_buf[x + 2] = color16a; + dest_buf[x + 3] = color16a; + + dest_buf[x + 4] = color16a; + dest_buf[x + 5] = color16a; + dest_buf[x + 6] = color16a; + dest_buf[x + 7] = color16a; + + dest_buf[x + 8] = color16a; + dest_buf[x + 9] = color16a; + dest_buf[x + 10] = color16a; + dest_buf[x + 11] = color16a; + + dest_buf[x + 12] = color16a; + dest_buf[x + 13] = color16a; + dest_buf[x + 14] = color16a; + dest_buf[x + 15] = color16a; + } + for(; x < w; x ++) { + dest_buf[x] = color16a; + } + + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + } + /*Opacity only*/ + else if(mask == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_AL88_WITH_OPA(dsc)) { + lv_color16a_t color16a; + color16a.lumi = lv_color_luminance(dsc->color); + color16a.alpha = opa; + lv_color16a_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_16a_16a_mix(color16a, &dest_buf[x], &cache); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + + } + /*Masked with full opacity*/ + else if(mask && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_AL88_WITH_MASK(dsc)) { + lv_color16a_t color16a; + color16a.lumi = lv_color_luminance(dsc->color); + lv_color16a_t * dest_buf = (lv_color16a_t *)dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color16a.alpha = mask[x]; + lv_color_16a_16a_mix(color16a, &dest_buf[x], &cache); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + + } + /*Masked with opacity*/ + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_AL88_MIX_MASK_OPA(dsc)) { + lv_color16a_t color16a; + color16a.lumi = lv_color_luminance(dsc->color); + lv_color16a_t * dest_buf = (lv_color16a_t *)dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color16a.alpha = LV_OPA_MIX2(mask[x], opa); + lv_color_16a_16a_mix(color16a, &dest_buf[x], &cache); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + } +} + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_al88(lv_draw_sw_blend_image_dsc_t * dsc) +{ + switch(dsc->src_color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + rgb565_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + rgb888_image_blend(dsc, 3); + break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 + case LV_COLOR_FORMAT_XRGB8888: + rgb888_image_blend(dsc, 4); + break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 + case LV_COLOR_FORMAT_ARGB8888: + argb8888_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + l8_image_blend(dsc); + break; +#endif + case LV_COLOR_FORMAT_AL88: + al88_image_blend(dsc); + break; +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + i1_image_blend(dsc); + break; +#endif + default: + LV_LOG_WARN("Not supported source color format"); + break; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#if LV_DRAW_SW_SUPPORT_I1 +static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color16a_t * dest_buf_al88 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_i1 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x, y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_al88[x].lumi = get_bit(src_buf_i1, x) * 255; + dest_buf_al88[x].alpha = 255; + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = get_bit(src_buf_i1, x) * 255; + src_color.alpha = opa; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = get_bit(src_buf_i1, x) * 255; + src_color.alpha = mask_buf[x]; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = get_bit(src_buf_i1, x) * 255; + src_color.alpha = LV_OPA_MIX2(mask_buf[x], opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = get_bit(src_buf_i1, x) * 255; + if(mask_buf == NULL) src_color.alpha = opa; + else src_color.alpha = LV_OPA_MIX2(mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_al88[x], src_color, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_L8 +static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color16a_t * dest_buf_al88 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x, y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_al88[x].lumi = src_buf_l8[x]; + dest_buf_al88[x].alpha = 255; + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = src_buf_l8[x]; + src_color.alpha = opa; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = src_buf_l8[x]; + src_color.alpha = mask_buf[x]; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = src_buf_l8[x]; + src_color.alpha = LV_OPA_MIX2(mask_buf[x], opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = src_buf_l8[x]; + if(mask_buf == NULL) src_color.alpha = opa; + else src_color.alpha = LV_OPA_MIX2(mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_al88[x], src_color, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } +} + +#endif + +static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color16a_t * dest_buf_al88 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16a_t * src_buf_al88 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x, y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_16a_16a_mix(src_buf_al88[x], &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color = src_buf_al88[x]; + src_color.alpha = LV_OPA_MIX2(src_color.alpha, opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color = src_buf_al88[x]; + src_color.alpha = LV_OPA_MIX2(src_color.alpha, mask_buf[x]); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color = src_buf_al88[x]; + src_color.alpha = LV_OPA_MIX3(src_color.alpha, mask_buf[x], opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color = src_buf_al88[x]; + if(mask_buf == NULL) src_color.alpha = LV_OPA_MIX2(src_color.alpha, opa); + else src_color.alpha = LV_OPA_MIX3(src_color.alpha, mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_al88[x], src_color, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } +} + +#if LV_DRAW_SW_SUPPORT_RGB565 + +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color16a_t * dest_buf_al88 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16_t * src_buf_c16 = (const lv_color16_t *)dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x, y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_al88[x].lumi = lv_color16_luminance(src_buf_c16[x]); + dest_buf_al88[x].alpha = 255; + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_WITH_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color16_luminance(src_buf_c16[x]); + src_color.alpha = opa; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_WITH_MASK(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color16_luminance(src_buf_c16[x]); + src_color.alpha = mask_buf[x]; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + mask_buf += mask_stride; + } + } + } + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color16_luminance(src_buf_c16[x]); + src_color.alpha = LV_OPA_MIX2(mask_buf[x], opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color16_luminance(src_buf_c16[x]); + if(mask_buf == NULL) src_color.alpha = opa; + else src_color.alpha = LV_OPA_MIX2(mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_al88[x], src_color, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 + +static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, + const uint8_t src_px_size) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color16a_t * dest_buf_al88 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + /*Special case*/ + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88(dsc, src_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + dest_buf_al88[dest_x].lumi = lv_color24_luminance(&src_buf_u8[src_x]); + dest_buf_al88[dest_x].alpha = 255; + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_u8 += src_stride; + } + } + } + if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_WITH_OPA(dsc, dest_px_size, src_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + lv_color16a_t src_color; + src_color.lumi = lv_color24_luminance(&src_buf_u8[src_x]); + src_color.alpha = opa; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[dest_x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_u8 += src_stride; + } + } + } + if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_WITH_MASK(dsc, dest_px_size, src_px_size)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x += src_px_size) { + lv_color16a_t src_color; + src_color.lumi = lv_color24_luminance(&src_buf_u8[src_x]); + src_color.alpha = mask_buf[mask_x]; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[dest_x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_u8 += src_stride; + mask_buf += mask_stride; + } + } + } + if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(dsc, dest_px_size, src_px_size)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x += src_px_size) { + lv_color16a_t src_color; + src_color.lumi = lv_color24_luminance(&src_buf_u8[src_x]); + src_color.alpha = LV_OPA_MIX2(mask_buf[mask_x], opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[dest_x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_u8 += src_stride; + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + lv_color16a_t src_color; + src_color.lumi = lv_color24_luminance(&src_buf_u8[src_x]); + if(mask_buf == NULL) src_color.alpha = opa; + else src_color.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + + blend_non_normal_pixel(&dest_buf_al88[dest_x], src_color, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_u8 += src_stride; + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color16a_t * dest_buf_al88 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color32_t * src_buf_c32 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color32_luminance(src_buf_c32[x]); + src_color.alpha = src_buf_c32[x].alpha; + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color32_luminance(src_buf_c32[x]); + src_color.alpha = LV_OPA_MIX2(src_buf_c32[x].alpha, opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color32_luminance(src_buf_c32[x]); + src_color.alpha = LV_OPA_MIX2(src_buf_c32[x].alpha, mask_buf[x]); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_AL88_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color32_luminance(src_buf_c32[x]); + src_color.alpha = LV_OPA_MIX3(src_buf_c32[x].alpha, mask_buf[x], opa); + lv_color_16a_16a_mix(src_color, &dest_buf_al88[x], &cache); + } + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color16a_t src_color; + src_color.lumi = lv_color32_luminance(src_buf_c32[x]); + src_color.alpha = src_buf_c32[x].alpha; + if(mask_buf == NULL) src_color.alpha = LV_OPA_MIX2(src_color.alpha, opa); + else src_color.alpha = LV_OPA_MIX3(src_color.alpha, mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_al88[x], src_color, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_al88 = drawbuf_next_row(dest_buf_al88, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} + +#endif + +/** + * Check if two AL88 colors are equal + * @param c1 the first color + * @param c2 the second color + * @return true: equal + */ +static inline bool lv_color16a_eq(lv_color16a_t c1, lv_color16a_t c2) +{ + return *((uint16_t *)&c1) == *((uint16_t *)&c2); +} + +static inline lv_color16a_t LV_ATTRIBUTE_FAST_MEM lv_color_mix16a(lv_color16a_t fg, lv_color16a_t bg) +{ +#if 0 + if(fg.alpha >= LV_OPA_MAX) { + fg.alpha = bg.alpha; + return fg; + } + if(fg.alpha <= LV_OPA_MIN) { + return bg; + } +#endif + bg.lumi = (uint32_t)((uint32_t)fg.lumi * fg.alpha + (uint32_t)bg.lumi * (255 - fg.alpha)) >> 8; + return bg; +} + +static inline void LV_ATTRIBUTE_FAST_MEM lv_color_16a_16a_mix(lv_color16a_t fg, lv_color16a_t * bg, + lv_color_mix_alpha_cache_t * cache) +{ + /*Pick the foreground if it's fully opaque or the Background is fully transparent*/ + if(fg.alpha >= LV_OPA_MAX || bg->alpha <= LV_OPA_MIN) { + *bg = fg; + } + /*Transparent foreground: use the Background*/ + else if(fg.alpha <= LV_OPA_MIN) { + /* no need to copy */ + } + /*Opaque background: use simple mix*/ + else if(bg->alpha == 255) { + *bg = lv_color_mix16a(fg, *bg); + } + /*Both colors have alpha. Expensive calculation needs to be applied*/ + else { + /*Save the parameters and the result. If they will be asked again don't compute again*/ + + /*Update the ratio and the result alpha value if the input alpha values change*/ + if(bg->alpha != cache->bg_saved.alpha || fg.alpha != cache->fg_saved.alpha) { + /*Info: + * https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/ + cache->res_alpha_saved = 255 - LV_OPA_MIX2(255 - fg.alpha, 255 - bg->alpha); + LV_ASSERT(cache->res_alpha_saved != 0); + cache->ratio_saved = (uint32_t)((uint32_t)fg.alpha * 255) / cache->res_alpha_saved; + } + + if(!lv_color16a_eq(*bg, cache->bg_saved) || !lv_color16a_eq(fg, cache->fg_saved)) { + cache->fg_saved = fg; + cache->bg_saved = *bg; + fg.alpha = cache->ratio_saved; + cache->res_saved = lv_color_mix16a(fg, *bg); + cache->res_saved.alpha = cache->res_alpha_saved; + } + + *bg = cache->res_saved; + } +} + +void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cache) +{ + lv_memzero(&cache->fg_saved, sizeof(lv_color16a_t)); + lv_memzero(&cache->bg_saved, sizeof(lv_color16a_t)); + lv_memzero(&cache->res_saved, sizeof(lv_color16a_t)); + cache->res_alpha_saved = 255; + cache->ratio_saved = 255; +} + +#if LV_DRAW_SW_SUPPORT_I1 + +static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) +{ + return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; +} + +#endif + +static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(lv_color16a_t * dest, lv_color16a_t src, + lv_blend_mode_t mode, lv_color_mix_alpha_cache_t * cache) +{ + lv_color16a_t res; + switch(mode) { + case LV_BLEND_MODE_ADDITIVE: + res.lumi = LV_MIN(dest->lumi + src.lumi, 255); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res.lumi = LV_MAX(dest->lumi - src.lumi, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res.lumi = (dest->lumi * src.lumi) >> 8; + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", mode); + return; + } + res.alpha = src.alpha; + lv_color_16a_16a_mix(res, dest, cache); +} + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) +{ + return (void *)((uint8_t *)buf + stride); +} + +#endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.h new file mode 100644 index 000000000..b83523b92 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_al88.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_al88.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_AL88_H +#define LV_DRAW_SW_BLEND_TO_AL88_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_al88(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_al88(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_AL88_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c index c78c10cfd..4bf3ef491 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_blend.c * */ @@ -9,7 +9,9 @@ #include "lv_draw_sw_blend_to_argb8888.h" #if LV_USE_DRAW_SW -#include "lv_draw_sw_blend.h" +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +#include "lv_draw_sw_blend_private.h" #include "../../../misc/lv_math.h" #include "../../../display/lv_display.h" #include "../../../core/lv_refr.h" @@ -44,12 +46,32 @@ typedef struct { * STATIC PROTOTYPES **********************/ -static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc); +#if LV_DRAW_SW_SUPPORT_AL88 + static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif -static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, +#if LV_DRAW_SW_SUPPORT_I1 + static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + + static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, int32_t bit_idx); +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size); +#endif -static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc); +static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_8_32_mix(const uint8_t src, lv_color32_t * dest, uint8_t mix); static inline lv_color32_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color_32_32_mix(lv_color32_t fg, lv_color32_t bg, lv_color_mix_alpha_cache_t * cache); @@ -84,6 +106,38 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888 + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_WITH_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_WITH_MASK + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888 + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(...) LV_RESULT_INVALID #endif @@ -132,11 +186,27 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888 + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + /********************** * GLOBAL FUNCTIONS **********************/ -void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(_lv_draw_sw_blend_fill_dsc_t * dsc) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_fill_dsc_t * dsc) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -245,21 +315,42 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(_lv_draw_sw_blend_ } } -void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_argb8888(_lv_draw_sw_blend_image_dsc_t * dsc) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_argb8888(lv_draw_sw_blend_image_dsc_t * dsc) { switch(dsc->src_color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 case LV_COLOR_FORMAT_RGB565: rgb565_image_blend(dsc); break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, 3); break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 case LV_COLOR_FORMAT_XRGB8888: rgb888_image_blend(dsc, 4); break; +#endif case LV_COLOR_FORMAT_ARGB8888: argb8888_image_blend(dsc); break; +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + l8_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + al88_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + i1_image_blend(dsc); + break; +#endif default: LV_LOG_WARN("Not supported source color format"); break; @@ -270,7 +361,288 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_argb8888(_lv_draw_sw_blend_ * STATIC FUNCTIONS **********************/ -static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc) +#if LV_DRAW_SW_SUPPORT_I1 +static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color32_t * dest_buf_c32 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_i1 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + dest_buf_c32[dest_x].alpha = chan_val; + dest_buf_c32[dest_x].red = chan_val; + dest_buf_c32[dest_x].green = chan_val; + dest_buf_c32[dest_x].blue = chan_val; + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_32_mix(chan_val, &dest_buf_c32[dest_x], opa); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_32_mix(chan_val, &dest_buf_c32[dest_x], mask_buf[src_x]); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_32_mix(chan_val, &dest_buf_c32[dest_x], LV_OPA_MIX2(mask_buf[src_x], opa)); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = get_bit(src_buf_i1, src_x) * 255; + src_argb.green = src_argb.red; + src_argb.blue = src_argb.red; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_c32[dest_x], src_argb, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_AL88 +static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color32_t * dest_buf_c32 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16a_t * src_buf_al88 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + /* + dest_buf_c32[dest_x].alpha = src_buf_al88[src_x].alpha; + dest_buf_c32[dest_x].red = src_buf_al88[src_x].lumi; + dest_buf_c32[dest_x].green = src_buf_al88[src_x].lumi; + dest_buf_c32[dest_x].blue = src_buf_al88[src_x].lumi; + */ + lv_color_8_32_mix(src_buf_al88[src_x].lumi, &dest_buf_c32[dest_x], src_buf_al88[src_x].alpha); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_32_mix(src_buf_al88[src_x].lumi, &dest_buf_c32[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa)); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_32_mix(src_buf_al88[src_x].lumi, &dest_buf_c32[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, + mask_buf[src_x])); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_32_mix(src_buf_al88[src_x].lumi, &dest_buf_c32[dest_x], LV_OPA_MIX3(src_buf_al88[src_x].alpha, + mask_buf[src_x], opa)); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = src_buf_al88[src_x].lumi; + src_argb.green = src_buf_al88[src_x].lumi; + src_argb.blue = src_buf_al88[src_x].lumi; + if(mask_buf == NULL) src_argb.alpha = LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa); + else src_argb.alpha = LV_OPA_MIX3(src_buf_al88[src_x].alpha, mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_c32[dest_x], src_argb, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + +static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + lv_color32_t * dest_buf_c32 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + dest_buf_c32[dest_x].alpha = src_buf_l8[src_x]; + dest_buf_c32[dest_x].red = src_buf_l8[src_x]; + dest_buf_c32[dest_x].green = src_buf_l8[src_x]; + dest_buf_c32[dest_x].blue = src_buf_l8[src_x]; + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_32_mix(src_buf_l8[src_x], &dest_buf_c32[dest_x], opa); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_32_mix(src_buf_l8[src_x], &dest_buf_c32[dest_x], mask_buf[src_x]); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_32_mix(src_buf_l8[src_x], &dest_buf_c32[dest_x], LV_OPA_MIX2(mask_buf[src_x], opa)); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = src_buf_l8[src_x]; + src_argb.green = src_buf_l8[src_x]; + src_argb.blue = src_buf_l8[src_x]; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_c32[dest_x], src_argb, dsc->blend_mode, &cache); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -365,7 +737,11 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(_lv_draw_sw_blend_image_dsc } } -static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 + +static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) { int32_t w = dsc->dest_w; @@ -483,7 +859,9 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(_lv_draw_sw_blend_image_dsc } } -static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc) +#endif + +static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -571,6 +949,25 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(_lv_draw_sw_blend_image_d } } +static inline void LV_ATTRIBUTE_FAST_MEM lv_color_8_32_mix(const uint8_t src, lv_color32_t * dest, uint8_t mix) +{ + + if(mix == 0) return; + + dest->alpha = 255; + if(mix >= LV_OPA_MAX) { + dest->red = src; + dest->green = src; + dest->blue = src; + } + else { + lv_opa_t mix_inv = 255 - mix; + dest->red = (uint32_t)((uint32_t)src * mix + dest->red * mix_inv) >> 8; + dest->green = (uint32_t)((uint32_t)src * mix + dest->green * mix_inv) >> 8; + dest->blue = (uint32_t)((uint32_t)src * mix + dest->blue * mix_inv) >> 8; + } +} + static inline lv_color32_t LV_ATTRIBUTE_FAST_MEM lv_color_32_32_mix(lv_color32_t fg, lv_color32_t bg, lv_color_mix_alpha_cache_t * cache) { @@ -595,7 +992,7 @@ static inline lv_color32_t LV_ATTRIBUTE_FAST_MEM lv_color_32_32_mix(lv_color32_t /*Info: * https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/ cache->res_alpha_saved = 255 - LV_OPA_MIX2(255 - fg.alpha, 255 - bg.alpha); - LV_ASSERT(cache->ratio_saved != 0); + LV_ASSERT(cache->res_alpha_saved != 0); cache->ratio_saved = (uint32_t)((uint32_t)fg.alpha * 255) / cache->res_alpha_saved; } @@ -620,6 +1017,15 @@ void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cache) cache->ratio_saved = 255; } +#if LV_DRAW_SW_SUPPORT_I1 + +static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) +{ + return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; +} + +#endif + static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(lv_color32_t * dest, lv_color32_t src, lv_blend_mode_t mode, lv_color_mix_alpha_cache_t * cache) { @@ -654,3 +1060,5 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui } #endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h index cfd431683..2046c23f3 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.h @@ -1,10 +1,10 @@ /** - * @file lv_draw_sw_blend_argb8888.h + * @file lv_draw_sw_blend_to_argb8888.h * */ -#ifndef LV_DRAW_SW_BLEND_ARGB8888_H -#define LV_DRAW_SW_BLEND_ARGB8888_H +#ifndef LV_DRAW_SW_BLEND_TO_ARGB8888_H +#define LV_DRAW_SW_BLEND_TO_ARGB8888_H #ifdef __cplusplus extern "C" { @@ -28,9 +28,9 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_argb8888(_lv_draw_sw_blend_fill_dsc_t * dsc); +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_fill_dsc_t * dsc); -void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_argb8888(_lv_draw_sw_blend_image_dsc_t * dsc); +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_argb8888(lv_draw_sw_blend_image_dsc_t * dsc); /********************** * MACROS @@ -42,4 +42,4 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_argb8888(_lv_draw_sw_ } /*extern "C"*/ #endif -#endif /*LV_DRAW_SW_BLEND_ARGB8888_H*/ +#endif /*LV_DRAW_SW_BLEND_TO_ARGB8888_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c new file mode 100644 index 000000000..1e056ee66 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c @@ -0,0 +1,1117 @@ +/** + * @file lv_draw_sw_blend_to_i1.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_to_i1.h" +#if LV_USE_DRAW_SW + +#include "lv_draw_sw_blend_private.h" +#include "../../../misc/lv_math.h" +#include "../../../display/lv_display.h" +#include "../../../core/lv_refr.h" +#include "../../../misc/lv_color.h" +#include "../../../stdlib/lv_string.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + #include "neon/lv_blend_neon.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM + #include "helium/lv_blend_helium.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #include LV_DRAW_SW_ASM_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +#if LV_DRAW_SW_SUPPORT_L8 + static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_AL88 + static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, + const uint8_t src_px_size); +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_8_8_mix(const uint8_t src, uint8_t * dest, uint8_t mix); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel(uint8_t * dest_buf, int32_t dest_x, + lv_color32_t src, + lv_blend_mode_t mode); + + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ set_bit(uint8_t * buf, int32_t bit_idx); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ clear_bit(uint8_t * buf, int32_t bit_idx); + +static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, int32_t bit_idx); + +static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define I1_LUM_THRESHOLD 127 + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_I1 + #define LV_DRAW_SW_COLOR_BLEND_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_I1_WITH_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_I1_WITH_MASK + #define LV_DRAW_SW_COLOR_BLEND_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_i1(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + const lv_opa_t * mask = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + int32_t dest_stride = dsc->dest_stride; + + uint8_t src_color = lv_color_luminance(dsc->color) / (I1_LUM_THRESHOLD + 1); + uint8_t * dest_buf = dsc->dest_buf; + + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + /* Simple fill */ + if(mask == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_I1(dsc)) { + for(int32_t y = 0; y < h; y++) { + for(int32_t x = 0; x < w; x++) { + if(src_color) { + set_bit(dest_buf, x + bit_ofs); + } + else { + clear_bit(dest_buf, x + bit_ofs); + } + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + } + /* Opacity only */ + else if(mask == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_I1_WITH_OPA(dsc)) { + for(int32_t y = 0; y < h; y++) { + for(int32_t x = 0; x < w; x++) { + uint8_t * dest_bit = &dest_buf[(x + bit_ofs) / 8]; + uint8_t current_bit = (*dest_bit >> (7 - ((x + bit_ofs) % 8))) & 0x01; + uint8_t new_bit = (opa * src_color + (255 - opa) * current_bit) / 255; + if(new_bit) { + set_bit(dest_buf, x + bit_ofs); + } + else { + clear_bit(dest_buf, x + bit_ofs); + } + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + } + /* Masked with full opacity */ + else if(mask && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_I1_WITH_MASK(dsc)) { + for(int32_t y = 0; y < h; y++) { + for(int32_t x = 0; x < w; x++) { + uint8_t mask_val = mask[x]; + if(mask_val == LV_OPA_TRANSP) continue; + if(mask_val == LV_OPA_COVER) { + if(src_color) { + set_bit(dest_buf, x + bit_ofs); + } + else { + clear_bit(dest_buf, x + bit_ofs); + } + } + else { + uint8_t * dest_bit = &dest_buf[(x + bit_ofs) / 8]; + uint8_t current_bit = (*dest_bit >> (7 - ((x + bit_ofs) % 8))) & 0x01; + uint8_t new_bit = (mask_val * src_color + (255 - mask_val) * current_bit) / 255; + if(new_bit) { + set_bit(dest_buf, x + bit_ofs); + } + else { + clear_bit(dest_buf, x + bit_ofs); + } + } + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + } + /* Masked with opacity */ + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_I1_MIX_MASK_OPA(dsc)) { + for(int32_t y = 0; y < h; y++) { + for(int32_t x = 0; x < w; x++) { + uint8_t mask_val = mask[x]; + if(mask_val == LV_OPA_TRANSP) continue; + uint8_t * dest_bit = &dest_buf[(x + bit_ofs) / 8]; + uint8_t current_bit = (*dest_bit >> (7 - ((x + bit_ofs) % 8))) & 0x01; + uint8_t blended_opa = (mask_val * opa) / 255; + uint8_t new_bit = (blended_opa * src_color + (255 - blended_opa) * current_bit) / 255; + if(new_bit) { + set_bit(dest_buf, x + bit_ofs); + } + else { + clear_bit(dest_buf, x + bit_ofs); + } + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + } +} + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_i1(lv_draw_sw_blend_image_dsc_t * dsc) +{ + switch(dsc->src_color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + rgb565_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + rgb888_image_blend(dsc, 3); + break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 + case LV_COLOR_FORMAT_XRGB8888: + rgb888_image_blend(dsc, 4); + break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 + case LV_COLOR_FORMAT_ARGB8888: + argb8888_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + l8_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + al88_image_blend(dsc); + break; +#endif + case LV_COLOR_FORMAT_I1: + i1_image_blend(dsc); + break; + default: + LV_LOG_WARN("Not supported source color format"); + break; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_i1 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_i1 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + if(get_bit(src_buf_i1, src_x)) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t src = get_bit(src_buf_i1, src_x); + uint8_t dest = get_bit(dest_buf_i1, dest_x + bit_ofs); + uint8_t blended = (src * opa + dest * (255 - opa)); + if(blended > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t mask_val = mask_buf[src_x]; + uint8_t src = get_bit(src_buf_i1, src_x); + uint8_t dest = get_bit(dest_buf_i1, dest_x + bit_ofs); + uint8_t blended = (src * mask_val + dest * (255 - mask_val)); + if(blended > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t mask_val = mask_buf[src_x]; + if(mask_val == LV_OPA_TRANSP) continue; + uint8_t src = get_bit(src_buf_i1, src_x); + uint8_t dest = get_bit(dest_buf_i1, dest_x + bit_ofs); + uint8_t blend_opa = LV_OPA_MIX2(mask_val, opa); + uint8_t blended = (src * blend_opa + dest * (255 - blend_opa)); + if(blended > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = get_bit(src_buf_i1, src_x) * 255; + src_argb.green = src_argb.red; + src_argb.blue = src_argb.red; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(dest_buf_i1, dest_x + bit_ofs, src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } +} + +#if LV_DRAW_SW_SUPPORT_L8 +static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_i1 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t src_x, dest_x; + int32_t y; + + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + if(src_buf_l8[src_x] > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_buf_l8[src_x], &dest_val, opa); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t src_luminance = src_buf_l8[src_x]; + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_luminance, &dest_val, mask_buf[src_x]); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t src_luminance = src_buf_l8[src_x]; + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_luminance, &dest_val, LV_OPA_MIX2(mask_buf[src_x], opa)); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(src_x = 0; src_x < w; src_x++) { + src_argb.red = src_buf_l8[src_x]; + src_argb.green = src_buf_l8[src_x]; + src_argb.blue = src_buf_l8[src_x]; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[src_x], opa); + blend_non_normal_pixel(dest_buf_i1, src_x + bit_ofs, src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_AL88 +static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_i1 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16a_t * src_buf_al88 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_val, src_buf_al88[src_x].alpha); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_val, LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa)); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_val, LV_OPA_MIX2(src_buf_al88[src_x].alpha, mask_buf[src_x])); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t dest_val = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_val, LV_OPA_MIX3(src_buf_al88[src_x].alpha, mask_buf[src_x], opa)); + if(dest_val > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = src_buf_al88[src_x].lumi; + src_argb.green = src_buf_al88[src_x].lumi; + src_argb.blue = src_buf_al88[src_x].lumi; + if(mask_buf == NULL) src_argb.alpha = LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa); + else src_argb.alpha = LV_OPA_MIX3(src_buf_al88[src_x].alpha, mask_buf[src_x], opa); + blend_non_normal_pixel(dest_buf_i1, dest_x + bit_ofs, src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 +static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_i1 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color32_t * src_buf_c32 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t x; + int32_t y; + + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint8_t src = lv_color32_luminance(src_buf_c32[x]); + uint8_t dest = get_bit(dest_buf_i1, x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, src_buf_c32[x].alpha); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint8_t src = lv_color32_luminance(src_buf_c32[x]); + uint8_t dest = get_bit(dest_buf_i1, x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, LV_OPA_MIX2(opa, src_buf_c32[x].alpha)); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint8_t src = lv_color32_luminance(src_buf_c32[x]); + uint8_t dest = get_bit(dest_buf_i1, x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, LV_OPA_MIX2(mask_buf[x], src_buf_c32[x].alpha)); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint8_t src = lv_color32_luminance(src_buf_c32[x]); + uint8_t dest = get_bit(dest_buf_i1, x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, LV_OPA_MIX3(opa, mask_buf[x], src_buf_c32[x].alpha)); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color32_t color_argb = src_buf_c32[x]; + if(mask_buf == NULL) color_argb.alpha = LV_OPA_MIX2(color_argb.alpha, opa); + else color_argb.alpha = LV_OPA_MIX3(color_argb.alpha, mask_buf[x], opa); + blend_non_normal_pixel(dest_buf_i1, x + bit_ofs, color_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 +static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, + const uint8_t src_px_size) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_i1 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_rgb888 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + /*Special case*/ + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + uint8_t src = lv_color24_luminance(&src_buf_rgb888[src_x]); + if(src > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_rgb888 = drawbuf_next_row(src_buf_rgb888, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + uint8_t src = lv_color24_luminance(&src_buf_rgb888[src_x]); + uint8_t dest = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, opa); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_rgb888 = drawbuf_next_row(src_buf_rgb888, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_WITH_MASK(dsc)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x += src_px_size) { + uint8_t src = lv_color24_luminance(&src_buf_rgb888[src_x]); + uint8_t dest = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, mask_buf[mask_x]); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_rgb888 = drawbuf_next_row(src_buf_rgb888, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(dsc)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x += src_px_size) { + uint8_t src = lv_color24_luminance(&src_buf_rgb888[src_x]); + uint8_t dest = get_bit(dest_buf_i1, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, LV_OPA_MIX2(mask_buf[mask_x], opa)); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_i1, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_i1, dest_x + bit_ofs); + } + } + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_rgb888 = drawbuf_next_row(src_buf_rgb888, src_stride); + mask_buf += mask_stride; + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + src_argb.red = src_buf_rgb888[src_x + 2]; + src_argb.green = src_buf_rgb888[src_x + 1]; + src_argb.blue = src_buf_rgb888[src_x + 0]; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + + blend_non_normal_pixel(dest_buf_i1, dest_x + bit_ofs, src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_i1 = drawbuf_next_row(dest_buf_i1, dest_stride); + src_buf_rgb888 = drawbuf_next_row(src_buf_rgb888, src_stride); + } + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16_t * src_buf_c16 = (const lv_color16_t *)dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + int32_t bit_ofs = dsc->relative_area.x1 % 8; + + int32_t src_x; + int32_t dest_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1(dsc)) { + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t src = lv_color16_luminance(src_buf_c16[src_x]); + if(src > I1_LUM_THRESHOLD) { + set_bit(dest_buf_u8, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_u8, dest_x + bit_ofs); + } + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t src = lv_color16_luminance(src_buf_c16[src_x]); + uint8_t dest = get_bit(dest_buf_u8, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, opa); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_u8, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_u8, dest_x + bit_ofs); + } + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_WITH_MASK(dsc)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x++) { + uint8_t src = lv_color16_luminance(src_buf_c16[src_x]); + uint8_t dest = get_bit(dest_buf_u8, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, mask_buf[mask_x]); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_u8, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_u8, dest_x + bit_ofs); + } + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(dsc)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x++) { + uint8_t src = lv_color16_luminance(src_buf_c16[src_x]); + uint8_t dest = get_bit(dest_buf_u8, dest_x + bit_ofs) * 255; + lv_color_8_8_mix(src, &dest, LV_OPA_MIX2(mask_buf[mask_x], opa)); + if(dest > I1_LUM_THRESHOLD) { + set_bit(dest_buf_u8, dest_x + bit_ofs); + } + else { + clear_bit(dest_buf_u8, dest_x + bit_ofs); + } + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; src_x++, dest_x++) { + src_argb.red = (src_buf_c16[src_x].red * 2106) >> 8; + src_argb.green = (src_buf_c16[src_x].green * 1037) >> 8; + src_argb.blue = (src_buf_c16[src_x].blue * 2106) >> 8; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[src_x], opa); + + blend_non_normal_pixel(dest_buf_u8, dest_x + bit_ofs, src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } +} +#endif + +static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest_buf, int32_t dest_x, lv_color32_t src, + lv_blend_mode_t mode) +{ + uint8_t res; + int32_t src_lumi = lv_color32_luminance(src); + uint8_t dest_lumi = get_bit(dest_buf, dest_x) * 255; + switch(mode) { + case LV_BLEND_MODE_ADDITIVE: + res = LV_MIN(dest_lumi + src_lumi, 255); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = LV_MAX(dest_lumi - src_lumi, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = (dest_lumi * src_lumi) >> 8; + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", mode); + return; + } + + lv_color_8_8_mix(res, &dest_lumi, src.alpha); + if(dest_lumi > I1_LUM_THRESHOLD) { + set_bit(dest_buf, dest_x); + } + else { + clear_bit(dest_buf, dest_x); + } +} + +static inline void LV_ATTRIBUTE_FAST_MEM lv_color_8_8_mix(const uint8_t src, uint8_t * dest, uint8_t mix) +{ + + if(mix == 0) return; + + if(mix >= LV_OPA_MAX) { + *dest = src; + } + else { + lv_opa_t mix_inv = 255 - mix; + *dest = (uint32_t)((uint32_t)src * mix + dest[0] * mix_inv) >> 8; + } +} + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) +{ + return (void *)((uint8_t *)buf + stride); +} + +static inline void LV_ATTRIBUTE_FAST_MEM set_bit(uint8_t * buf, int32_t bit_idx) +{ + buf[bit_idx / 8] |= (1 << (7 - (bit_idx % 8))); +} + +static inline void LV_ATTRIBUTE_FAST_MEM clear_bit(uint8_t * buf, int32_t bit_idx) +{ + buf[bit_idx / 8] &= ~(1 << (7 - (bit_idx % 8))); +} + +static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) +{ + return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; +} + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.h new file mode 100644 index 000000000..5d72523de --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_i1.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_i1.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_I1_H +#define LV_DRAW_SW_BLEND_TO_I1_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_i1(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_i1(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_I1_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c new file mode 100644 index 000000000..fa9c0251f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c @@ -0,0 +1,897 @@ +/** + * @file lv_draw_sw_blend_l8.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_to_l8.h" +#if LV_USE_DRAW_SW + +#if LV_DRAW_SW_SUPPORT_L8 + +#include "lv_draw_sw_blend_private.h" +#include "../../../misc/lv_math.h" +#include "../../../display/lv_display.h" +#include "../../../core/lv_refr.h" +#include "../../../misc/lv_color.h" +#include "../../../stdlib/lv_string.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + #include "neon/lv_blend_neon.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM + #include "helium/lv_blend_helium.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #include LV_DRAW_SW_ASM_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +#if LV_DRAW_SW_SUPPORT_I1 + static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + + static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, int32_t bit_idx); +#endif + +static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +#if LV_DRAW_SW_SUPPORT_AL88 + static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, + const uint8_t src_px_size); +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_8_8_mix(const uint8_t src, uint8_t * dest, uint8_t mix); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel(uint8_t * dest, lv_color32_t src, + lv_blend_mode_t mode); + +static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_L8 + #define LV_DRAW_SW_COLOR_BLEND_TO_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_L8_WITH_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_L8_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_L8_WITH_MASK + #define LV_DRAW_SW_COLOR_BLEND_TO_L8_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_L8_MIX_MASK_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_L8_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8 + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_WITH_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_WITH_MASK + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8 + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_WITH_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_WITH_MASK + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_MIX_MASK_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8 + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_MASK + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_MIX_MASK_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8 + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8 + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_l8(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + const lv_opa_t * mask = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + int32_t dest_stride = dsc->dest_stride; + + int32_t x; + int32_t y; + + LV_UNUSED(w); + LV_UNUSED(h); + LV_UNUSED(x); + LV_UNUSED(y); + LV_UNUSED(opa); + LV_UNUSED(mask); + LV_UNUSED(mask_stride); + LV_UNUSED(dest_stride); + + /*Simple fill*/ + if(mask == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_L8(dsc)) { + uint8_t color8 = lv_color_luminance(dsc->color); + uint8_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w - 16; x += 16) { + dest_buf[x + 0] = color8; + dest_buf[x + 1] = color8; + dest_buf[x + 2] = color8; + dest_buf[x + 3] = color8; + + dest_buf[x + 4] = color8; + dest_buf[x + 5] = color8; + dest_buf[x + 6] = color8; + dest_buf[x + 7] = color8; + + dest_buf[x + 8] = color8; + dest_buf[x + 9] = color8; + dest_buf[x + 10] = color8; + dest_buf[x + 11] = color8; + + dest_buf[x + 12] = color8; + dest_buf[x + 13] = color8; + dest_buf[x + 14] = color8; + dest_buf[x + 15] = color8; + } + for(; x < w; x ++) { + dest_buf[x] = color8; + } + + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + } + /*Opacity only*/ + else if(mask == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_L8_WITH_OPA(dsc)) { + uint8_t color8 = lv_color_luminance(dsc->color); + uint8_t * dest_buf = dsc->dest_buf; + + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(color8, &dest_buf[x], opa); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + + } + /*Masked with full opacity*/ + else if(mask && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_L8_WITH_MASK(dsc)) { + uint8_t color8 = lv_color_luminance(dsc->color); + uint8_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(color8, &dest_buf[x], mask[x]); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + + } + /*Masked with opacity*/ + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_L8_MIX_MASK_OPA(dsc)) { + uint8_t color8 = lv_color_luminance(dsc->color); + uint8_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(color8, &dest_buf[x], LV_OPA_MIX2(mask[x], opa)); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + } +} + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_l8(lv_draw_sw_blend_image_dsc_t * dsc) +{ + switch(dsc->src_color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + rgb565_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + rgb888_image_blend(dsc, 3); + break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 + case LV_COLOR_FORMAT_XRGB8888: + rgb888_image_blend(dsc, 4); + break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 + case LV_COLOR_FORMAT_ARGB8888: + argb8888_image_blend(dsc); + break; +#endif + case LV_COLOR_FORMAT_L8: + l8_image_blend(dsc); + break; +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + al88_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + i1_image_blend(dsc); + break; +#endif + default: + LV_LOG_WARN("Not supported source color format"); + break; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#if LV_DRAW_SW_SUPPORT_I1 +static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_l8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_i1 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_8_mix(chan_val, &dest_buf_l8[dest_x], opa); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_8_mix(chan_val, &dest_buf_l8[dest_x], opa); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_8_mix(chan_val, &dest_buf_l8[dest_x], mask_buf[src_x]); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_8_mix(chan_val, &dest_buf_l8[dest_x], LV_OPA_MIX2(mask_buf[src_x], opa)); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = get_bit(src_buf_i1, src_x) * 255; + src_argb.green = src_argb.red; + src_argb.blue = src_argb.red; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_l8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } +} +#endif + +static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_l8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8(dsc)) { + for(y = 0; y < h; y++) { + lv_memcpy(dest_buf_l8, src_buf_l8, w); + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_l8[src_x], &dest_buf_l8[dest_x], opa); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_l8[src_x], &dest_buf_l8[dest_x], mask_buf[src_x]); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_l8[src_x], &dest_buf_l8[dest_x], LV_OPA_MIX2(mask_buf[src_x], opa)); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = src_buf_l8[src_x]; + src_argb.green = src_buf_l8[src_x]; + src_argb.blue = src_buf_l8[src_x]; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_l8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } +} + +#if LV_DRAW_SW_SUPPORT_AL88 + +static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_l8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16a_t * src_buf_al88 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_buf_l8[dest_x], src_buf_al88[src_x].alpha); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_buf_l8[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa)); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_buf_l8[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, + mask_buf[src_x])); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(src_buf_al88[src_x].lumi, &dest_buf_l8[dest_x], LV_OPA_MIX3(src_buf_al88[src_x].alpha, mask_buf[src_x], + opa)); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x++, src_x++) { + src_argb.red = src_buf_al88[src_x].lumi; + src_argb.green = src_buf_al88[src_x].lumi; + src_argb.blue = src_buf_al88[src_x].lumi; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_l8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16_t * src_buf_c16 = (const lv_color16_t *)dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t src_x; + int32_t dest_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8(dsc)) { + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; dest_x++, src_x++) { + dest_buf_u8[dest_x] = lv_color16_luminance(src_buf_c16[src_x]); + } + dest_buf_u8 += dest_stride; + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_WITH_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(lv_color16_luminance(src_buf_c16[src_x]), &dest_buf_u8[dest_x], opa); + } + dest_buf_u8 += dest_stride; + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_WITH_MASK(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(lv_color16_luminance(src_buf_c16[src_x]), &dest_buf_u8[dest_x], mask_buf[src_x]); + } + dest_buf_u8 += dest_stride; + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + mask_buf += mask_stride; + } + } + } + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; dest_x++, src_x++) { + lv_color_8_8_mix(lv_color16_luminance(src_buf_c16[src_x]), &dest_buf_u8[dest_x], LV_OPA_MIX2(opa, mask_buf[src_x])); + } + dest_buf_u8 += dest_stride; + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(src_x = 0, dest_x = 0; src_x < w; src_x++, dest_x++) { + src_argb.red = (src_buf_c16[src_x].red * 2106) >> 8; + src_argb.green = (src_buf_c16[src_x].green * 1037) >> 8; + src_argb.blue = (src_buf_c16[src_x].blue * 2106) >> 8; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[src_x], opa); + blend_non_normal_pixel(&dest_buf_u8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_u8 += dest_stride; + src_buf_c16 = drawbuf_next_row(src_buf_c16, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 + +static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, + const uint8_t src_px_size) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_l8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + /*Special case*/ + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8(dsc, src_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + dest_buf_l8[dest_x] = lv_color24_luminance(&src_buf_u8[src_x]); + } + dest_buf_l8 += dest_stride; + src_buf_u8 += src_stride; + } + } + } + if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_WITH_OPA(dsc, dest_px_size, src_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + lv_color_8_8_mix(lv_color24_luminance(&src_buf_u8[src_x]), &dest_buf_l8[dest_x], opa); + } + dest_buf_l8 += dest_stride; + src_buf_u8 += src_stride; + } + } + } + if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_WITH_MASK(dsc, dest_px_size, src_px_size)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x += src_px_size) { + lv_color_8_8_mix(lv_color24_luminance(&src_buf_u8[src_x]), &dest_buf_l8[dest_x], mask_buf[mask_x]); + } + dest_buf_l8 += dest_stride; + src_buf_u8 += src_stride; + mask_buf += mask_stride; + } + } + } + if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(dsc, dest_px_size, src_px_size)) { + uint32_t mask_x; + for(y = 0; y < h; y++) { + for(mask_x = 0, dest_x = 0, src_x = 0; dest_x < w; mask_x++, dest_x++, src_x += src_px_size) { + lv_color_8_8_mix(lv_color24_luminance(&src_buf_u8[src_x]), &dest_buf_l8[dest_x], LV_OPA_MIX2(opa, mask_buf[mask_x])); + } + dest_buf_l8 += dest_stride; + src_buf_u8 += src_stride; + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + src_argb.red = src_buf_u8[src_x + 2]; + src_argb.green = src_buf_u8[src_x + 1]; + src_argb.blue = src_buf_u8[src_x + 0]; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + + blend_non_normal_pixel(&dest_buf_l8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_l8 += dest_stride; + src_buf_u8 += src_stride; + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_l8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color32_t * src_buf_c32 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(lv_color32_luminance(src_buf_c32[x]), &dest_buf_l8[x], src_buf_c32[x].alpha); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(lv_color32_luminance(src_buf_c32[x]), &dest_buf_l8[x], LV_OPA_MIX2(src_buf_c32[x].alpha, opa)); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(lv_color32_luminance(src_buf_c32[x]), &dest_buf_l8[x], LV_OPA_MIX2(src_buf_c32[x].alpha, mask_buf[x])); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_L8_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color_8_8_mix(lv_color32_luminance(src_buf_c32[x]), &dest_buf_l8[x], LV_OPA_MIX3(src_buf_c32[x].alpha, opa, + mask_buf[x])); + } + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color32_t color_argb = src_buf_c32[x]; + if(mask_buf == NULL) color_argb.alpha = LV_OPA_MIX2(color_argb.alpha, opa); + else color_argb.alpha = LV_OPA_MIX3(color_argb.alpha, mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_l8[x], color_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_l8 = drawbuf_next_row(dest_buf_l8, dest_stride); + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} + +#endif + +static inline void LV_ATTRIBUTE_FAST_MEM lv_color_8_8_mix(const uint8_t src, uint8_t * dest, uint8_t mix) +{ + + if(mix == 0) return; + + if(mix >= LV_OPA_MAX) { + *dest = src; + } + else { + lv_opa_t mix_inv = 255 - mix; + *dest = (uint32_t)((uint32_t)src * mix + dest[0] * mix_inv) >> 8; + } +} + + +#if LV_DRAW_SW_SUPPORT_I1 + +static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) +{ + return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; +} + +#endif + +static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest, lv_color32_t src, lv_blend_mode_t mode) +{ + uint8_t res; + int32_t src_lumi = lv_color32_luminance(src); + switch(mode) { + case LV_BLEND_MODE_ADDITIVE: + res = LV_MIN(*dest + src_lumi, 255); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = LV_MAX(*dest - src_lumi, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = (*dest * src_lumi) >> 8; + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", mode); + return; + } + lv_color_8_8_mix(res, dest, src.alpha); +} + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) +{ + return (void *)((uint8_t *)buf + stride); +} + +#endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.h new file mode 100644 index 000000000..079218e5a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_l8.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_l8.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_L8_H +#define LV_DRAW_SW_BLEND_TO_L8_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_draw_sw.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_l8(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_l8(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_TO_L8_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c index 84c19398d..1fa8c06b2 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_blend_to_rgb565.c * */ @@ -9,7 +9,9 @@ #include "lv_draw_sw_blend_to_rgb565.h" #if LV_USE_DRAW_SW -#include "lv_draw_sw_blend.h" +#if LV_DRAW_SW_SUPPORT_RGB565 + +#include "lv_draw_sw_blend_private.h" #include "../../../misc/lv_math.h" #include "../../../display/lv_display.h" #include "../../../core/lv_refr.h" @@ -36,12 +38,34 @@ * STATIC PROTOTYPES **********************/ -static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc); +#if LV_DRAW_SW_SUPPORT_AL88 + static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif -static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, +#if LV_DRAW_SW_SUPPORT_I1 + static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + + static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, int32_t bit_idx); +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +#if LV_DRAW_SW_SUPPORT_RGB888 +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size); +#endif -static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc); +#if LV_DRAW_SW_SUPPORT_ARGB8888 + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +static inline uint16_t /* LV_ATTRIBUTE_FAST_MEM */ l8_to_rgb565(const uint8_t c1); + +static inline uint16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color_8_16_mix(const uint8_t c1, uint16_t c2, uint8_t mix); static inline uint16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color_24_16_mix(const uint8_t * c1, uint16_t c2, uint8_t mix); @@ -71,6 +95,38 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565 + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_MASK + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565 + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID #endif @@ -119,6 +175,22 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565 + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + /********************** * GLOBAL FUNCTIONS **********************/ @@ -136,7 +208,7 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b * @param mask * @param mask_stride */ -void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565(_lv_draw_sw_blend_fill_dsc_t * dsc) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565(lv_draw_sw_blend_fill_dsc_t * dsc) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -287,21 +359,42 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565(_lv_draw_sw_blend_fi } } -void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb565(_lv_draw_sw_blend_image_dsc_t * dsc) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc) { switch(dsc->src_color_format) { case LV_COLOR_FORMAT_RGB565: rgb565_image_blend(dsc); break; +#if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, 3); break; +#endif +#if LV_DRAW_SW_SUPPORT_XRGB8888 case LV_COLOR_FORMAT_XRGB8888: rgb888_image_blend(dsc, 4); break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 case LV_COLOR_FORMAT_ARGB8888: argb8888_image_blend(dsc); break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + l8_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + al88_image_blend(dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + i1_image_blend(dsc); + break; +#endif default: LV_LOG_WARN("Not supported source color format"); break; @@ -312,7 +405,356 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb565(_lv_draw_sw_blend_im * STATIC FUNCTIONS **********************/ -static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc) +#if LV_DRAW_SW_SUPPORT_I1 +static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_i1 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + dest_buf_u16[dest_x] = l8_to_rgb565(chan_val); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + dest_buf_u16[dest_x] = lv_color_8_16_mix(chan_val, dest_buf_u16[dest_x], opa); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc)) { + + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + dest_buf_u16[dest_x] = lv_color_8_16_mix(chan_val, dest_buf_u16[dest_x], mask_buf[dest_x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + dest_buf_u16[dest_x] = lv_color_8_16_mix(chan_val, dest_buf_u16[dest_x], LV_OPA_MIX2(mask_buf[dest_x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + uint16_t res = 0; + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + // Additive blending mode + res = (LV_MIN(dest_buf_u16[dest_x] + l8_to_rgb565(chan_val), 0xFFFF)); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + // Subtractive blending mode + res = (LV_MAX(dest_buf_u16[dest_x] - l8_to_rgb565(chan_val), 0)); + break; + case LV_BLEND_MODE_MULTIPLY: + // Multiply blending mode + res = ((((dest_buf_u16[dest_x] >> 11) * (l8_to_rgb565(chan_val) >> 3)) & 0x1F) << 11) | + ((((dest_buf_u16[dest_x] >> 5) & 0x3F) * ((l8_to_rgb565(chan_val) >> 2) & 0x3F) >> 6) << 5) | + (((dest_buf_u16[dest_x] & 0x1F) * (l8_to_rgb565(chan_val) & 0x1F)) >> 5); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + dest_buf_u16[dest_x] = res; + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], opa); + } + else { + if(opa >= LV_OPA_MAX) + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], mask_buf[dest_x]); + else + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(mask_buf[dest_x], opa)); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + if(mask_buf) mask_buf += mask_stride; + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_AL88 +static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16a_t * src_buf_al88 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_al88[src_x].lumi, dest_buf_u16[dest_x], src_buf_al88[src_x].alpha); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_al88[src_x].lumi, dest_buf_u16[dest_x], + LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_al88[src_x].lumi, dest_buf_u16[dest_x], + LV_OPA_MIX2(src_buf_al88[src_x].alpha, mask_buf[dest_x])); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_al88[src_x].lumi, dest_buf_u16[dest_x], + LV_OPA_MIX3(src_buf_al88[src_x].alpha, mask_buf[dest_x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + uint16_t res = 0; + for(y = 0; y < h; y++) { + lv_color16_t * dest_buf_c16 = (lv_color16_t *)dest_buf_u16; + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + uint8_t rb = src_buf_al88[src_x].lumi >> 3; + uint8_t g = src_buf_al88[src_x].lumi >> 2; + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + res = (LV_MIN(dest_buf_c16[dest_x].red + rb, 31)) << 11; + res += (LV_MIN(dest_buf_c16[dest_x].green + g, 63)) << 5; + res += LV_MIN(dest_buf_c16[dest_x].blue + rb, 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(dest_buf_c16[dest_x].red - rb, 0)) << 11; + res += (LV_MAX(dest_buf_c16[dest_x].green - g, 0)) << 5; + res += LV_MAX(dest_buf_c16[dest_x].blue - rb, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((dest_buf_c16[dest_x].red * rb) >> 5) << 11; + res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5; + res += (dest_buf_c16[dest_x].blue * rb) >> 5; + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], src_buf_al88[src_x].alpha); + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(opa, src_buf_al88[src_x].alpha)); + } + else { + if(opa >= LV_OPA_MAX) dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], mask_buf[dest_x]); + else dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX3(mask_buf[dest_x], opa, + src_buf_al88[src_x].alpha)); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + +static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = l8_to_rgb565(src_buf_l8[src_x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_l8 += src_stride; + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_l8[src_x], dest_buf_u16[dest_x], opa); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_l8 += src_stride; + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_l8[src_x], dest_buf_u16[dest_x], mask_buf[dest_x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_l8 += src_stride; + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x++) { + dest_buf_u16[dest_x] = lv_color_8_16_mix(src_buf_l8[src_x], dest_buf_u16[dest_x], LV_OPA_MIX2(mask_buf[dest_x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_l8 += src_stride; + mask_buf += mask_stride; + } + } + } + } + else { + uint16_t res = 0; + for(y = 0; y < h; y++) { + lv_color16_t * dest_buf_c16 = (lv_color16_t *)dest_buf_u16; + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + uint8_t rb = src_buf_l8[src_x] >> 3; + uint8_t g = src_buf_l8[src_x] >> 2; + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + res = (LV_MIN(dest_buf_c16[dest_x].red + rb, 31)) << 11; + res += (LV_MIN(dest_buf_c16[dest_x].green + g, 63)) << 5; + res += LV_MIN(dest_buf_c16[dest_x].blue + rb, 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(dest_buf_c16[dest_x].red - rb, 0)) << 11; + res += (LV_MAX(dest_buf_c16[dest_x].green - g, 0)) << 5; + res += LV_MAX(dest_buf_c16[dest_x].blue - rb, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((dest_buf_c16[dest_x].red * rb) >> 5) << 11; + res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5; + res += (dest_buf_c16[dest_x].blue * rb) >> 5; + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + dest_buf_u16[dest_x] = res; + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], opa); + } + else { + if(opa >= LV_OPA_MAX) dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], mask_buf[dest_x]); + else dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(mask_buf[dest_x], opa)); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_l8 += src_stride; + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#endif + +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -420,7 +862,9 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(_lv_draw_sw_blend_image_dsc } } -static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) +#if LV_DRAW_SW_SUPPORT_RGB888 + +static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -528,7 +972,11 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(_lv_draw_sw_blend_image_dsc } } -static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc) +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -641,6 +1089,31 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(_lv_draw_sw_blend_image_d } } +#endif + +static inline uint16_t LV_ATTRIBUTE_FAST_MEM l8_to_rgb565(const uint8_t c1) +{ + return ((c1 & 0xF8) << 8) + ((c1 & 0xFC) << 3) + ((c1 & 0xF8) >> 3); +} + +static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_8_16_mix(const uint8_t c1, uint16_t c2, uint8_t mix) +{ + + if(mix == 0) { + return c2; + } + else if(mix == 255) { + return ((c1 & 0xF8) << 8) + ((c1 & 0xFC) << 3) + ((c1 & 0xF8) >> 3); + } + else { + lv_opa_t mix_inv = 255 - mix; + + return ((((c1 >> 3) * mix + ((c2 >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + ((((c1 >> 2) * mix + ((c2 >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + (((c1 >> 3) * mix + (c2 & 0x1F) * mix_inv) >> 8); + } +} + static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_24_16_mix(const uint8_t * c1, uint16_t c2, uint8_t mix) { if(mix == 0) { @@ -658,9 +1131,20 @@ static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_24_16_mix(const uint8_t * } } +#if LV_DRAW_SW_SUPPORT_I1 + +static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) +{ + return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; +} + +#endif + static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) { return (void *)((uint8_t *)buf + stride); } #endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h index c7482f948..d14bfd94d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.h @@ -1,10 +1,10 @@ /** - * @file lv_draw_sw_blend_rgb565.h + * @file lv_draw_sw_blend_to_rgb565.h * */ -#ifndef LV_DRAW_SW_BLEND_RGB565_H -#define LV_DRAW_SW_BLEND_RGB565_H +#ifndef LV_DRAW_SW_BLEND_TO_RGB565_H +#define LV_DRAW_SW_BLEND_TO_RGB565_H #ifdef __cplusplus extern "C" { @@ -28,9 +28,9 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_rgb565(_lv_draw_sw_blend_fill_dsc_t * dsc); +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_rgb565(lv_draw_sw_blend_fill_dsc_t * dsc); -void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb565(_lv_draw_sw_blend_image_dsc_t * dsc); +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); /********************** * MACROS @@ -42,4 +42,4 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb565(_lv_draw_sw_bl } /*extern "C"*/ #endif -#endif /*LV_DRAW_SW_BLEND_RGB565_H*/ +#endif /*LV_DRAW_SW_BLEND_TO_RGB565_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c index 84e087f9e..e29e934c1 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_blend_to_rgb888.c * */ @@ -9,7 +9,9 @@ #include "lv_draw_sw_blend_to_rgb888.h" #if LV_USE_DRAW_SW -#include "lv_draw_sw_blend.h" +#if LV_DRAW_SW_SUPPORT_RGB888 + +#include "lv_draw_sw_blend_private.h" #include "../../../misc/lv_math.h" #include "../../../display/lv_display.h" #include "../../../core/lv_refr.h" @@ -36,14 +38,34 @@ * STATIC PROTOTYPES **********************/ -static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +#if LV_DRAW_SW_SUPPORT_AL88 + static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +#endif -static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, +#if LV_DRAW_SW_SUPPORT_I1 + static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); + + static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, int32_t bit_idx); +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +#endif + +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t dest_px_size, uint32_t src_px_size); -static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, +#if LV_DRAW_SW_SUPPORT_ARGB8888 +static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +#endif + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_8_24_mix(const uint8_t src, uint8_t * dest, uint8_t mix); static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_24_24_mix(const uint8_t * src, uint8_t * dest, uint8_t mix); @@ -75,6 +97,22 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888 + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_MASK + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(...) LV_RESULT_INVALID #endif @@ -123,11 +161,27 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_888 + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + /********************** * GLOBAL FUNCTIONS **********************/ -void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb888(_lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb888(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -254,22 +308,43 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb888(_lv_draw_sw_blend_fi } } -void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb888(_lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) { switch(dsc->src_color_format) { +#if LV_DRAW_SW_SUPPORT_RGB565 case LV_COLOR_FORMAT_RGB565: rgb565_image_blend(dsc, dest_px_size); break; +#endif case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, dest_px_size, 3); break; +#if LV_DRAW_SW_SUPPORT_XRGB8888 case LV_COLOR_FORMAT_XRGB8888: rgb888_image_blend(dsc, dest_px_size, 4); break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 case LV_COLOR_FORMAT_ARGB8888: argb8888_image_blend(dsc, dest_px_size); break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + l8_image_blend(dsc, dest_px_size); + break; +#endif +#if LV_DRAW_SW_SUPPORT_AL88 + case LV_COLOR_FORMAT_AL88: + al88_image_blend(dsc, dest_px_size); + break; +#endif +#if LV_DRAW_SW_SUPPORT_I1 + case LV_COLOR_FORMAT_I1: + i1_image_blend(dsc, dest_px_size); + break; +#endif default: LV_LOG_WARN("Not supported source color format"); break; @@ -280,7 +355,272 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb888(_lv_draw_sw_blend_im * STATIC FUNCTIONS **********************/ -static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +#if LV_DRAW_SW_SUPPORT_I1 +static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_i1 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_888(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + dest_buf_u8[dest_x + 2] = chan_val; + dest_buf_u8[dest_x + 1] = chan_val; + dest_buf_u8[dest_x + 0] = chan_val; + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_24_mix(chan_val, &dest_buf_u8[dest_x], opa); + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_24_mix(chan_val, &dest_buf_u8[dest_x], mask_buf[src_x]); + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_I1_BLEND_NORMAL_TO_888_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + uint8_t chan_val = get_bit(src_buf_i1, src_x) * 255; + lv_color_8_24_mix(chan_val, &dest_buf_u8[dest_x], LV_OPA_MIX2(opa, mask_buf[src_x])); + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color32_t src_argb; + src_argb.red = get_bit(src_buf_i1, src_x) * 255; + src_argb.green = src_argb.red; + src_argb.blue = src_argb.red; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[src_x], opa); + blend_non_normal_pixel(&dest_buf_u8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_i1 = drawbuf_next_row(src_buf_i1, src_stride); + } + } +} +#endif + +#if LV_DRAW_SW_SUPPORT_AL88 +static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const lv_color16a_t * src_buf_al88 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], src_buf_al88[src_x].alpha); + } + dest_buf_u8 += dest_stride; + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa)); + } + dest_buf_u8 += dest_stride; + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, + mask_buf[src_x])); + } + dest_buf_u8 += dest_stride; + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], LV_OPA_MIX3(src_buf_al88[src_x].alpha, + mask_buf[src_x], opa)); + } + dest_buf_u8 += dest_stride; + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color32_t src_argb; + src_argb.red = src_argb.green = src_argb.blue = src_buf_al88[src_x].lumi; + if(mask_buf == NULL) src_argb.alpha = LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa); + else src_argb.alpha = LV_OPA_MIX3(src_buf_al88[src_x].alpha, mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_u8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_u8 += dest_stride; + src_buf_al88 = drawbuf_next_row(src_buf_al88, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + +static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + lv_opa_t opa = dsc->opa; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + const lv_opa_t * mask_buf = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + + int32_t dest_x; + int32_t src_x; + int32_t y; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + dest_buf_u8[dest_x + 2] = src_buf_l8[src_x]; + dest_buf_u8[dest_x + 1] = src_buf_l8[src_x]; + dest_buf_u8[dest_x + 0] = src_buf_l8[src_x]; + } + dest_buf_u8 += dest_stride; + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_l8[src_x], &dest_buf_u8[dest_x], opa); + } + dest_buf_u8 += dest_stride; + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_l8[src_x], &dest_buf_u8[dest_x], mask_buf[src_x]); + } + dest_buf_u8 += dest_stride; + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + lv_color_8_24_mix(src_buf_l8[src_x], &dest_buf_u8[dest_x], LV_OPA_MIX2(opa, mask_buf[src_x])); + } + dest_buf_u8 += dest_stride; + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { + src_argb.red = src_buf_l8[src_x]; + src_argb.green = src_buf_l8[src_x]; + src_argb.blue = src_buf_l8[src_x]; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[dest_x], opa); + blend_non_normal_pixel(&dest_buf_u8[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf_u8 += dest_stride; + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -376,7 +716,9 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(_lv_draw_sw_blend_image_dsc } } -static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t dest_px_size, +#endif + +static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t dest_px_size, uint32_t src_px_size) { int32_t w = dsc->dest_w * dest_px_size; @@ -474,7 +816,9 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(_lv_draw_sw_blend_image_dsc } } -static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(_lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) { int32_t w = dsc->dest_w; int32_t h = dsc->dest_h; @@ -557,6 +901,8 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(_lv_draw_sw_blend_image_d } } +#endif + static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest, lv_color32_t src, lv_blend_mode_t mode) { uint8_t res[3] = {0, 0, 0}; @@ -583,6 +929,24 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest, lv_color_24_24_mix(res, dest, src.alpha); } +static inline void LV_ATTRIBUTE_FAST_MEM lv_color_8_24_mix(const uint8_t src, uint8_t * dest, uint8_t mix) +{ + + if(mix == 0) return; + + if(mix >= LV_OPA_MAX) { + dest[0] = src; + dest[1] = src; + dest[2] = src; + } + else { + lv_opa_t mix_inv = 255 - mix; + dest[0] = (uint32_t)((uint32_t)src * mix + dest[0] * mix_inv) >> 8; + dest[1] = (uint32_t)((uint32_t)src * mix + dest[1] * mix_inv) >> 8; + dest[2] = (uint32_t)((uint32_t)src * mix + dest[2] * mix_inv) >> 8; + } +} + static inline void LV_ATTRIBUTE_FAST_MEM lv_color_24_24_mix(const uint8_t * src, uint8_t * dest, uint8_t mix) { @@ -601,9 +965,21 @@ static inline void LV_ATTRIBUTE_FAST_MEM lv_color_24_24_mix(const uint8_t * src, } } +#if LV_DRAW_SW_SUPPORT_I1 + +static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) +{ + return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; +} + +#endif + + static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) { return (void *)((uint8_t *)buf + stride); } #endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h index a97a58bfe..441c0d3e8 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.h @@ -1,10 +1,10 @@ /** - * @file lv_draw_sw_blend_rgb888.h + * @file lv_draw_sw_blend_to_rgb888.h * */ -#ifndef LV_DRAW_SW_BLEND_RGB888_H -#define LV_DRAW_SW_BLEND_RGB888_H +#ifndef LV_DRAW_SW_BLEND_TO_RGB888_H +#define LV_DRAW_SW_BLEND_TO_RGB888_H #ifdef __cplusplus extern "C" { @@ -28,10 +28,10 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_rgb888(_lv_draw_sw_blend_fill_dsc_t * dsc, +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color_to_rgb888(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size); -void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb888(_lv_draw_sw_blend_image_dsc_t * dsc, +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); /********************** @@ -44,4 +44,4 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb888(_lv_draw_sw_bl } /*extern "C"*/ #endif -#endif /*LV_DRAW_SW_BLEND_RGB888_H*/ +#endif /*LV_DRAW_SW_BLEND_TO_RGB888_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.S b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.S index 61577e22a..e82120440 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.S +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.S @@ -641,6 +641,7 @@ TMP_Q1 .qn q14 .thumb_func .func name .global name +.hidden name name&: blender src_bpp, dst_bpp, mask, opa, mode .endfunc @@ -648,15 +649,15 @@ name&: .macro export_set src, dst, src_bpp, dst_bpp, mode .if src == color - export lv_&src&_blend_to_&dst&_neon, src_bpp, dst_bpp, 0, 0, mode - export lv_&src&_blend_to_&dst&_with_opa_neon, src_bpp, dst_bpp, 0, 1, mode - export lv_&src&_blend_to_&dst&_with_mask_neon, src_bpp, dst_bpp, 1, 0, mode - export lv_&src&_blend_to_&dst&_mix_mask_opa_neon, src_bpp, dst_bpp, 1, 1, mode + export _lv_&src&_blend_to_&dst&_neon, src_bpp, dst_bpp, 0, 0, mode + export _lv_&src&_blend_to_&dst&_with_opa_neon, src_bpp, dst_bpp, 0, 1, mode + export _lv_&src&_blend_to_&dst&_with_mask_neon, src_bpp, dst_bpp, 1, 0, mode + export _lv_&src&_blend_to_&dst&_mix_mask_opa_neon, src_bpp, dst_bpp, 1, 1, mode .else - export lv_&src&_blend_&mode&_to_&dst&_neon, src_bpp, dst_bpp, 0, 0, mode - export lv_&src&_blend_&mode&_to_&dst&_with_opa_neon, src_bpp, dst_bpp, 0, 1, mode - export lv_&src&_blend_&mode&_to_&dst&_with_mask_neon, src_bpp, dst_bpp, 1, 0, mode - export lv_&src&_blend_&mode&_to_&dst&_mix_mask_opa_neon, src_bpp, dst_bpp, 1, 1, mode + export _lv_&src&_blend_&mode&_to_&dst&_neon, src_bpp, dst_bpp, 0, 0, mode + export _lv_&src&_blend_&mode&_to_&dst&_with_opa_neon, src_bpp, dst_bpp, 0, 1, mode + export _lv_&src&_blend_&mode&_to_&dst&_with_mask_neon, src_bpp, dst_bpp, 1, 0, mode + export _lv_&src&_blend_&mode&_to_&dst&_mix_mask_opa_neon, src_bpp, dst_bpp, 1, 1, mode .endif .endm diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.h index fbe7ea9b4..fd52647bf 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/neon/lv_blend_neon.h @@ -25,244 +25,250 @@ extern "C" { *********************/ #if !defined(__ASSEMBLY__) +#if __GNUC__ >= 4 +#define LVGL_HIDDEN __attribute__((visibility("hidden"))) +#else +#define LVGL_HIDDEN +#endif + #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ - _lv_color_blend_to_rgb565_neon(dsc) + lv_color_blend_to_rgb565_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ - _lv_color_blend_to_rgb565_with_opa_neon(dsc) + lv_color_blend_to_rgb565_with_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ - _lv_color_blend_to_rgb565_with_mask_neon(dsc) + lv_color_blend_to_rgb565_with_mask_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_color_blend_to_rgb565_mix_mask_opa_neon(dsc) + lv_color_blend_to_rgb565_mix_mask_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_neon(dsc) + lv_rgb565_blend_normal_to_rgb565_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(dsc) + lv_rgb565_blend_normal_to_rgb565_with_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(dsc) + lv_rgb565_blend_normal_to_rgb565_with_mask_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) + lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_with_opa_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_with_mask_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_neon(dsc) + lv_argb8888_blend_normal_to_rgb565_neon(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(dsc) + lv_argb8888_blend_normal_to_rgb565_with_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(dsc) + lv_argb8888_blend_normal_to_rgb565_with_mask_neon(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) + lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_neon(dsc, dst_px_size) + lv_color_blend_to_rgb888_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_with_opa_neon(dsc, dst_px_size) + lv_color_blend_to_rgb888_with_opa_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_with_mask_neon(dsc, dst_px_size) + lv_color_blend_to_rgb888_with_mask_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_color_blend_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) + lv_color_blend_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_neon(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) + lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_neon(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_neon(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ - _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size, src_px_size) + lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_neon(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) + lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888 #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888(dsc) \ - _lv_color_blend_to_argb8888_neon(dsc) + lv_color_blend_to_argb8888_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA(dsc) \ - _lv_color_blend_to_argb8888_with_opa_neon(dsc) + lv_color_blend_to_argb8888_with_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK(dsc) \ - _lv_color_blend_to_argb8888_with_mask_neon(dsc) + lv_color_blend_to_argb8888_with_mask_neon(dsc) #endif #ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - _lv_color_blend_to_argb8888_mix_mask_opa_neon(dsc) + lv_color_blend_to_argb8888_mix_mask_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_neon(dsc) + lv_rgb565_blend_normal_to_argb8888_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(dsc) + lv_rgb565_blend_normal_to_argb8888_with_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(dsc) + lv_rgb565_blend_normal_to_argb8888_with_mask_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) + lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_with_opa_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_with_mask_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc, src_px_size) \ - _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc, src_px_size) + lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc, src_px_size) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888 #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_neon(dsc) + lv_argb8888_blend_normal_to_argb8888_neon(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(dsc) + lv_argb8888_blend_normal_to_argb8888_with_opa_neon(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(dsc) + lv_argb8888_blend_normal_to_argb8888_with_mask_neon(dsc) #endif #ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) + lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) #endif /********************** @@ -284,8 +290,8 @@ typedef struct { * GLOBAL PROTOTYPES **********************/ -extern void lv_color_blend_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_neon(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -295,12 +301,12 @@ static inline lv_result_t _lv_color_blend_to_rgb565_neon(_lv_draw_sw_blend_fill_ .src_buf = &dsc->color }; - lv_color_blend_to_rgb565_neon(&asm_dsc); + _lv_color_blend_to_rgb565_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_with_opa_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -310,12 +316,12 @@ static inline lv_result_t _lv_color_blend_to_rgb565_with_opa_neon(_lv_draw_sw_bl .dst_stride = dsc->dest_stride, .src_buf = &dsc->color }; - lv_color_blend_to_rgb565_with_opa_neon(&asm_dsc); + _lv_color_blend_to_rgb565_with_opa_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_with_mask_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -326,12 +332,12 @@ static inline lv_result_t _lv_color_blend_to_rgb565_with_mask_neon(_lv_draw_sw_b .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_color_blend_to_rgb565_with_mask_neon(&asm_dsc); + _lv_color_blend_to_rgb565_with_mask_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb565_mix_mask_opa_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -343,12 +349,12 @@ static inline lv_result_t _lv_color_blend_to_rgb565_mix_mask_opa_neon(_lv_draw_s .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_color_blend_to_rgb565_mix_mask_opa_neon(&asm_dsc); + _lv_color_blend_to_rgb565_mix_mask_opa_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -358,12 +364,12 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_neon(_lv_draw_sw_ble .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_rgb565_blend_normal_to_rgb565_neon(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -374,12 +380,12 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(_lv_dr .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_rgb565_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -391,12 +397,12 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(_lv_d .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_rgb565_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -409,14 +415,14 @@ static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(_l .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -427,41 +433,41 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_neon(_lv_draw_sw_ble .src_stride = dsc->src_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_neon(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_neon(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb565_neon(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_neon(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -474,705 +480,21 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(_lv_d .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - lv_argb8888_blend_normal_to_rgb565_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - lv_argb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - lv_argb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_rgb888_neon(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_neon(_lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - if(dst_px_size == 3) { - lv_color_blend_to_rgb888_neon(&asm_dsc); - } - else { - lv_color_blend_to_xrgb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_with_opa_neon(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - if(dst_px_size == 3) { - lv_color_blend_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - lv_color_blend_to_xrgb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_with_mask_neon(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - lv_color_blend_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - lv_color_blend_to_xrgb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_rgb888_mix_mask_opa_neon(_lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - lv_color_blend_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - lv_color_blend_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_neon(&asm_dsc); - } - else { - lv_rgb565_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_rgb888_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_neon(&asm_dsc); - } - else { - lv_argb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - - lv_color_blend_to_argb8888_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_with_opa_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - lv_color_blend_to_argb8888_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_with_mask_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - lv_color_blend_to_argb8888_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_color_blend_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_color_blend_to_argb8888_mix_mask_opa_neon(_lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - lv_color_blend_to_argb8888_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - lv_rgb565_blend_normal_to_argb8888_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - lv_rgb565_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - lv_rgb565_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_argb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - } - else { - lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern void lv_rgb888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc, +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { asm_dsc_t asm_dsc = { + .opa = dsc->opa, .dst_buf = dsc->dest_buf, .dst_w = dsc->dest_w, .dst_h = dsc->dest_h, @@ -1183,18 +505,702 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(_lv .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_argb8888_blend_normal_to_rgb565_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_neon(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_color_blend_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_color_blend_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size, uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + } + else { + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dst_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(dst_px_size == 3) { + _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); + } + else { + _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + + _lv_color_blend_to_argb8888_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color + }; + _lv_color_blend_to_argb8888_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_color_blend_to_argb8888_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = &dsc->color, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_color_blend_to_argb8888_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_rgb565_blend_normal_to_argb8888_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .opa = dsc->opa, + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) +{ + asm_dsc_t asm_dsc = { + .dst_buf = dsc->dest_buf, + .dst_w = dsc->dest_w, + .dst_h = dsc->dest_h, + .dst_stride = dsc->dest_stride, + .src_buf = dsc->src_buf, + .src_stride = dsc->src_stride, + .mask_buf = dsc->mask_buf, + .mask_stride = dsc->mask_stride + }; + if(src_px_size == 3) { + _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + } + else { + _lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + } + return LV_RESULT_OK; +} + +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t src_px_size) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1208,16 +1214,16 @@ static inline lv_result_t _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon( .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1227,12 +1233,12 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_neon(_lv_draw_sw .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_argb8888_blend_normal_to_argb8888_neon(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1243,12 +1249,12 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(_l .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_argb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .dst_buf = dsc->dest_buf, @@ -1260,12 +1266,12 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(_ .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_argb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(_lv_draw_sw_blend_image_dsc_t * dsc) +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); +static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { .opa = dsc->opa, @@ -1278,7 +1284,7 @@ static inline lv_result_t _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neo .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); return LV_RESULT_OK; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.c index 4ced5d1d0..1ae578d15 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.c @@ -6,11 +6,11 @@ /********************* * INCLUDES *********************/ -#include "../lv_draw.h" +#include "lv_draw_sw_private.h" +#include "../lv_draw_private.h" #if LV_USE_DRAW_SW #include "../../core/lv_refr.h" -#include "lv_draw_sw.h" #include "../../display/lv_display_private.h" #include "../../stdlib/lv_string.h" #include "../../core/lv_global.h" @@ -29,6 +29,10 @@ #include LV_DRAW_SW_ASM_CUSTOM_INCLUDE #endif +#if LV_DRAW_SW_DRAW_UNIT_CNT > 1 && LV_USE_OS == LV_OS_NONE + #error "OS support is required when more than one SW rendering units are enabled" +#endif + /********************* * DEFINES *********************/ @@ -74,6 +78,18 @@ #define LV_DRAW_SW_ROTATE270_RGB565(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_ROTATE90_L8 + #define LV_DRAW_SW_ROTATE90_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE180_L8 + #define LV_DRAW_SW_ROTATE180_L8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE270_L8 + #define LV_DRAW_SW_ROTATE270_L8(...) LV_RESULT_INVALID +#endif + /********************** * TYPEDEFS **********************/ @@ -91,29 +107,47 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); static int32_t lv_draw_sw_delete(lv_draw_unit_t * draw_unit); -static void rotate90_argb8888(const uint32_t * src, uint32_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride); +#if LV_DRAW_SW_SUPPORT_ARGB8888 +static void rotate90_argb8888(const uint32_t * src, uint32_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); static void rotate180_argb8888(const uint32_t * src, uint32_t * dst, int32_t width, int32_t height, int32_t src_stride, int32_t dest_stride); -static void rotate270_argb8888(const uint32_t * src, uint32_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride); -static void rotate90_rgb888(const uint8_t * src, uint8_t * dst, int32_t srcWidth, int32_t srcHeight, int32_t srcStride, - int32_t dstStride); +static void rotate270_argb8888(const uint32_t * src, uint32_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 +static void rotate90_rgb888(const uint8_t * src, uint8_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); static void rotate180_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t src_stride, int32_t dest_stride); -static void rotate270_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t srcStride, - int32_t dstStride); -static void rotate90_rgb565(const uint16_t * src, uint16_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride); +static void rotate270_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t src_stride, + int32_t dst_stride); +#endif +#if LV_DRAW_SW_SUPPORT_RGB565 +static void rotate90_rgb565(const uint16_t * src, uint16_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); static void rotate180_rgb565(const uint16_t * src, uint16_t * dst, int32_t width, int32_t height, int32_t src_stride, int32_t dest_stride); -static void rotate270_rgb565(const uint16_t * src, uint16_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride); +static void rotate270_rgb565(const uint16_t * src, uint16_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); +#endif +#if LV_DRAW_SW_SUPPORT_L8 + +static void rotate90_l8(const uint8_t * src, uint8_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); +static void rotate180_l8(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t src_stride, + int32_t dest_stride); +static void rotate270_l8(const uint8_t * src, uint8_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride); +#endif /********************** * STATIC VARIABLES **********************/ @@ -143,7 +177,7 @@ void lv_draw_sw_init(void) draw_sw_unit->base_unit.delete_cb = LV_USE_OS ? lv_draw_sw_delete : NULL; #if LV_USE_OS - lv_thread_init(&draw_sw_unit->thread, LV_THREAD_PRIO_HIGH, render_thread_cb, 8 * 1024, draw_sw_unit); + lv_thread_init(&draw_sw_unit->thread, LV_THREAD_PRIO_HIGH, render_thread_cb, LV_DRAW_THREAD_STACK_SIZE, draw_sw_unit); #endif } @@ -216,24 +250,128 @@ void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px) } -void lv_draw_sw_rotate(const void * src, void * dest, int32_t src_width, int32_t src_height, int32_t src_sride, +void lv_draw_sw_i1_invert(void * buf, uint32_t buf_size) +{ + if(buf == NULL) return; + + uint8_t * byte_buf = (uint8_t *)buf; + uint32_t i; + + /*Make the buffer aligned*/ + while(((uintptr_t)(byte_buf) & (sizeof(int) - 1)) && buf_size > 0) { + *byte_buf = ~(*byte_buf); + byte_buf++; + buf_size--; + } + + if(buf_size >= sizeof(uint32_t)) { + uint32_t * aligned_addr = (uint32_t *)byte_buf; + uint32_t word_count = buf_size / 4; + + for(i = 0; i < word_count; ++i) { + aligned_addr[i] = ~aligned_addr[i]; + } + + byte_buf = (uint8_t *)(aligned_addr + word_count); + buf_size = buf_size % sizeof(uint32_t); + } + + for(i = 0; i < buf_size; ++i) { + byte_buf[i] = ~byte_buf[i]; + } +} + +void lv_draw_sw_rotate(const void * src, void * dest, int32_t src_width, int32_t src_height, int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation, lv_color_format_t color_format) { - uint32_t px_bpp = lv_color_format_get_bpp(color_format); if(rotation == LV_DISPLAY_ROTATION_90) { - if(px_bpp == 16) rotate90_rgb565(src, dest, src_width, src_height, src_sride, dest_stride); - if(px_bpp == 24) rotate90_rgb888(src, dest, src_width, src_height, src_sride, dest_stride); - if(px_bpp == 32) rotate90_argb8888(src, dest, src_width, src_height, src_sride, dest_stride); + switch(color_format) { +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + rotate90_l8(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + rotate90_rgb565(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + rotate90_rgb888(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 || LV_DRAW_SW_SUPPORT_XRGB8888 + case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB8888: + rotate90_argb8888(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif + default: + break; + } + + return; } - else if(rotation == LV_DISPLAY_ROTATION_180) { - if(px_bpp == 16) rotate180_rgb565(src, dest, src_width, src_height, src_sride, dest_stride); - if(px_bpp == 24) rotate180_rgb888(src, dest, src_width, src_height, src_sride, dest_stride); - if(px_bpp == 32) rotate180_argb8888(src, dest, src_width, src_height, src_sride, dest_stride); + + if(rotation == LV_DISPLAY_ROTATION_180) { + switch(color_format) { +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + rotate180_l8(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + rotate180_rgb565(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + rotate180_rgb888(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 || LV_DRAW_SW_SUPPORT_XRGB8888 + case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB8888: + rotate180_argb8888(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif + default: + break; + } + + return; } - else if(rotation == LV_DISPLAY_ROTATION_270) { - if(px_bpp == 16) rotate270_rgb565(src, dest, src_width, src_height, src_sride, dest_stride); - if(px_bpp == 24) rotate270_rgb888(src, dest, src_width, src_height, src_sride, dest_stride); - if(px_bpp == 32) rotate270_argb8888(src, dest, src_width, src_height, src_sride, dest_stride); + + if(rotation == LV_DISPLAY_ROTATION_270) { + switch(color_format) { +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + rotate270_l8(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + rotate270_rgb565(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + rotate270_rgb888(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 || LV_DRAW_SW_SUPPORT_XRGB8888 + case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB8888: + rotate270_argb8888(src, dest, src_width, src_height, src_stride, dest_stride); + break; +#endif + default: + break; + } + + return; } } @@ -304,13 +442,13 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_SW); if(t == NULL) { LV_PROFILER_END; - return -1; + return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } void * buf = lv_draw_layer_alloc_buf(layer); if(buf == NULL) { LV_PROFILER_END; - return -1; + return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; @@ -407,7 +545,7 @@ static void execute_drawing(lv_draw_sw_unit_t * u) /*Layers manage it for themselves*/ if(t->type != LV_DRAW_TASK_TYPE_LAYER) { lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area)) return; int32_t idx = 0; lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; @@ -417,7 +555,7 @@ static void execute_drawing(lv_draw_sw_unit_t * u) } lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); - rect_dsc.bg_color = lv_palette_main(idx % _LV_PALETTE_LAST); + rect_dsc.bg_color = lv_palette_main(idx % LV_PALETTE_LAST); rect_dsc.border_color = rect_dsc.bg_color; rect_dsc.bg_opa = LV_OPA_10; rect_dsc.border_opa = LV_OPA_80; @@ -449,23 +587,25 @@ static void execute_drawing(lv_draw_sw_unit_t * u) LV_PROFILER_END; } -static void rotate90_argb8888(const uint32_t * src, uint32_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride) +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +static void rotate270_argb8888(const uint32_t * src, uint32_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_ARGB8888(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } - srcStride /= sizeof(uint32_t); - dstStride /= sizeof(uint32_t); + src_stride /= sizeof(uint32_t); + dst_stride /= sizeof(uint32_t); - for(int32_t x = 0; x < srcWidth; ++x) { - int32_t dstIndex = x * dstStride; + for(int32_t x = 0; x < src_width; ++x) { + int32_t dstIndex = x * dst_stride; int32_t srcIndex = x; - for(int32_t y = 0; y < srcHeight; ++y) { - dst[dstIndex + (srcHeight - y - 1)] = src[srcIndex]; - srcIndex += srcStride; + for(int32_t y = 0; y < src_height; ++y) { + dst[dstIndex + (src_height - y - 1)] = src[srcIndex]; + srcIndex += src_stride; } } } @@ -474,7 +614,7 @@ static void rotate180_argb8888(const uint32_t * src, uint32_t * dst, int32_t wid int32_t dest_stride) { LV_UNUSED(dest_stride); - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_ARGB8888(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } @@ -489,38 +629,42 @@ static void rotate180_argb8888(const uint32_t * src, uint32_t * dst, int32_t wid } } -static void rotate270_argb8888(const uint32_t * src, uint32_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride) +static void rotate90_argb8888(const uint32_t * src, uint32_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, int32_t dst_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_ARGB8888(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } - srcStride /= sizeof(uint32_t); - dstStride /= sizeof(uint32_t); + src_stride /= sizeof(uint32_t); + dst_stride /= sizeof(uint32_t); - for(int32_t x = 0; x < srcWidth; ++x) { - int32_t dstIndex = (srcWidth - x - 1); + for(int32_t x = 0; x < src_width; ++x) { + int32_t dstIndex = (src_width - x - 1); int32_t srcIndex = x; - for(int32_t y = 0; y < srcHeight; ++y) { - dst[dstIndex * dstStride + y] = src[srcIndex]; - srcIndex += srcStride; + for(int32_t y = 0; y < src_height; ++y) { + dst[dstIndex * dst_stride + y] = src[srcIndex]; + srcIndex += src_stride; } } } -static void rotate90_rgb888(const uint8_t * src, uint8_t * dst, int32_t srcWidth, int32_t srcHeight, int32_t srcStride, - int32_t dstStride) +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 + +static void rotate90_rgb888(const uint8_t * src, uint8_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_RGB888(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_RGB888(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } - for(int32_t x = 0; x < srcWidth; ++x) { - for(int32_t y = 0; y < srcHeight; ++y) { - int32_t srcIndex = y * srcStride + x * 3; - int32_t dstIndex = (srcWidth - x - 1) * dstStride + y * 3; + for(int32_t x = 0; x < src_width; ++x) { + for(int32_t y = 0; y < src_height; ++y) { + int32_t srcIndex = y * src_stride + x * 3; + int32_t dstIndex = (src_width - x - 1) * dst_stride + y * 3; dst[dstIndex] = src[srcIndex]; /*Red*/ dst[dstIndex + 1] = src[srcIndex + 1]; /*Green*/ dst[dstIndex + 2] = src[srcIndex + 2]; /*Blue*/ @@ -531,7 +675,7 @@ static void rotate90_rgb888(const uint8_t * src, uint8_t * dst, int32_t srcWidth static void rotate180_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t src_stride, int32_t dest_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_RGB888(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_RGB888(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } @@ -546,17 +690,17 @@ static void rotate180_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, } } -static void rotate270_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t srcStride, - int32_t dstStride) +static void rotate270_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t src_stride, + int32_t dst_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_RGB888(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_RGB888(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } for(int32_t x = 0; x < width; ++x) { for(int32_t y = 0; y < height; ++y) { - int32_t srcIndex = y * srcStride + x * 3; - int32_t dstIndex = x * dstStride + (height - y - 1) * 3; + int32_t srcIndex = y * src_stride + x * 3; + int32_t dstIndex = x * dst_stride + (height - y - 1) * 3; dst[dstIndex] = src[srcIndex]; /*Red*/ dst[dstIndex + 1] = src[srcIndex + 1]; /*Green*/ dst[dstIndex + 2] = src[srcIndex + 2]; /*Blue*/ @@ -564,23 +708,27 @@ static void rotate270_rgb888(const uint8_t * src, uint8_t * dst, int32_t width, } } -static void rotate90_rgb565(const uint16_t * src, uint16_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride) +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565 + +static void rotate270_rgb565(const uint16_t * src, uint16_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_RGB565(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_RGB565(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } - srcStride /= sizeof(uint16_t); - dstStride /= sizeof(uint16_t); + src_stride /= sizeof(uint16_t); + dst_stride /= sizeof(uint16_t); - for(int32_t x = 0; x < srcWidth; ++x) { - int32_t dstIndex = x * dstStride; + for(int32_t x = 0; x < src_width; ++x) { + int32_t dstIndex = x * dst_stride; int32_t srcIndex = x; - for(int32_t y = 0; y < srcHeight; ++y) { - dst[dstIndex + (srcHeight - y - 1)] = src[srcIndex]; - srcIndex += srcStride; + for(int32_t y = 0; y < src_height; ++y) { + dst[dstIndex + (src_height - y - 1)] = src[srcIndex]; + srcIndex += src_stride; } } } @@ -588,7 +736,7 @@ static void rotate90_rgb565(const uint16_t * src, uint16_t * dst, int32_t srcWid static void rotate180_rgb565(const uint16_t * src, uint16_t * dst, int32_t width, int32_t height, int32_t src_stride, int32_t dest_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_RGB565(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_RGB565(src, dst, width, height, src_stride)) { return ; } @@ -604,25 +752,84 @@ static void rotate180_rgb565(const uint16_t * src, uint16_t * dst, int32_t width } } -static void rotate270_rgb565(const uint16_t * src, uint16_t * dst, int32_t srcWidth, int32_t srcHeight, - int32_t srcStride, - int32_t dstStride) +static void rotate90_rgb565(const uint16_t * src, uint16_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride) { - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_RGB565(src, dst, srcWidth, srcHeight, srcStride, dstStride)) { + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_RGB565(src, dst, src_width, src_height, src_stride, dst_stride)) { return ; } - srcStride /= sizeof(uint16_t); - dstStride /= sizeof(uint16_t); + src_stride /= sizeof(uint16_t); + dst_stride /= sizeof(uint16_t); - for(int32_t x = 0; x < srcWidth; ++x) { - int32_t dstIndex = (srcWidth - x - 1); + for(int32_t x = 0; x < src_width; ++x) { + int32_t dstIndex = (src_width - x - 1); int32_t srcIndex = x; - for(int32_t y = 0; y < srcHeight; ++y) { - dst[dstIndex * dstStride + y] = src[srcIndex]; - srcIndex += srcStride; + for(int32_t y = 0; y < src_height; ++y) { + dst[dstIndex * dst_stride + y] = src[srcIndex]; + srcIndex += src_stride; } } } +#endif + + +#if LV_DRAW_SW_SUPPORT_L8 + +static void rotate90_l8(const uint8_t * src, uint8_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride) +{ + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE270_L8(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + for(int32_t x = 0; x < src_width; ++x) { + int32_t dstIndex = (src_width - x - 1); + int32_t srcIndex = x; + for(int32_t y = 0; y < src_height; ++y) { + dst[dstIndex * dst_stride + y] = src[srcIndex]; + srcIndex += src_stride; + } + } +} + +static void rotate180_l8(const uint8_t * src, uint8_t * dst, int32_t width, int32_t height, int32_t src_stride, + int32_t dest_stride) +{ + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_L8(src, dst, width, height, src_stride)) { + return ; + } + + for(int32_t y = 0; y < height; ++y) { + int32_t dstIndex = (height - y - 1) * dest_stride; + int32_t srcIndex = y * src_stride; + for(int32_t x = 0; x < width; ++x) { + dst[dstIndex + width - x - 1] = src[srcIndex + x]; + } + } +} + +static void rotate270_l8(const uint8_t * src, uint8_t * dst, int32_t src_width, int32_t src_height, + int32_t src_stride, + int32_t dst_stride) +{ + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE90_L8(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + for(int32_t x = 0; x < src_width; ++x) { + int32_t dstIndex = x * dst_stride; + int32_t srcIndex = x; + for(int32_t y = 0; y < src_height; ++y) { + dst[dstIndex + (src_height - y - 1)] = src[srcIndex]; + srcIndex += src_stride; + } + } +} + +#endif + #endif /*LV_USE_DRAW_SW*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.h index 23f1c58dd..6463afd86 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw.h * */ @@ -21,36 +21,17 @@ extern "C" { #include "../../display/lv_display.h" #include "../../osal/lv_os.h" -#include "../../draw/lv_draw_vector.h" +#include "../lv_draw_vector.h" +#include "../lv_draw_triangle.h" +#include "../lv_draw_label.h" +#include "../lv_draw_image.h" +#include "../lv_draw_line.h" +#include "../lv_draw_arc.h" /********************* * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_draw_unit_t base_unit; - lv_draw_task_t * task_act; -#if LV_USE_OS - lv_thread_sync_t sync; - lv_thread_t thread; - volatile bool inited; - volatile bool exit_status; -#endif - uint32_t idx; -} lv_draw_sw_unit_t; - -#if LV_DRAW_SW_SHADOW_CACHE_SIZE -typedef struct { - uint8_t cache[LV_DRAW_SW_SHADOW_CACHE_SIZE * LV_DRAW_SW_SHADOW_CACHE_SIZE]; - int32_t cache_size; - int32_t cache_r; -} lv_draw_sw_shadow_cache_t; -#endif - /********************** * GLOBAL PROTOTYPES **********************/ @@ -72,7 +53,7 @@ void lv_draw_sw_deinit(void); * @param dsc the draw descriptor * @param coords the coordinates of the rectangle */ -void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); /** * Draw border with SW render. @@ -93,7 +74,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ /** * Draw an image with SW render. It handles image decoding, tiling, transformations, and recoloring. * @param draw_unit pointer to a draw unit - * @param dsc the draw descriptor + * @param draw_dsc the draw descriptor * @param coords the coordinates of the image */ void lv_draw_sw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, @@ -125,7 +106,7 @@ void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) /** * Blend a layer with SW render * @param draw_unit pointer to a draw unit - * @param dsc the draw descriptor + * @param draw_dsc the draw descriptor * @param coords the coordinates of the layer */ void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); @@ -148,12 +129,12 @@ void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_ds /** * Used internally to get a transformed are of an image * @param draw_unit pointer to a draw unit - * @param dest_area the area to calculate, i.e. get this area from the transformed image - * @param src_buf the source buffer + * @param dest_area area to calculate, i.e. get this area from the transformed image + * @param src_buf source buffer * @param src_w source buffer width in pixels * @param src_h source buffer height in pixels * @param src_stride source buffer stride in bytes - * @param dsc the draw descriptor + * @param draw_dsc draw descriptor * @param sup supplementary data * @param cf color format of the source buffer * @param dest_buf the destination buffer @@ -175,22 +156,33 @@ void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc * Swap the upper and lower byte of an RGB565 buffer. * Might be required if a 8bit parallel port or an SPI port send the bytes in the wrong order. * The bytes will be swapped in place. + * @param buf pointer to buffer * @param buf_size_px number of pixels in the buffer */ void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px); /** - * Rotate a buffer into an other buffer + * Invert a draw buffer in the I1 color format. + * Conventionally, a bit is set to 1 during blending if the luminance is greater than 127. + * Depending on the display controller used, you might want to have different behavior. + * The inversion will be performed in place. + * @param buf pointer to the buffer to be inverted + * @param buf_size size of the buffer in bytes + */ +void lv_draw_sw_i1_invert(void * buf, uint32_t buf_size); + +/** + * Rotate a buffer into another buffer * @param src the source buffer * @param dest the destination buffer * @param src_width source width in pixels * @param src_height source height in pixels - * @param src_sride source stride in bytes (number of bytes in a row) + * @param src_stride source stride in bytes (number of bytes in a row) * @param dest_stride destination stride in bytes (number of bytes in a row) * @param rotation LV_DISPLAY_ROTATION_0/90/180/270 * @param color_format LV_COLOR_FORMAT_RGB565/RGB888/XRGB8888/ARGB8888 */ -void lv_draw_sw_rotate(const void * src, void * dest, int32_t src_width, int32_t src_height, int32_t src_sride, +void lv_draw_sw_rotate(const void * src, void * dest, int32_t src_width, int32_t src_height, int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation, lv_color_format_t color_format); /*********************** diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_arc.c index 5a205c173..ec2fb2fd9 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_arc.c @@ -6,6 +6,10 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "lv_draw_sw_mask_private.h" +#include "blend/lv_draw_sw_blend_private.h" +#include "../lv_image_decoder_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW #if LV_DRAW_SW_COMPLEX @@ -14,7 +18,7 @@ #include "../../misc/lv_log.h" #include "../../stdlib/lv_mem.h" #include "../../stdlib/lv_string.h" -#include "../lv_draw.h" +#include "../lv_draw_private.h" static void add_circle(const lv_opa_t * circle_mask, const lv_area_t * blend_area, const lv_area_t * circle_area, lv_opa_t * mask_buf, int32_t width); @@ -58,7 +62,7 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c lv_area_t area_out = *coords; lv_area_t clipped_area; - if(!_lv_area_intersect(&clipped_area, &area_out, draw_unit->clip_area)) return; + if(!lv_area_intersect(&clipped_area, &area_out, draw_unit->clip_area)) return; /*Draw a full ring*/ if(dsc->img_src == NULL && @@ -118,22 +122,34 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c blend_dsc.opa = dsc->opa; blend_dsc.blend_area = &blend_area; blend_dsc.mask_area = &blend_area; + + const uint8_t * img_mask = NULL; lv_image_decoder_dsc_t decoder_dsc; if(dsc->img_src == NULL) { blend_dsc.color = dsc->color; } else { - lv_image_decoder_open(&decoder_dsc, dsc->img_src, NULL); - img_area.x1 = 0; - img_area.y1 = 0; - img_area.x2 = decoder_dsc.decoded->header.w - 1; - img_area.y2 = decoder_dsc.decoded->header.h - 1; - int32_t ofs = decoder_dsc.decoded->header.w / 2; - lv_area_move(&img_area, dsc->center.x - ofs, dsc->center.y - ofs); - blend_dsc.src_area = &img_area; - blend_dsc.src_buf = decoder_dsc.decoded->data; - blend_dsc.src_color_format = decoder_dsc.decoded->header.cf; - blend_dsc.src_stride = decoder_dsc.decoded->header.stride; + lv_result_t res = lv_image_decoder_open(&decoder_dsc, dsc->img_src, NULL); + if(res == LV_RESULT_INVALID || decoder_dsc.decoded == NULL) { + LV_LOG_WARN("Can't decode the background image"); + blend_dsc.color = dsc->color; + } + else { + img_area.x1 = 0; + img_area.y1 = 0; + img_area.x2 = decoder_dsc.decoded->header.w - 1; + img_area.y2 = decoder_dsc.decoded->header.h - 1; + int32_t ofs = decoder_dsc.decoded->header.w / 2; + lv_area_move(&img_area, dsc->center.x - ofs, dsc->center.y - ofs); + blend_dsc.src_area = &img_area; + blend_dsc.src_buf = decoder_dsc.decoded->data; + blend_dsc.src_stride = decoder_dsc.decoded->header.stride; + blend_dsc.src_color_format = decoder_dsc.decoded->header.cf; + if(blend_dsc.src_color_format == LV_COLOR_FORMAT_RGB565A8) { + blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; + img_mask = (uint8_t *)blend_dsc.src_buf + blend_dsc.src_stride * lv_area_get_height(blend_dsc.src_area); + } + } } lv_opa_t * circle_mask = NULL; @@ -185,6 +201,21 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c } } + /*If it was an RGB565A8 image use consider its A8 part on the mask*/ + if(img_mask && blend_dsc.mask_res != LV_DRAW_SW_MASK_RES_TRANSP) { + const uint8_t * img_mask_tmp = img_mask; + img_mask_tmp += blend_dsc.src_stride / 2 * (blend_area.y1 - blend_dsc.src_area->y1); + img_mask_tmp += blend_area.x1 - blend_dsc.src_area->x1; + + int32_t i; + for(i = 0; i < blend_w; i++) { + mask_buf[i] = LV_OPA_MIX2(mask_buf[i], img_mask_tmp[i]); + } + if(blend_dsc.mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) { + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + } + } + lv_draw_sw_blend(draw_unit, &blend_dsc); blend_area.y1 ++; @@ -219,7 +250,7 @@ static void add_circle(const lv_opa_t * circle_mask, const lv_area_t * blend_are lv_opa_t * mask_buf, int32_t width) { lv_area_t circle_common_area; - if(_lv_area_intersect(&circle_common_area, circle_area, blend_area)) { + if(lv_area_intersect(&circle_common_area, circle_area, blend_area)) { const lv_opa_t * circle_mask_tmp = circle_mask + width * (circle_common_area.y1 - circle_area->y1); circle_mask_tmp += circle_common_area.x1 - circle_area->x1; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_border.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_border.c index c7f11919d..07eb18c0e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_border.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_border.c @@ -6,10 +6,14 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "lv_draw_sw_mask_private.h" +#include "../lv_draw_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW -#include "blend/lv_draw_sw_blend.h" +#include "blend/lv_draw_sw_blend_private.h" #include "../../misc/lv_math.h" #include "../../misc/lv_text_ap.h" #include "../../core/lv_refr.h" @@ -90,7 +94,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are /*Get clipped draw area which is the real draw area. *It is always the same or inside `coords`*/ lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, outer_area, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, outer_area, draw_unit->clip_area)) return; int32_t draw_area_w = lv_area_get_width(&draw_area); lv_draw_sw_blend_dsc_t blend_dsc; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_box_shadow.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_box_shadow.c index 67b93322c..f80287566 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_box_shadow.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_box_shadow.c @@ -6,12 +6,15 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "lv_draw_sw_mask_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW #if LV_DRAW_SW_COMPLEX -#include "blend/lv_draw_sw_blend.h" +#include "blend/lv_draw_sw_blend_private.h" #include "../../core/lv_global.h" #include "../../misc/lv_math.h" #include "../../core/lv_refr.h" @@ -74,7 +77,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ /*Get clipped draw area which is the real draw area. *It is always the same or inside `shadow_area`*/ lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &shadow_area, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, &shadow_area, draw_unit->clip_area)) return; /*Consider 1 px smaller bg to be sure the edge will be covered by the shadow*/ lv_area_t bg_area; @@ -161,15 +164,15 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.x1 = LV_MAX(blend_area.x1, w_half); blend_area.y2 = LV_MIN(blend_area.y2, h_half); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (clip_area_sub.y1 - shadow_area.y1) * corner_size; sh_buf_tmp += clip_area_sub.x1 - (shadow_area.x2 - corner_size + 1); /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; if(w > 0) { blend_dsc.mask_buf = mask_buf; @@ -204,14 +207,14 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.x1 = LV_MAX(blend_area.x1, w_half); blend_area.y1 = LV_MAX(blend_area.y1, h_half + 1); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (blend_area.y2 - clip_area_sub.y2) * corner_size; sh_buf_tmp += clip_area_sub.x1 - (shadow_area.x2 - corner_size + 1); /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; if(w > 0) { @@ -244,14 +247,14 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y2 = shadow_area.y1 + corner_size - 1; blend_area.y2 = LV_MIN(blend_area.y2, h_half); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (clip_area_sub.y1 - blend_area.y1) * corner_size; /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; if(w > 0) { @@ -291,14 +294,14 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y2 = shadow_area.y2; blend_area.y1 = LV_MAX(blend_area.y1, h_half + 1); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (blend_area.y2 - clip_area_sub.y2) * corner_size; if(w > 0) { /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; if(!simple_sub) { @@ -315,7 +318,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y2 = y; /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; if(!simple_sub) { @@ -346,15 +349,15 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y2 = LV_MAX(blend_area.y2, h_half); blend_area.x1 = LV_MAX(blend_area.x1, w_half); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (corner_size - 1) * corner_size; sh_buf_tmp += clip_area_sub.x1 - (shadow_area.x2 - corner_size + 1); /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; blend_dsc.mask_buf = simple_sub ? sh_buf_tmp : mask_buf; @@ -403,15 +406,15 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y2 = LV_MAX(blend_area.y2, h_half); blend_area.x2 = LV_MIN(blend_area.x2, w_half - 1); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (corner_size - 1) * corner_size; sh_buf_tmp += clip_area_sub.x1 - blend_area.x1; /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; blend_dsc.mask_buf = simple_sub ? sh_buf_tmp : mask_buf; if(w > 0) { @@ -442,15 +445,15 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.x2 = LV_MIN(blend_area.x2, w_half - 1); blend_area.y2 = LV_MIN(blend_area.y2, h_half); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (clip_area_sub.y1 - blend_area.y1) * corner_size; sh_buf_tmp += clip_area_sub.x1 - blend_area.x1; /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; blend_dsc.mask_buf = mask_buf; @@ -487,15 +490,15 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y1 = LV_MAX(blend_area.y1, h_half + 1); blend_area.x2 = LV_MIN(blend_area.x2, w_half - 1); - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); sh_buf_tmp = sh_buf; sh_buf_tmp += (blend_area.y2 - clip_area_sub.y2) * corner_size; sh_buf_tmp += clip_area_sub.x1 - blend_area.x1; /*Do not mask if out of the bg*/ - if(simple && _lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; + if(simple && lv_area_is_out(&clip_area_sub, &bg_area, r_bg)) simple_sub = true; else simple_sub = simple; blend_dsc.mask_buf = mask_buf; if(w > 0) { @@ -529,8 +532,8 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_area.y2 = LV_MAX(blend_area.y2, h_half); blend_dsc.mask_buf = mask_buf; - if(_lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && - !_lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { + if(lv_area_intersect(&clip_area_sub, &blend_area, draw_unit->clip_area) && + !lv_area_is_in(&clip_area_sub, &bg_area, r_bg)) { int32_t w = lv_area_get_width(&clip_area_sub); if(w > 0) { blend_area.x1 = clip_area_sub.x1; @@ -582,7 +585,7 @@ static void LV_ATTRIBUTE_FAST_MEM shadow_draw_corner_buf(const lv_area_t * coord lv_draw_sw_mask_radius_init(&mask_param, &sh_area, r, false); #if SHADOW_ENHANCE - /*Set half shadow width width because blur will be repeated*/ + /*Set half shadow width because blur will be repeated*/ if(sw_ori == 1) sw = 1; else sw = sw_ori >> 1; #endif /*SHADOW_ENHANCE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_fill.c index 027f3048d..0aeb55994 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_fill.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_fill.c * */ @@ -6,11 +6,14 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "lv_draw_sw_mask_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW -#include "blend/lv_draw_sw_blend.h" -#include "lv_draw_sw_gradient.h" +#include "blend/lv_draw_sw_blend_private.h" +#include "lv_draw_sw_gradient_private.h" #include "../../misc/lv_math.h" #include "../../misc/lv_text_ap.h" #include "../../core/lv_refr.h" @@ -42,7 +45,7 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; @@ -50,7 +53,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, lv_area_copy(&bg_coords, coords); lv_area_t clipped_coords; - if(!_lv_area_intersect(&clipped_coords, &bg_coords, draw_unit->clip_area)) return; + if(!lv_area_intersect(&clipped_coords, &bg_coords, draw_unit->clip_area)) return; lv_grad_dir_t grad_dir = dsc->grad.dir; lv_color_t bg_color = grad_dir == LV_GRAD_DIR_NONE ? dsc->color : dsc->grad.stops[0].color; @@ -103,10 +106,10 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, /*Get gradient if appropriate*/ lv_grad_t * grad = lv_gradient_get(&dsc->grad, coords_bg_w, coords_bg_h); lv_opa_t * grad_opa_map = NULL; - if(grad && grad_dir == LV_GRAD_DIR_HOR) { + bool transp = false; + if(grad && grad_dir >= LV_GRAD_DIR_HOR) { blend_dsc.src_area = &blend_area; blend_dsc.src_buf = grad->color_map + clipped_coords.x1 - bg_coords.x1; - bool transp = false; uint32_t s; for(s = 0; s < dsc->grad.stops_count; s++) { if(dsc->grad.stops[s].opa != LV_OPA_COVER) { @@ -114,18 +117,45 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, break; } } - - if(transp) grad_opa_map = grad->opa_map + clipped_coords.x1 - bg_coords.x1; - + if(grad_dir == LV_GRAD_DIR_HOR) { + if(transp) grad_opa_map = grad->opa_map + clipped_coords.x1 - bg_coords.x1; + } blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB888; } +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + + /*Prepare complex gradient*/ + if(grad_dir >= LV_GRAD_DIR_LINEAR) { + switch(grad_dir) { + case LV_GRAD_DIR_LINEAR: + lv_gradient_linear_setup(&dsc->grad, coords); + break; + case LV_GRAD_DIR_RADIAL: + lv_gradient_radial_setup(&dsc->grad, coords); + break; + case LV_GRAD_DIR_CONICAL: + lv_gradient_conical_setup(&dsc->grad, coords); + break; + default: + LV_LOG_WARN("Gradient type is not supported"); + return; + } + blend_dsc.src_area = &blend_area; + /* For complex gradients we reuse the color map buffer for the pixel data */ + blend_dsc.src_buf = grad->color_map; + grad_opa_map = grad->opa_map; + } +#endif + /* Draw the top of the rectangle line by line and mirror it to the bottom. */ for(h = 0; h < rout; h++) { int32_t top_y = bg_coords.y1 + h; int32_t bottom_y = bg_coords.y2 - h; if(top_y < clipped_coords.y1 && bottom_y > clipped_coords.y2) continue; /*This line is clipped now*/ + bool preblend = false; + /* Initialize the mask to opa instead of 0xFF and blend with LV_OPA_COVER. * It saves calculating the final opa in lv_draw_sw_blend*/ lv_memset(mask_buf, opa, clipped_w); @@ -137,19 +167,39 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, blend_area.y1 = top_y; blend_area.y2 = top_y; - if(grad_dir == LV_GRAD_DIR_VER) { - blend_dsc.color = grad->color_map[top_y - bg_coords.y1]; - blend_dsc.opa = grad->opa_map[top_y - bg_coords.y1]; + switch(grad_dir) { + case LV_GRAD_DIR_VER: + blend_dsc.color = grad->color_map[top_y - bg_coords.y1]; + blend_dsc.opa = grad->opa_map[top_y - bg_coords.y1]; + break; + case LV_GRAD_DIR_HOR: + hor_grad_processed = true; + preblend = grad_opa_map != NULL; + break; +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + case LV_GRAD_DIR_LINEAR: + lv_gradient_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); + preblend = true; + break; + case LV_GRAD_DIR_RADIAL: + lv_gradient_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); + preblend = true; + break; + case LV_GRAD_DIR_CONICAL: + lv_gradient_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); + preblend = true; + break; +#endif + default: + break; } - else if(grad_dir == LV_GRAD_DIR_HOR) { - hor_grad_processed = true; - if(grad_opa_map) { - int32_t i; - for(i = 0; i < clipped_w; i++) { - if(grad_opa_map[i] < LV_OPA_MAX) mask_buf[i] = (mask_buf[i] * grad_opa_map[i]) >> 8; - } - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + /* pre-blend the mask */ + if(preblend) { + int32_t i; + for(i = 0; i < clipped_w; i++) { + if(grad_opa_map[i] < LV_OPA_MAX) mask_buf[i] = (mask_buf[i] * grad_opa_map[i]) >> 8; } + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; } lv_draw_sw_blend(draw_unit, &blend_dsc); } @@ -158,18 +208,44 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, blend_area.y1 = bottom_y; blend_area.y2 = bottom_y; - if(grad_dir == LV_GRAD_DIR_VER) { - blend_dsc.color = grad->color_map[bottom_y - bg_coords.y1]; - blend_dsc.opa = grad->opa_map[bottom_y - bg_coords.y1]; + switch(grad_dir) { + case LV_GRAD_DIR_VER: + blend_dsc.color = grad->color_map[bottom_y - bg_coords.y1]; + blend_dsc.opa = grad->opa_map[bottom_y - bg_coords.y1]; + break; + case LV_GRAD_DIR_HOR: + preblend = !hor_grad_processed && (grad_opa_map != NULL); + break; +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + case LV_GRAD_DIR_LINEAR: + lv_gradient_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, grad); + preblend = true; + break; + case LV_GRAD_DIR_RADIAL: + lv_gradient_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, grad); + preblend = true; + break; + case LV_GRAD_DIR_CONICAL: + lv_gradient_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, grad); + preblend = true; + break; +#endif + default: + break; } - else if(hor_grad_processed == false && grad_dir == LV_GRAD_DIR_HOR) { - if(grad_opa_map) { - int32_t i; - for(i = 0; i < clipped_w; i++) { - if(grad_opa_map[i] < LV_OPA_MAX) mask_buf[i] = (mask_buf[i] * grad_opa_map[i]) >> 8; - } - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + /* pre-blend the mask */ + if(preblend) { + int32_t i; + if(grad_dir >= LV_GRAD_DIR_LINEAR) { + /*Need to generate the mask again, because we have mixed in the upper part of the gradient*/ + lv_memset(mask_buf, opa, clipped_w); + blend_dsc.mask_res = lv_draw_sw_mask_apply(mask_list, mask_buf, blend_area.x1, top_y, clipped_w); + if(blend_dsc.mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; } + for(i = 0; i < clipped_w; i++) { + if(grad_opa_map[i] < LV_OPA_MAX) mask_buf[i] = (mask_buf[i] * grad_opa_map[i]) >> 8; + } + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; } lv_draw_sw_blend(draw_unit, &blend_dsc); } @@ -188,23 +264,48 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, /*With gradient draw line by line*/ else { blend_dsc.opa = opa; - if(grad_dir == LV_GRAD_DIR_VER) { - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_FULL_COVER; - } - else if(grad_dir == LV_GRAD_DIR_HOR) { - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; - blend_dsc.mask_buf = grad_opa_map; + switch(grad_dir) { + case LV_GRAD_DIR_VER: + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_FULL_COVER; + break; + case LV_GRAD_DIR_HOR: + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + blend_dsc.mask_buf = grad_opa_map; + break; + case LV_GRAD_DIR_LINEAR: + case LV_GRAD_DIR_RADIAL: + case LV_GRAD_DIR_CONICAL: + blend_dsc.mask_res = transp ? LV_DRAW_SW_MASK_RES_CHANGED : LV_DRAW_SW_MASK_RES_FULL_COVER; + blend_dsc.mask_buf = grad_opa_map; + default: + break; } - int32_t h_end = bg_coords.y2 - rout; - for(h = bg_coords.y1 + rout; h <= h_end; h++) { + int32_t h_start = LV_MAX(bg_coords.y1 + rout, clipped_coords.y1); + int32_t h_end = LV_MIN(bg_coords.y2 - rout, clipped_coords.y2); + for(h = h_start; h <= h_end; h++) { blend_area.y1 = h; blend_area.y2 = h; - if(grad_dir == LV_GRAD_DIR_VER) { - blend_dsc.color = grad->color_map[h - bg_coords.y1]; - if(opa >= LV_OPA_MAX) blend_dsc.opa = grad->opa_map[h - bg_coords.y1]; - else blend_dsc.opa = LV_OPA_MIX2(grad->opa_map[h - bg_coords.y1], opa); + switch(grad_dir) { + case LV_GRAD_DIR_VER: + blend_dsc.color = grad->color_map[h - bg_coords.y1]; + if(opa >= LV_OPA_MAX) blend_dsc.opa = grad->opa_map[h - bg_coords.y1]; + else blend_dsc.opa = LV_OPA_MIX2(grad->opa_map[h - bg_coords.y1], opa); + break; +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + case LV_GRAD_DIR_LINEAR: + lv_gradient_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); + break; + case LV_GRAD_DIR_RADIAL: + lv_gradient_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); + break; + case LV_GRAD_DIR_CONICAL: + lv_gradient_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); + break; +#endif + default: + break; } lv_draw_sw_blend(draw_unit, &blend_dsc); } @@ -217,6 +318,23 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, if(grad) { lv_gradient_cleanup(grad); } +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + if(grad_dir >= LV_GRAD_DIR_LINEAR) { + switch(grad_dir) { + case LV_GRAD_DIR_LINEAR: + lv_gradient_linear_cleanup(&dsc->grad); + break; + case LV_GRAD_DIR_RADIAL: + lv_gradient_radial_cleanup(&dsc->grad); + break; + case LV_GRAD_DIR_CONICAL: + lv_gradient_conical_cleanup(&dsc->grad); + break; + default: + break; + } + } +#endif #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.c index 2e855644c..92627108c 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_gradient.c * */ @@ -6,11 +6,12 @@ /********************* * INCLUDES *********************/ -#include "lv_draw_sw_gradient.h" +#include "lv_draw_sw_gradient_private.h" #if LV_USE_DRAW_SW #include "../../misc/lv_types.h" #include "../../osal/lv_os.h" +#include "../../misc/lv_math.h" /********************* * DEFINES @@ -25,12 +26,61 @@ #define ALIGN(X) (((X) + 3) & ~3) #endif +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +typedef struct { + /* w = (-b(xp, yp) + sqrt(sqr(b(xp, yp)) - 4 * a * c(xp, yp))) / (2 * a) */ + int32_t x0; /* center of the start circle */ + int32_t y0; /* center of the start circle */ + int32_t r0; /* radius of the start circle */ + int32_t inv_dr; /* 1 / (r1 - r0) */ + int32_t a4; /* 4 * a */ + int32_t inv_a4; /* 1 / (4 * a) */ + int32_t dx; + /* b(xp, yp) = xp * bpx + yp * bpy + bc */ + int32_t bpx; + int32_t bpy; + int32_t bc; + lv_area_t clip_area; + lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ +} lv_grad_radial_state_t; + +typedef struct { + /* w = a * xp + b * yp + c */ + int32_t a; + int32_t b; + int32_t c; + lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ +} lv_grad_linear_state_t; + +typedef struct { + /* w = a * xp + b * yp + c */ + int32_t x0; + int32_t y0; + int32_t a; + int32_t da; + int32_t inv_da; + lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ +} lv_grad_conical_state_t; + +#endif + /********************** * STATIC PROTOTYPES **********************/ typedef lv_result_t (*op_cache_t)(lv_grad_t * c, void * ctx); static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + + static inline int32_t extend_w(int32_t w, lv_grad_extend_t extend); + +#endif + /********************** * STATIC VARIABLE **********************/ @@ -41,7 +91,20 @@ static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) { - int32_t size = g->dir == LV_GRAD_DIR_HOR ? w : h; + int32_t size; + switch(g->dir) { + case LV_GRAD_DIR_HOR: + case LV_GRAD_DIR_LINEAR: + case LV_GRAD_DIR_RADIAL: + case LV_GRAD_DIR_CONICAL: + size = w; + break; + case LV_GRAD_DIR_VER: + size = h; + break; + default: + size = 64; + } size_t req_size = ALIGN(sizeof(lv_grad_t)) + ALIGN(size * sizeof(lv_color_t)) + ALIGN(size * sizeof(lv_opa_t)); lv_grad_t * item = lv_malloc(req_size); @@ -55,6 +118,25 @@ static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) return item; } +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +static inline int32_t extend_w(int32_t w, lv_grad_extend_t extend) +{ + if(extend == LV_GRAD_EXTEND_PAD) { /**< Repeat the same color*/ + return w < 0 ? 0 : LV_MIN(w, 255); + } + if(extend == LV_GRAD_EXTEND_REPEAT) { /**< Repeat the pattern*/ + return w & 255; + } + /*LV_GRAD_EXTEND_REFLECT*/ + w &= 511; + if(w > 255) + w ^= 511; /* 511 - w */ + return w; +} + +#endif + /********************** * FUNCTIONS **********************/ @@ -137,4 +219,450 @@ void lv_gradient_cleanup(lv_grad_t * grad) lv_free(grad); } +void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], + const uint8_t fracs[], int num_stops) +{ + LV_ASSERT(num_stops <= LV_GRADIENT_MAX_STOPS); + grad->stops_count = num_stops; + for(int i = 0; i < num_stops; i++) { + grad->stops[i].color = colors[i]; + grad->stops[i].opa = opa != NULL ? opa[i] : LV_OPA_COVER; + grad->stops[i].frac = fracs != NULL ? fracs[i] : 255 * i / (num_stops - 1); + } +} + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +/* + Calculate radial gradient based on the following equation: + + | P - (C1 - C0)w - C0 | = (r1 - r0)w + r0, where + + P: {xp, yp} is the point of interest + C0: {x0, y0} is the center of the start circle + C1: {x1, y1} is the center of the end circle + r0 is the radius of the start circle + r1 is the radius of the end circle + w is the unknown variable + || is the length of the vector + + The above equation can be rewritten as: + + ((r1-r0)^2 - (x1-x0)^2 - (y1-y0)^2) * w^2 + 2*((xp-x0)*(x1-x0) + (yp-y0)*(y1-y0)) * w + (-(xp-x0)^2 - (yp-y0)^) = 0 + + The roots of the quadratical equation can be obtained using the well-known formula (-b +- sqrt(b^2 - 4ac)) / 2a + We only need the more positive root. + + Let's denote + dx = x1 - x0 + dy = y1 - y0 + dr = r1 - r0 + + Thus: + + w = (-b(xp, yp) + sqrt(sqr(b(xp, yp)) - 4 * a * c(xp, yp))) / (2 * a), where + + b(xp, yp) = 2dx * xp + 2dy * yp + 2(r0 * dr - x0 * dx - y0 * dy) + c(xp, yp) = r0^2 - (xp - x0)^2 - (yp - y0)^2 + + Rewrite b(xp, yp) as: + + b(xp, yp) = xp * bpx + yp * bpy + bc, where + + bpx = 2dx + bpy = 2dy + bc = 2(r0 * dr - x0 * dx - y0 * dy) + + We can pre-calculate the constants, because they do not depend on the pixel coordinates. + +*/ + +void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +{ + lv_point_t start = dsc->params.radial.focal; + lv_point_t end = dsc->params.radial.end; + lv_point_t start_extent = dsc->params.radial.focal_extent; + lv_point_t end_extent = dsc->params.radial.end_extent; + lv_grad_radial_state_t * state = lv_malloc(sizeof(lv_grad_radial_state_t)); + dsc->state = state; + + /* Convert from percentage coordinates */ + int32_t wdt = lv_area_get_width(coords); + int32_t hgt = lv_area_get_height(coords); + + start.x = lv_pct_to_px(start.x, wdt); + end.x = lv_pct_to_px(end.x, wdt); + start_extent.x = lv_pct_to_px(start_extent.x, wdt); + end_extent.x = lv_pct_to_px(end_extent.x, wdt); + start.y = lv_pct_to_px(start.y, hgt); + end.y = lv_pct_to_px(end.y, hgt); + start_extent.y = lv_pct_to_px(start_extent.y, hgt); + end_extent.y = lv_pct_to_px(end_extent.y, hgt); + + /* Calculate radii */ + int16_t r_start = lv_sqrt32(lv_sqr(start_extent.x - start.x) + lv_sqr(start_extent.y - start.y)); + int16_t r_end = lv_sqrt32(lv_sqr(end_extent.x - end.x) + lv_sqr(end_extent.y - end.y)); + LV_ASSERT(r_end != 0); + + /* Create gradient color map */ + state->cgrad = lv_gradient_get(dsc, 256, 0); + + state->x0 = start.x; + state->y0 = start.y; + state->r0 = r_start; + int32_t dr = r_end - r_start; + if(end.x == start.x && end.y == start.y) { + LV_ASSERT(dr != 0); + state->a4 = lv_sqr(dr) << 2; + state->bpx = 0; + state->bpy = 0; + state->bc = (state->r0 * dr) << 1; + state->dx = 0; + state->inv_dr = (1 << (8 + 16)) / dr; + } + else { + int32_t dx = end.x - start.x; + int32_t dy = end.y - start.y; + state->dx = dx; /* needed for incremental calculation */ + state->a4 = (lv_sqr(dr) - lv_sqr(dx) - lv_sqr(dy)) << 2; + /* b(xp, yp) = xp * bpx + yp * bpy + bc */ + state->bpx = dx << 1; + state->bpy = dy << 1; + state->bc = (state->r0 * dr - state->x0 * dx - state->y0 * dy) << 1; + } + state->inv_a4 = state->a4 != 0 ? (1 << (13 + 16)) / state->a4 : 0; + /* check for possible clipping */ + if(dsc->extend == LV_GRAD_EXTEND_PAD && + /* if extend mode is 'pad', then we can clip to the end circle's bounding box, if the start circle is entirely within the end circle */ + (lv_sqr(start.x - end.x) + lv_sqr(start.y - end.y) < lv_sqr(r_end - r_start))) { + if(r_end > r_start) { + lv_area_set(&state->clip_area, end.x - r_end, end.y - r_end, end.x + r_end, end.y + r_end); + } + else { + lv_area_set(&state->clip_area, start.x - r_start, start.y - r_start, start.x + r_start, start.y + r_start); + } + } + else { + state->clip_area.x1 = -0x7fffffff; + } +} + +void lv_gradient_radial_cleanup(lv_grad_dsc_t * dsc) +{ + lv_grad_radial_state_t * state = dsc->state; + if(state == NULL) + return; + if(state->cgrad) + lv_gradient_cleanup(state->cgrad); + lv_free(state); +} + +void LV_ATTRIBUTE_FAST_MEM lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_grad_t * result) +{ + lv_grad_radial_state_t * state = (lv_grad_radial_state_t *)dsc->state; + lv_color_t * buf = result->color_map; + lv_opa_t * opa = result->opa_map; + lv_grad_t * grad = state->cgrad; + + int32_t w; /* the result: this is an offset into the 256 element gradient color table */ + int32_t b, db, c, dc; + + /* check for possible clipping */ + if(state->clip_area.x1 != -0x7fffffff) { + /* fill line with end color for pixels outside the clipped region */ + lv_color_t * _buf = buf; + lv_opa_t * _opa = opa; + lv_color_t _c = grad->color_map[255]; + lv_opa_t _o = grad->opa_map[255]; + int32_t _w = width; + for(; _w > 0; _w--) { + *_buf++ = _c; + *_opa++ = _o; + } + /* is this line fully outside the clip area? */ + if(yp < state->clip_area.y1 || + yp >= state->clip_area.y2 || + xp >= state->clip_area.x2 || + xp + width < state->clip_area.x1) { + return; + } + else { /* not fully outside: clip line to the bounding box */ + int32_t _x1 = LV_MAX(xp, state->clip_area.x1); + int32_t _x2 = LV_MIN(xp + width, state->clip_area.x2); + buf += _x1 - xp; + opa += _x1 - xp; + xp = _x1; + width = _x2 - _x1; + } + } + + b = xp * state->bpx + yp * state->bpy + state->bc; + c = lv_sqr(state->r0) - lv_sqr(xp - state->x0) - lv_sqr(yp - state->y0); + /* We can save some calculations by using the previous values of b and c */ + db = state->dx << 1; + dc = ((xp - state->x0) << 1) + 1; + + if(state->a4 == 0) { /* not a quadratic equation: solve linear equation: w = -c/b */ + for(; width > 0; width--) { + w = extend_w(b == 0 ? 0 : -(c << 8) / b, dsc->extend); + *buf++ = grad->color_map[w]; + *opa++ = grad->opa_map[w]; + b += db; + c -= dc; + dc += 2; + } + } + else { /* solve quadratical equation */ + if(state->bpx || + state->bpy) { /* general case (circles are not concentric): w = (-b + sqrt(b^2 - 4ac))/2a (we only need the more positive root)*/ + int32_t a4 = state->a4 >> 4; + for(; width > 0; width--) { + int32_t det = lv_sqr(b >> 4) - (a4 * (c >> 4)); /* b^2 shifted down by 2*4=8, 4ac shifted down by 8 */ + /* check determinant: if negative, then there is no solution: use starting color */ + w = det < 0 ? 0 : extend_w(((lv_sqrt32(det) - (b >> 4)) * state->inv_a4) >> 16, + dsc->extend); /* square root shifted down by 4 (includes *256 to set output range) */ + *buf++ = grad->color_map[w]; + *opa++ = grad->opa_map[w]; + b += db; + c -= dc; + dc += 2; + } + } + else { /* special case: concentric circles: w = (sqrt((xp-x0)^2 + (yx-y0)^2)-r0)/(r1-r0) */ + c = lv_sqr(xp - state->x0) + lv_sqr(yp - state->y0); + for(; width > 0; width--) { + w = extend_w((((lv_sqrt32(c) - state->r0)) * state->inv_dr) >> 16, dsc->extend); + *buf++ = grad->color_map[w]; + *opa++ = grad->opa_map[w]; + c += dc; + dc += 2; + } + } + } +} + +/* + Calculate linear gradient based on the following equation: + + w = ((P - C0) x (C1 - C0)) / | C1 - C0 |^2, where + + P: {xp, yp} is the point of interest + C0: {x0, y0} is the start point of the gradient vector + C1: {x1, y1} is the end point of the gradient vector + w is the unknown variable + + || is the length of the vector + x is a dot product + + The above equation can be rewritten as: + + w = xp * (dx / (dx^2 + dy^2)) + yp * (dy / (dx^2 + dy^2)) - (x0 * dx + y0 * dy) / (dx^2 + dy^2), where + + dx = x1 - x0 + dy = y1 - y0 + + We can pre-calculate the constants, because they do not depend on the pixel coordinates. + +*/ + +void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +{ + lv_point_t start = dsc->params.linear.start; + lv_point_t end = dsc->params.linear.end; + lv_grad_linear_state_t * state = lv_malloc(sizeof(lv_grad_linear_state_t)); + dsc->state = state; + + /* Create gradient color map */ + state->cgrad = lv_gradient_get(dsc, 256, 0); + + /* Convert from percentage coordinates */ + int32_t wdt = lv_area_get_width(coords); + int32_t hgt = lv_area_get_height(coords); + + start.x = lv_pct_to_px(start.x, wdt); + end.x = lv_pct_to_px(end.x, wdt); + start.y = lv_pct_to_px(start.y, hgt); + end.y = lv_pct_to_px(end.y, hgt); + + /* Precalculate constants */ + int32_t dx = end.x - start.x; + int32_t dy = end.y - start.y; + + int32_t l2 = lv_sqr(dx) + lv_sqr(dy); + state->a = (dx << 16) / l2; + state->b = (dy << 16) / l2; + state->c = ((start.x * dx + start.y * dy) << 16) / l2; +} + +void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc) +{ + lv_grad_linear_state_t * state = dsc->state; + if(state == NULL) + return; + if(state->cgrad) + lv_free(state->cgrad); + lv_free(state); +} + +void LV_ATTRIBUTE_FAST_MEM lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_grad_t * result) +{ + lv_grad_linear_state_t * state = (lv_grad_linear_state_t *)dsc->state; + lv_color_t * buf = result->color_map; + lv_opa_t * opa = result->opa_map; + lv_grad_t * grad = state->cgrad; + + int32_t w; /* the result: this is an offset into the 256 element gradient color table */ + int32_t x, d; + + x = xp * state->a + yp * state->b - state->c; + d = state->a; + + for(; width > 0; width--) { + w = extend_w(x >> 8, dsc->extend); + *buf++ = grad->color_map[w]; + *opa++ = grad->opa_map[w]; + x += d; + } +} + +/* + Calculate conical gradient based on the following equation: + + w = (atan((yp - y0)/(xp - x0)) - alpha) / (beta - alpha), where + + P: {xp, yp} is the point of interest + C0: {x0, y0} is the center of the gradient + alpha is the start angle + beta is the end angle + w is the unknown variable +*/ + +void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +{ + lv_point_t c0 = dsc->params.conical.center; + int32_t alpha = dsc->params.conical.start_angle % 360; + int32_t beta = dsc->params.conical.end_angle % 360; + lv_grad_conical_state_t * state = lv_malloc(sizeof(lv_grad_conical_state_t)); + dsc->state = state; + + /* Create gradient color map */ + state->cgrad = lv_gradient_get(dsc, 256, 0); + + /* Convert from percentage coordinates */ + int32_t wdt = lv_area_get_width(coords); + int32_t hgt = lv_area_get_height(coords); + + c0.x = lv_pct_to_px(c0.x, wdt); + c0.y = lv_pct_to_px(c0.y, hgt); + + /* Precalculate constants */ + if(beta <= alpha) + beta += 360; + state->x0 = c0.x; + state->y0 = c0.y; + state->a = alpha; + state->da = beta - alpha; + state->inv_da = (1 << 16) / (beta - alpha); +} + +void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc) +{ + lv_grad_conical_state_t * state = dsc->state; + if(state == NULL) + return; + if(state->cgrad) + lv_free(state->cgrad); + lv_free(state); +} + +void LV_ATTRIBUTE_FAST_MEM lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_grad_t * result) +{ + lv_grad_conical_state_t * state = (lv_grad_conical_state_t *)dsc->state; + lv_color_t * buf = result->color_map; + lv_opa_t * opa = result->opa_map; + lv_grad_t * grad = state->cgrad; + + int32_t w; /* the result: this is an offset into the 256 element gradient color table */ + int32_t dx = xp - state->x0; + int32_t dy = yp - state->y0; + + if(dy == 0) { /* we will eventually go through the center of the conical: need an extra test in the loop to avoid both dx and dy being zero in atan2 */ + for(; width > 0; width--) { + if(dx == 0) { + w = 0; + } + else { + int32_t d = lv_atan2(dy, dx) - state->a; + if(d < 0) + d += 360; + w = extend_w((d * state->inv_da) >> 8, dsc->extend); + } + *buf++ = grad->color_map[w]; + *opa++ = grad->opa_map[w]; + dx++; + } + } + else { + for(; width > 0; width--) { + int32_t d = lv_atan2(dy, dx) - state->a; + if(d < 0) + d += 360; + w = extend_w((d * state->inv_da) >> 8, dsc->extend); + *buf++ = grad->color_map[w]; + *opa++ = grad->opa_map[w]; + dx++; + } + } +} + +void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend) +{ + dsc->dir = LV_GRAD_DIR_LINEAR; + dsc->params.linear.start.x = from_x; + dsc->params.linear.start.y = from_y; + dsc->params.linear.end.x = to_x; + dsc->params.linear.end.y = to_y; + dsc->extend = extend; +} + +void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend) +{ + dsc->dir = LV_GRAD_DIR_RADIAL; + dsc->params.radial.focal.x = center_x; + dsc->params.radial.focal.y = center_y; + dsc->params.radial.focal_extent.x = center_x; + dsc->params.radial.focal_extent.y = center_y; + dsc->params.radial.end.x = center_x; + dsc->params.radial.end.y = center_y; + dsc->params.radial.end_extent.x = to_x; + dsc->params.radial.end_extent.y = to_y; + dsc->extend = extend; +} + +void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, + int32_t end_angle, lv_grad_extend_t extend) +{ + dsc->dir = LV_GRAD_DIR_CONICAL; + dsc->params.conical.center.x = center_x; + dsc->params.conical.center.y = center_y; + dsc->params.conical.start_angle = start_angle; + dsc->params.conical.end_angle = end_angle; + dsc->extend = extend; +} + +void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius) +{ + dsc->params.radial.focal.x = center_x; + dsc->params.radial.focal.y = center_y; + dsc->params.radial.focal_extent.x = center_x + radius; + dsc->params.radial.focal_extent.y = center_y; +} + +#endif /* LV_USE_DRAW_SW_COMPLEX_GRADIENTS */ + #endif /*LV_USE_DRAW_SW*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.h index 09bb3771c..01029cbab 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_gradient.h * */ @@ -25,17 +25,17 @@ extern "C" { #error LVGL needs at least 2 stops for gradients. Please increase the LV_GRADIENT_MAX_STOPS #endif +#define LV_GRAD_LEFT LV_PCT(0) +#define LV_GRAD_RIGHT LV_PCT(100) +#define LV_GRAD_TOP LV_PCT(0) +#define LV_GRAD_BOTTOM LV_PCT(100) +#define LV_GRAD_CENTER LV_PCT(50) + /********************** * TYPEDEFS **********************/ typedef lv_color_t lv_grad_color_t; -typedef struct _lv_gradient_cache_t { - lv_color_t * color_map; - lv_opa_t * opa_map; - uint32_t size; -} lv_grad_t; - /********************** * PROTOTYPES **********************/ @@ -44,6 +44,8 @@ typedef struct _lv_gradient_cache_t { * @param dsc The gradient descriptor to use * @param range The range to use in computation. * @param frac The current part used in the range. frac is in [0; range] + * @param color_out Calculated gradient color + * @param opa_out Calculated opacity */ void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, @@ -58,6 +60,140 @@ lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * gradient, int32_t w, int32_t h */ void lv_gradient_cleanup(lv_grad_t * grad); +/** + * Initialize gradient color map from a table + * @param grad pointer to a gradient descriptor + * @param colors color array + * @param fracs position array (0..255): if NULL, then colors are distributed evenly + * @param opa opacity array: if NULL, then LV_OPA_COVER is assumed + * @param num_stops number of gradient stops (1..LV_GRADIENT_MAX_STOPS) + */ +void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], + const uint8_t fracs[], int num_stops); + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +/** + * Helper function to initialize linear gradient + * @param dsc gradient descriptor + * @param from_x start x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param from_y start y position + * @param to_x end x position + * @param to_y end y position + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend); + +/** + * Helper function to initialize radial gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param to_x point on the end circle x position + * @param to_y point on the end circle y position + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend); + +/** + * Set focal (starting) circle of a radial gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param radius radius of the starting circle (NOTE: this must be a scalar number, not percentage) + */ +void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius); + +/** + * Helper function to initialize conical gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param start_angle start angle in degrees + * @param end_angle end angle in degrees + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, + int32_t end_angle, lv_grad_extend_t extend); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + */ +void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a linear gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, int32_t width, + lv_grad_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + */ +void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_gradient_radial_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a radial gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, int32_t width, + lv_grad_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + */ +void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a conical gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_grad_t * result); + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + #endif /*LV_USE_DRAW_SW*/ #ifdef __cplusplus diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h new file mode 100644 index 000000000..7e2f2ab3d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h @@ -0,0 +1,50 @@ +/** + * @file lv_draw_sw_gradient_private.h + * + */ + +#ifndef LV_DRAW_SW_GRADIENT_PRIVATE_H +#define LV_DRAW_SW_GRADIENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw_gradient.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_grad_t { + lv_color_t * color_map; + lv_opa_t * opa_map; + uint32_t size; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_GRADIENT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_img.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_img.c index 2f6dcf34a..42179a2a2 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_img.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_img.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_img.c * */ @@ -6,13 +6,18 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "blend/lv_draw_sw_blend_private.h" +#include "../lv_image_decoder_private.h" +#include "../lv_draw_image_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW #include "../../display/lv_display.h" #include "../../display/lv_display_private.h" #include "../../misc/lv_log.h" -#include "../../core/lv_refr.h" +#include "../../core/lv_refr_private.h" #include "../../stdlib/lv_mem.h" #include "../../misc/lv_math.h" #include "../../misc/lv_color.h" @@ -28,7 +33,7 @@ /********************* * DEFINES *********************/ -#define MAX_BUF_SIZE (uint32_t) (4 * lv_display_get_horizontal_resolution(_lv_refr_get_disp_refreshing()) * lv_color_format_get_size(lv_display_get_color_format(_lv_refr_get_disp_refreshing()))) +#define MAX_BUF_SIZE (uint32_t) (4 * lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing()) * lv_color_format_get_size(lv_display_get_color_format(lv_refr_get_disp_refreshing()))) #ifndef LV_DRAW_SW_IMAGE #define LV_DRAW_SW_IMAGE(...) LV_RESULT_INVALID @@ -85,8 +90,8 @@ void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr int32_t w = lv_area_get_width(coords); int32_t h = lv_area_get_height(coords); - _lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, - &draw_dsc->pivot); + lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, + &draw_dsc->pivot); area_rot.x1 += coords->x1; area_rot.y1 += coords->y1; @@ -94,7 +99,7 @@ void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr area_rot.y2 += coords->y1; } lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return; #endif #if LV_USE_LAYER_DEBUG @@ -123,13 +128,13 @@ void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr lv_draw_fill_dsc_t fill_dsc; lv_draw_rect_dsc_init(&fill_dsc); - fill_dsc.color = lv_palette_main(idx % _LV_PALETTE_LAST); + fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); fill_dsc.opa = LV_OPA_10; lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); lv_draw_border_dsc_t border_dsc; lv_draw_border_dsc_init(&border_dsc); - border_dsc.color = lv_palette_main(idx % _LV_PALETTE_LAST); + border_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); border_dsc.opa = LV_OPA_100; border_dsc.width = 2; lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); @@ -161,10 +166,10 @@ void lv_draw_sw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr const lv_area_t * coords) { if(!draw_dsc->tile) { - _lv_draw_image_normal_helper(draw_unit, draw_dsc, coords, img_draw_core); + lv_draw_image_normal_helper(draw_unit, draw_dsc, coords, img_draw_core); } else { - _lv_draw_image_tiled_helper(draw_unit, draw_dsc, coords, img_draw_core); + lv_draw_image_tiled_helper(draw_unit, draw_dsc, coords, img_draw_core); } } @@ -195,7 +200,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t if(!transformed && !masked && cf == LV_COLOR_FORMAT_A8) { lv_area_t clipped_coords; - if(!_lv_area_intersect(&clipped_coords, img_coords, draw_unit->clip_area)) return; + if(!lv_area_intersect(&clipped_coords, img_coords, draw_unit->clip_area)) return; blend_dsc.mask_buf = (lv_opa_t *)src_buf; blend_dsc.mask_area = img_coords; @@ -236,24 +241,41 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t } /*Handle masked RGB565, RGB888, XRGB888, or ARGB8888 images*/ else if(!transformed && masked && draw_dsc->recolor_opa <= LV_OPA_MIN) { + lv_image_decoder_dsc_t mask_decoder_dsc; + lv_area_t mask_area; + lv_result_t decoder_res = lv_image_decoder_open(&mask_decoder_dsc, draw_dsc->bitmap_mask_src, NULL); + if(decoder_res == LV_RESULT_OK && mask_decoder_dsc.decoded) { + if(mask_decoder_dsc.decoded->header.cf == LV_COLOR_FORMAT_A8 || + mask_decoder_dsc.decoded->header.cf == LV_COLOR_FORMAT_L8) { + const lv_draw_buf_t * mask_img = mask_decoder_dsc.decoded; + blend_dsc.mask_buf = mask_img->data; + blend_dsc.mask_stride = mask_img->header.stride; + + const lv_area_t * image_area; + if(lv_area_get_width(&draw_dsc->image_area) < 0) image_area = img_coords; + else image_area = &draw_dsc->image_area; + lv_area_set(&mask_area, 0, 0, mask_img->header.w - 1, mask_img->header.h - 1); + lv_area_align(image_area, &mask_area, LV_ALIGN_CENTER, 0, 0); + blend_dsc.mask_area = &mask_area; + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + } + else { + LV_LOG_WARN("The mask image is not A8/L8 format. Drawing the image without mask."); + } + } + else { + LV_LOG_WARN("Couldn't decode the mask image. Drawing the image without mask."); + } + blend_dsc.src_area = img_coords; blend_dsc.src_buf = src_buf; blend_dsc.blend_area = img_coords; blend_dsc.src_color_format = cf; - blend_dsc.mask_buf = draw_dsc->bitmap_mask_src->data; - blend_dsc.mask_stride = draw_dsc->bitmap_mask_src->header.stride; - - const lv_area_t * original_area; - if(lv_area_get_width(&draw_dsc->original_area) < 0) original_area = img_coords; - else original_area = &draw_dsc->original_area; - - lv_area_t a = {0, 0, draw_dsc->bitmap_mask_src->header.w - 1, draw_dsc->bitmap_mask_src->header.h - 1}; - lv_area_align(original_area, &a, LV_ALIGN_CENTER, 0, 0); - blend_dsc.mask_area = &a; - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; lv_draw_sw_blend(draw_unit, &blend_dsc); + + if(decoder_res == LV_RESULT_OK) lv_image_decoder_close(&mask_decoder_dsc); } - /* check whether it is possible to accelerate the operation in synchronouse mode */ + /* check whether it is possible to accelerate the operation in synchronous mode */ else if(LV_RESULT_INVALID == LV_DRAW_SW_IMAGE(transformed, /* whether require transform */ cf, /* image format */ src_buf, /* image buffer */ @@ -273,9 +295,13 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t int32_t blend_h = lv_area_get_height(&blend_area); lv_color_format_t cf_final = cf; + if((cf == LV_COLOR_FORMAT_L8) && (draw_dsc->recolor_opa > LV_OPA_MIN)) { + cf_final = LV_COLOR_FORMAT_ARGB8888; + } if(transformed) { - if(cf == LV_COLOR_FORMAT_RGB888 || cf == LV_COLOR_FORMAT_XRGB8888) cf_final = LV_COLOR_FORMAT_ARGB8888; - else if(cf == LV_COLOR_FORMAT_RGB565) cf_final = LV_COLOR_FORMAT_RGB565A8; + if(cf_final == LV_COLOR_FORMAT_RGB888 || cf_final == LV_COLOR_FORMAT_XRGB8888) cf_final = LV_COLOR_FORMAT_ARGB8888; + else if(cf_final == LV_COLOR_FORMAT_RGB565) cf_final = LV_COLOR_FORMAT_RGB565A8; + else if(cf_final == LV_COLOR_FORMAT_L8) cf_final = LV_COLOR_FORMAT_AL88; } uint8_t * tmp_buf; @@ -334,7 +360,23 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t } else if(draw_dsc->recolor_opa >= LV_OPA_MIN) { int32_t h = lv_area_get_height(&relative_area); - if(cf_final == LV_COLOR_FORMAT_RGB565A8) { + if(cf == LV_COLOR_FORMAT_L8) { + /* L8 is recolored, but not transformed: copy L8 image into ARGB8888 temporary buffer */ + const uint8_t * src_buf_tmp = src_buf + img_stride * relative_area.y1 + relative_area.x1 * 1; + lv_color32_t * dest_buf_tmp = (lv_color32_t *)tmp_buf; + int32_t i, x; + for(i = 0; i < h; i++) { + for(x = 0; x < blend_w; x++) { + dest_buf_tmp[x].red = src_buf_tmp[x]; + dest_buf_tmp[x].green = src_buf_tmp[x]; + dest_buf_tmp[x].blue = src_buf_tmp[x]; + dest_buf_tmp[x].alpha = 255; + } + dest_buf_tmp += blend_w; + src_buf_tmp += img_stride; + } + } + else if(cf_final == LV_COLOR_FORMAT_RGB565A8) { uint32_t stride_px = img_stride / 2; const uint8_t * rgb_src_buf = src_buf + stride_px * 2 * relative_area.y1 + relative_area.x1 * 2; const uint8_t * a_src_buf = src_buf + stride_px * 2 * src_h + stride_px * relative_area.y1 + @@ -393,7 +435,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t c_mult[1] = color.green * mix; c_mult[2] = color.red * mix; uint8_t * tmp_buf_2 = tmp_buf; - for(i = 0; i < size * px_size; i += px_size) { + for(i = 0; i < (uint32_t)(size * px_size); i += px_size) { tmp_buf_2[i + 0] = (c_mult[0] + (tmp_buf_2[i + 0] * mix_inv)) >> 8; tmp_buf_2[i + 1] = (c_mult[1] + (tmp_buf_2[i + 1] * mix_inv)) >> 8; tmp_buf_2[i + 2] = (c_mult[2] + (tmp_buf_2[i + 2] * mix_inv)) >> 8; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_letter.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_letter.c index 74d862e39..3dec220d9 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_letter.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_letter.c @@ -6,6 +6,8 @@ /********************* * INCLUDES *********************/ +#include "blend/lv_draw_sw_blend_private.h" +#include "../lv_draw_label_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW @@ -15,7 +17,7 @@ #include "../../misc/lv_area.h" #include "../../misc/lv_style.h" #include "../../font/lv_font.h" -#include "../../core/lv_refr.h" +#include "../../core/lv_refr_private.h" #include "../../stdlib/lv_string.h" /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_line.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_line.c index aa5bd622d..be3b19103 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_line.c @@ -6,12 +6,17 @@ /********************* * INCLUDES *********************/ -#include +#include "../../misc/lv_area_private.h" +#include "lv_draw_sw_mask_private.h" +#include "blend/lv_draw_sw_blend_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" + #if LV_USE_DRAW_SW #include "../../misc/lv_math.h" -#include "../../core/lv_refr.h" +#include "../../misc/lv_types.h" +#include "../../core/lv_refr_private.h" #include "../../stdlib/lv_string.h" /********************* @@ -56,7 +61,7 @@ void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) clip_line.y2 = (int32_t)LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width / 2; bool is_common; - is_common = _lv_area_intersect(&clip_line, &clip_line, draw_unit->clip_area); + is_common = lv_area_intersect(&clip_line, &clip_line, draw_unit->clip_area); if(!is_common) return; LV_PROFILER_BEGIN; @@ -110,7 +115,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_hor(lv_draw_unit_t * draw_unit, cons blend_area.y2 = (int32_t)dsc->p1.y + w_half0; bool is_common; - is_common = _lv_area_intersect(&blend_area, &blend_area, draw_unit->clip_area); + is_common = lv_area_intersect(&blend_area, &blend_area, draw_unit->clip_area); if(!is_common) return; bool dashed = dsc->dash_gap && dsc->dash_width; @@ -185,7 +190,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_ver(lv_draw_unit_t * draw_unit, cons blend_area.y2 = (int32_t)LV_MAX(dsc->p1.y, dsc->p2.y) - 1; bool is_common; - is_common = _lv_area_intersect(&blend_area, &blend_area, draw_unit->clip_area); + is_common = lv_area_intersect(&blend_area, &blend_area, draw_unit->clip_area); if(!is_common) return; bool dashed = dsc->dash_gap && dsc->dash_width; @@ -288,7 +293,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_unit_t * draw_unit, con /*Get the union of `coords` and `clip`*/ /*`clip` is already truncated to the `draw_buf` size *in 'lv_refr_area' function*/ - bool is_common = _lv_area_intersect(&blend_area, &blend_area, draw_unit->clip_area); + bool is_common = lv_area_intersect(&blend_area, &blend_area, draw_unit->clip_area); if(is_common == false) return; lv_draw_sw_mask_line_param_t mask_left_param; @@ -338,7 +343,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_unit_t * draw_unit, con /*Draw the background line by line*/ int32_t h; - uint32_t hor_res = (uint32_t)lv_display_get_horizontal_resolution(_lv_refr_get_disp_refreshing()); + uint32_t hor_res = (uint32_t)lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing()); size_t mask_buf_size = LV_MIN(lv_area_get_size(&blend_area), hor_res); lv_opa_t * mask_buf = lv_malloc(mask_buf_size); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.c index 7c44197a1..c4fd79220 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.c @@ -6,10 +6,11 @@ /********************* * INCLUDES *********************/ +#include "lv_draw_sw_mask_private.h" +#include "../lv_draw_mask_private.h" #include "../lv_draw.h" #if LV_DRAW_SW_COMPLEX -#include "lv_draw_sw_mask.h" #include "../../core/lv_global.h" #include "../../misc/lv_math.h" #include "../../misc/lv_log.h" @@ -60,8 +61,8 @@ static lv_draw_sw_mask_res_t /* LV_ATTRIBUTE_FAST_MEM */ line_mask_steep(lv_opa_ static void circ_init(lv_point_t * c, int32_t * tmp, int32_t radius); static bool circ_cont(lv_point_t * c); static void circ_next(lv_point_t * c, int32_t * tmp); -static void circ_calc_aa4(_lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radius); -static lv_opa_t * get_next_line(_lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t y, int32_t * len, +static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radius); +static lv_opa_t * get_next_line(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t y, int32_t * len, int32_t * x_start); static inline lv_opa_t /* LV_ATTRIBUTE_FAST_MEM */ mask_mix(lv_opa_t mask_act, lv_opa_t mask_new); @@ -92,7 +93,7 @@ lv_draw_sw_mask_res_t LV_ATTRIBUTE_FAST_MEM lv_draw_sw_mask_apply(void * masks[] int32_t len) { bool changed = false; - _lv_draw_sw_mask_common_dsc_t * dsc; + lv_draw_sw_mask_common_dsc_t * dsc; uint32_t i; for(i = 0; masks[i]; i++) { @@ -109,7 +110,7 @@ lv_draw_sw_mask_res_t LV_ATTRIBUTE_FAST_MEM lv_draw_sw_mask_apply(void * masks[] void lv_draw_sw_mask_free_param(void * p) { lv_mutex_lock(&circle_cache_mutex); - _lv_draw_sw_mask_common_dsc_t * pdsc = p; + lv_draw_sw_mask_common_dsc_t * pdsc = p; if(pdsc->type == LV_DRAW_SW_MASK_TYPE_RADIUS) { lv_draw_sw_mask_radius_param_t * radius_p = (lv_draw_sw_mask_radius_param_t *) p; if(radius_p->circle) { @@ -126,7 +127,7 @@ void lv_draw_sw_mask_free_param(void * p) lv_mutex_unlock(&circle_cache_mutex); } -void _lv_draw_sw_mask_cleanup(void) +void lv_draw_sw_mask_cleanup(void) { uint8_t i; for(i = 0; i < LV_DRAW_SW_CIRCLE_CACHE_SIZE; i++) { @@ -326,7 +327,7 @@ void lv_draw_sw_mask_radius_init(lv_draw_sw_mask_radius_param_t * param, const l } /*If not cached use the free entry with lowest life*/ - _lv_draw_sw_mask_radius_circle_dsc_t * entry = NULL; + lv_draw_sw_mask_radius_circle_dsc_t * entry = NULL; for(i = 0; i < LV_DRAW_SW_CIRCLE_CACHE_SIZE; i++) { if(_circle_cache[i].used_cnt == 0) { if(!entry) entry = &(_circle_cache[i]); @@ -336,7 +337,7 @@ void lv_draw_sw_mask_radius_init(lv_draw_sw_mask_radius_param_t * param, const l /*There is no unused entry. Allocate one temporarily*/ if(!entry) { - entry = lv_malloc_zeroed(sizeof(_lv_draw_sw_mask_radius_circle_dsc_t)); + entry = lv_malloc_zeroed(sizeof(lv_draw_sw_mask_radius_circle_dsc_t)); LV_ASSERT_MALLOC(entry); entry->life = -1; } @@ -1067,7 +1068,7 @@ static void circ_next(lv_point_t * c, int32_t * tmp) c->y++; } -static void circ_calc_aa4(_lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radius) +static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radius) { if(radius == 0) return; c->radius = radius; @@ -1216,7 +1217,7 @@ static void circ_calc_aa4(_lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radi lv_free(cir_x); } -static lv_opa_t * get_next_line(_lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t y, int32_t * len, +static lv_opa_t * get_next_line(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t y, int32_t * len, int32_t * x_start) { *len = c->opa_start_on_y[y + 1] - c->opa_start_on_y[y]; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.h index 65290375f..3f7b306e4 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask.h @@ -13,52 +13,48 @@ extern "C" { /********************* * INCLUDES *********************/ -#include #include "../../misc/lv_area.h" #include "../../misc/lv_color.h" #include "../../misc/lv_math.h" +#include "../../misc/lv_types.h" /********************* * DEFINES *********************/ #define LV_MASK_ID_INV (-1) #if LV_DRAW_SW_COMPLEX -# define _LV_MASK_MAX_NUM 16 +# define LV_MASK_MAX_NUM 16 #else -# define _LV_MASK_MAX_NUM 1 +# define LV_MASK_MAX_NUM 1 #endif /********************** * TYPEDEFS **********************/ -enum { +typedef enum { LV_DRAW_SW_MASK_RES_TRANSP, LV_DRAW_SW_MASK_RES_FULL_COVER, LV_DRAW_SW_MASK_RES_CHANGED, LV_DRAW_SW_MASK_RES_UNKNOWN -}; - -typedef uint8_t lv_draw_sw_mask_res_t; +} lv_draw_sw_mask_res_t; #if LV_DRAW_SW_COMPLEX -enum { +typedef enum { LV_DRAW_SW_MASK_TYPE_LINE, LV_DRAW_SW_MASK_TYPE_ANGLE, LV_DRAW_SW_MASK_TYPE_RADIUS, LV_DRAW_SW_MASK_TYPE_FADE, LV_DRAW_SW_MASK_TYPE_MAP, -}; +} lv_draw_sw_mask_type_t; -typedef uint8_t lv_draw_sw_mask_type_t; - -enum { +typedef enum { LV_DRAW_SW_MASK_LINE_SIDE_LEFT = 0, LV_DRAW_SW_MASK_LINE_SIDE_RIGHT, LV_DRAW_SW_MASK_LINE_SIDE_TOP, LV_DRAW_SW_MASK_LINE_SIDE_BOTTOM, -}; +} lv_draw_sw_mask_line_side_t; /** * A common callback type for every mask type. @@ -68,116 +64,6 @@ typedef lv_draw_sw_mask_res_t (*lv_draw_sw_mask_xcb_t)(lv_opa_t * mask_buf, int3 int32_t len, void * p); -typedef uint8_t lv_draw_sw_mask_line_side_t; - -typedef struct { - lv_draw_sw_mask_xcb_t cb; - lv_draw_sw_mask_type_t type; -} _lv_draw_sw_mask_common_dsc_t; - -typedef struct { - /*The first element must be the common descriptor*/ - _lv_draw_sw_mask_common_dsc_t dsc; - - struct { - /*First point*/ - lv_point_t p1; - - /*Second point*/ - lv_point_t p2; - - /*Which side to keep?*/ - lv_draw_sw_mask_line_side_t side : 2; - } cfg; - - /*A point of the line*/ - lv_point_t origo; - - /*X / (1024*Y) steepness (X is 0..1023 range). What is the change of X in 1024 Y?*/ - int32_t xy_steep; - - /*Y / (1024*X) steepness (Y is 0..1023 range). What is the change of Y in 1024 X?*/ - int32_t yx_steep; - - /*Helper which stores yx_steep for flat lines and xy_steep for steep (non flat) lines*/ - int32_t steep; - - /*Steepness in 1 px in 0..255 range. Used only by flat lines.*/ - int32_t spx; - - /*1: It's a flat line? (Near to horizontal)*/ - uint8_t flat : 1; - - /*Invert the mask. The default is: Keep the left part. - *It is used to select left/right/top/bottom*/ - uint8_t inv: 1; -} lv_draw_sw_mask_line_param_t; - -typedef struct { - /*The first element must be the common descriptor*/ - _lv_draw_sw_mask_common_dsc_t dsc; - - struct { - lv_point_t vertex_p; - int32_t start_angle; - int32_t end_angle; - } cfg; - - lv_draw_sw_mask_line_param_t start_line; - lv_draw_sw_mask_line_param_t end_line; - uint16_t delta_deg; -} lv_draw_sw_mask_angle_param_t; - -typedef struct { - uint8_t * buf; - lv_opa_t * cir_opa; /*Opacity of values on the circumference of an 1/4 circle*/ - uint16_t * x_start_on_y; /*The x coordinate of the circle for each y value*/ - uint16_t * opa_start_on_y; /*The index of `cir_opa` for each y value*/ - int32_t life; /*How many times the entry way used*/ - uint32_t used_cnt; /*Like a semaphore to count the referencing masks*/ - int32_t radius; /*The radius of the entry*/ -} _lv_draw_sw_mask_radius_circle_dsc_t; - -typedef _lv_draw_sw_mask_radius_circle_dsc_t _lv_draw_sw_mask_radius_circle_dsc_arr_t[LV_DRAW_SW_CIRCLE_CACHE_SIZE]; - -typedef struct { - /*The first element must be the common descriptor*/ - _lv_draw_sw_mask_common_dsc_t dsc; - - struct { - lv_area_t rect; - int32_t radius; - /*Invert the mask. 0: Keep the pixels inside.*/ - uint8_t outer: 1; - } cfg; - - _lv_draw_sw_mask_radius_circle_dsc_t * circle; -} lv_draw_sw_mask_radius_param_t; - -typedef struct { - /*The first element must be the common descriptor*/ - _lv_draw_sw_mask_common_dsc_t dsc; - - struct { - lv_area_t coords; - int32_t y_top; - int32_t y_bottom; - lv_opa_t opa_top; - lv_opa_t opa_bottom; - } cfg; - -} lv_draw_sw_mask_fade_param_t; - -typedef struct _lv_draw_sw_mask_map_param_t { - /*The first element must be the common descriptor*/ - _lv_draw_sw_mask_common_dsc_t dsc; - - struct { - lv_area_t coords; - const lv_opa_t * map; - } cfg; -} lv_draw_sw_mask_map_param_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -216,12 +102,6 @@ lv_draw_sw_mask_res_t /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_mask_apply(void * m */ void lv_draw_sw_mask_free_param(void * p); -/** - * Called by LVGL the rendering of a screen is ready to clean up - * the temporal (cache) data of the masks - */ -void _lv_draw_sw_mask_cleanup(void); - /** *Initialize a line mask from two points. * @param param pointer to a `lv_draw_mask_param_t` to initialize @@ -239,15 +119,15 @@ void lv_draw_sw_mask_line_points_init(lv_draw_sw_mask_line_param_t * param, int3 /** *Initialize a line mask from a point and an angle. - * @param param pointer to a `lv_draw_mask_param_t` to initialize - * @param px X coordinate of a point of the line - * @param py X coordinate of a point of the line - * @param angle right 0 deg, bottom: 90 - * @param side and element of `lv_draw_mask_line_side_t` to describe which side to keep. + * @param param pointer to a `lv_draw_mask_param_t` to initialize + * @param px X coordinate of a point of the line + * @param py X coordinate of a point of the line + * @param angle right 0 deg, bottom: 90 + * @param side an element of `lv_draw_mask_line_side_t` to describe which side to keep. * With `LV_DRAW_MASK_LINE_SIDE_LEFT/RIGHT` and horizontal line all pixels are kept * With `LV_DRAW_MASK_LINE_SIDE_TOP/BOTTOM` and vertical line all pixels are kept */ -void lv_draw_sw_mask_line_angle_init(lv_draw_sw_mask_line_param_t * param, int32_t p1x, int32_t py, int16_t angle, +void lv_draw_sw_mask_line_angle_init(lv_draw_sw_mask_line_param_t * param, int32_t px, int32_t py, int16_t angle, lv_draw_sw_mask_line_side_t side); /** diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h new file mode 100644 index 000000000..44d3f87d5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_private.h @@ -0,0 +1,153 @@ +/** + * @file lv_draw_sw_mask_private.h + * + */ + +#ifndef LV_DRAW_SW_MASK_PRIVATE_H +#define LV_DRAW_SW_MASK_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw_mask.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint8_t * buf; + lv_opa_t * cir_opa; /**< Opacity of values on the circumference of an 1/4 circle */ + uint16_t * x_start_on_y; /**< The x coordinate of the circle for each y value */ + uint16_t * opa_start_on_y; /**< The index of `cir_opa` for each y value */ + int32_t life; /**< How many times the entry way used */ + uint32_t used_cnt; /**< Like a semaphore to count the referencing masks */ + int32_t radius; /**< The radius of the entry */ +} lv_draw_sw_mask_radius_circle_dsc_t; + +struct lv_draw_sw_mask_common_dsc_t { + lv_draw_sw_mask_xcb_t cb; + lv_draw_sw_mask_type_t type; +}; + +struct lv_draw_sw_mask_line_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + /*First point*/ + lv_point_t p1; + + /*Second point*/ + lv_point_t p2; + + /*Which side to keep?*/ + lv_draw_sw_mask_line_side_t side : 2; + } cfg; + + /** A point of the line */ + lv_point_t origo; + + /** X / (1024*Y) steepness (X is 0..1023 range). What is the change of X in 1024 Y? */ + int32_t xy_steep; + + /** Y / (1024*X) steepness (Y is 0..1023 range). What is the change of Y in 1024 X? */ + int32_t yx_steep; + + /** Helper which stores yx_steep for flat lines and xy_steep for steep (non flat) lines */ + int32_t steep; + + /** Steepness in 1 px in 0..255 range. Used only by flat lines. */ + int32_t spx; + + /** 1: It's a flat line? (Near to horizontal) */ + uint8_t flat : 1; + + /** Invert the mask. The default is: Keep the left part. + *It is used to select left/right/top/bottom */ + uint8_t inv: 1; +}; + +struct lv_draw_sw_mask_angle_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_point_t vertex_p; + int32_t start_angle; + int32_t end_angle; + } cfg; + + lv_draw_sw_mask_line_param_t start_line; + lv_draw_sw_mask_line_param_t end_line; + uint16_t delta_deg; +}; + +struct lv_draw_sw_mask_radius_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_area_t rect; + int32_t radius; + /** Invert the mask. 0: Keep the pixels inside. */ + uint8_t outer: 1; + } cfg; + + lv_draw_sw_mask_radius_circle_dsc_t * circle; +}; + +struct lv_draw_sw_mask_fade_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_area_t coords; + int32_t y_top; + int32_t y_bottom; + lv_opa_t opa_top; + lv_opa_t opa_bottom; + } cfg; + +}; + +struct lv_draw_sw_mask_map_param_t { + /** The first element must be the common descriptor */ + lv_draw_sw_mask_common_dsc_t dsc; + + struct { + lv_area_t coords; + const lv_opa_t * map; + } cfg; +}; + +typedef lv_draw_sw_mask_radius_circle_dsc_t lv_draw_sw_mask_radius_circle_dsc_arr_t[LV_DRAW_SW_CIRCLE_CACHE_SIZE]; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Called by LVGL the rendering of a screen is ready to clean up + * the temporal (cache) data of the masks + */ +void lv_draw_sw_mask_cleanup(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_MASK_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_rect.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_rect.c index 919758cbf..bd28d0d0e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_rect.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_mask_rect.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "../lv_draw.h" +#include "../../misc/lv_area_private.h" +#include "../lv_draw_mask_private.h" +#include "../lv_draw_private.h" #if LV_USE_DRAW_SW #if LV_DRAW_SW_COMPLEX @@ -15,7 +17,7 @@ #include "../../stdlib/lv_mem.h" #include "../../stdlib/lv_string.h" #include "lv_draw_sw.h" -#include "lv_draw_sw_mask.h" +#include "lv_draw_sw_mask_private.h" /********************* * DEFINES @@ -46,7 +48,7 @@ void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_ds LV_UNUSED(coords); lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &dsc->area, draw_unit->clip_area)) { + if(!lv_area_intersect(&draw_area, &dsc->area, draw_unit->clip_area)) { return; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_private.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_private.h new file mode 100644 index 000000000..38ba3b4c7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_draw_sw_private.h + * + */ + +#ifndef LV_DRAW_SW_PRIVATE_H +#define LV_DRAW_SW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_sw.h" +#include "../lv_draw_private.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_draw_sw_unit_t { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; +#if LV_USE_OS + lv_thread_sync_t sync; + lv_thread_t thread; + volatile bool inited; + volatile bool exit_status; +#endif + uint32_t idx; +}; + +#if LV_DRAW_SW_SHADOW_CACHE_SIZE +typedef struct { + uint8_t cache[LV_DRAW_SW_SHADOW_CACHE_SIZE * LV_DRAW_SW_SHADOW_CACHE_SIZE]; + int32_t cache_size; + int32_t cache_r; +} lv_draw_sw_shadow_cache_t; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c index 71fadd7de..d4301100b 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_transform.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_transform.c * */ @@ -51,21 +51,39 @@ typedef struct { static void transform_point_upscaled(point_transform_dsc_t * t, int32_t xin, int32_t yin, int32_t * xout, int32_t * yout); +#if LV_DRAW_SW_SUPPORT_RGB888 static void transform_rgb888(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint8_t * dest_buf, bool aa, uint32_t px_size); +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint8_t * dest_buf, bool aa); +#endif +#if LV_DRAW_SW_SUPPORT_RGB565A8 static void transform_rgb565a8(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint16_t * cbuf, uint8_t * abuf, bool src_has_a8, bool aa); +#endif +#if LV_DRAW_SW_SUPPORT_A8 static void transform_a8(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint8_t * abuf, bool aa); +#endif + +#if LV_DRAW_SW_SUPPORT_L8 +static void transform_l8_to_al88(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, + int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, + int32_t x_end, uint8_t * abuf, bool aa); + +static void transform_l8_to_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, + int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, + int32_t x_end, uint8_t * abuf, bool aa); +#endif /********************** * STATIC VARIABLES @@ -114,10 +132,13 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are int32_t dest_stride_a8 = dest_w; int32_t dest_stride; - if(src_cf == LV_COLOR_FORMAT_RGB888) { + if(src_cf == LV_COLOR_FORMAT_L8) { + dest_stride = dest_w * ((draw_dsc->recolor_opa >= LV_OPA_MIN) ? 4 : 2); + } + else if(src_cf == LV_COLOR_FORMAT_RGB888) { dest_stride = dest_w * lv_color_format_get_size(LV_COLOR_FORMAT_ARGB8888); } - else if(src_cf == LV_COLOR_FORMAT_RGB565A8) { + else if((src_cf == LV_COLOR_FORMAT_RGB565A8) || (src_cf == LV_COLOR_FORMAT_L8)) { dest_stride = dest_w * 2; } else { @@ -139,6 +160,13 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are int32_t xs_ups = 0, ys_ups = 0, ys_ups_start = 0, ys_step_256_original = 0; int32_t xs_step_256 = 0, ys_step_256 = 0; + /*When some of the color formats are disabled, these variables could be unused, avoid warning here*/ + LV_UNUSED(aa); + LV_UNUSED(xs_ups); + LV_UNUSED(ys_ups); + LV_UNUSED(xs_step_256); + LV_UNUSED(ys_step_256); + /*If scaled only make some simplification to avoid rounding errors. *For example if there is a 100x100 image zoomed to 300% *The destination area in X will be x1=0; x2=299 @@ -204,30 +232,51 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are } switch(src_cf) { +#if LV_DRAW_SW_SUPPORT_XRGB8888 case LV_COLOR_FORMAT_XRGB8888: transform_rgb888(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, aa, 4); break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: transform_rgb888(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, aa, 3); break; +#endif +#if LV_DRAW_SW_SUPPORT_A8 case LV_COLOR_FORMAT_A8: transform_a8(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, aa); break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888 case LV_COLOR_FORMAT_ARGB8888: transform_argb8888(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, aa); break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB565 && LV_DRAW_SW_SUPPORT_RGB565A8 case LV_COLOR_FORMAT_RGB565: transform_rgb565a8(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, alpha_buf, false, aa); break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB565A8 case LV_COLOR_FORMAT_RGB565A8: transform_rgb565a8(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, (uint16_t *)dest_buf, alpha_buf, true, aa); break; +#endif +#if LV_DRAW_SW_SUPPORT_L8 + case LV_COLOR_FORMAT_L8: + if(draw_dsc->recolor_opa >= LV_OPA_MIN) + transform_l8_to_argb8888(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, + aa); + else + transform_l8_to_al88(src_buf, src_w, src_h, src_stride, xs_ups, ys_ups, xs_step_256, ys_step_256, dest_w, dest_buf, aa); + break; +#endif default: break; } @@ -241,6 +290,8 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are * STATIC FUNCTIONS **********************/ +#if LV_DRAW_SW_SUPPORT_RGB888 + static void transform_rgb888(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint8_t * dest_buf, bool aa, uint32_t px_size) @@ -337,6 +388,10 @@ static void transform_rgb888(const uint8_t * src, int32_t src_w, int32_t src_h, } } +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint8_t * dest_buf, bool aa) @@ -426,6 +481,10 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h } } +#endif + +#if LV_DRAW_SW_SUPPORT_RGB565A8 + static void transform_rgb565a8(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint16_t * cbuf, uint8_t * abuf, bool src_has_a8, bool aa) @@ -537,6 +596,10 @@ static void transform_rgb565a8(const uint8_t * src, int32_t src_w, int32_t src_h } } +#endif + +#if LV_DRAW_SW_SUPPORT_A8 + static void transform_a8(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, int32_t x_end, uint8_t * abuf, bool aa) @@ -611,6 +674,173 @@ static void transform_a8(const uint8_t * src, int32_t src_w, int32_t src_h, int3 } } +#endif + +#if LV_DRAW_SW_SUPPORT_L8 + +#if LV_DRAW_SW_SUPPORT_AL88 + +/* L8 will be transformed into an AL88 buffer, because it will not be recolored */ +static void transform_l8_to_al88(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, + int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, + int32_t x_end, uint8_t * dest_buf, bool aa) +{ + int32_t xs_ups_start = xs_ups; + int32_t ys_ups_start = ys_ups; + lv_color16a_t * dest_al88 = (lv_color16a_t *)dest_buf; + + int32_t x; + for(x = 0; x < x_end; x++) { + xs_ups = xs_ups_start + ((xs_step * x) >> 8); + ys_ups = ys_ups_start + ((ys_step * x) >> 8); + + int32_t xs_int = xs_ups >> 8; + int32_t ys_int = ys_ups >> 8; + + /*Fully out of the image*/ + if(xs_int < 0 || xs_int >= src_w || ys_int < 0 || ys_int >= src_h) { + dest_al88[x].lumi = 0x00; + dest_al88[x].alpha = 0x00; + continue; + } + + /*Get the direction the hor and ver neighbor + *`fract` will be in range of 0x00..0xFF and `next` (+/-1) indicates the direction*/ + int32_t xs_fract = xs_ups & 0xFF; + int32_t ys_fract = ys_ups & 0xFF; + + int32_t x_next; + int32_t y_next; + if(xs_fract < 0x80) { + x_next = -1; + xs_fract = (0x7F - xs_fract) * 2; + } + else { + x_next = 1; + xs_fract = (xs_fract - 0x80) * 2; + } + if(ys_fract < 0x80) { + y_next = -1; + ys_fract = (0x7F - ys_fract) * 2; + } + else { + y_next = 1; + ys_fract = (ys_fract - 0x80) * 2; + } + + const uint8_t * src_tmp = src; + src_tmp += ys_int * src_stride + xs_int; + dest_al88[x].lumi = src_tmp[0]; + dest_al88[x].alpha = 255; + if(aa && + xs_int + x_next >= 0 && + xs_int + x_next <= src_w - 1 && + ys_int + y_next >= 0 && + ys_int + y_next <= src_h - 1) { + + lv_opa_t a_ver = src_tmp[x_next]; + lv_opa_t a_hor = src_tmp[y_next * src_stride]; + + if(a_ver != dest_al88[x].lumi) a_ver = ((a_ver * ys_fract) + (dest_al88[x].lumi * (0x100 - ys_fract))) >> 8; + if(a_hor != dest_al88[x].lumi) a_hor = ((a_hor * xs_fract) + (dest_al88[x].lumi * (0x100 - xs_fract))) >> 8; + dest_al88[x].lumi = (a_ver + a_hor) >> 1; + } + else { + /*Partially out of the image*/ + if((xs_int == 0 && x_next < 0) || (xs_int == src_w - 1 && x_next > 0)) { + dest_al88[x].alpha = (src_tmp[0] * (0xFF - xs_fract)) >> 8; + } + else if((ys_int == 0 && y_next < 0) || (ys_int == src_h - 1 && y_next > 0)) { + dest_al88[x].alpha = (src_tmp[0] * (0xFF - ys_fract)) >> 8; + } + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888 + +/* L8 has to be transformed into an ARGB8888 buffer, because it will be recolored as well */ +static void transform_l8_to_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h, int32_t src_stride, + int32_t xs_ups, int32_t ys_ups, int32_t xs_step, int32_t ys_step, + int32_t x_end, uint8_t * dest_buf, bool aa) +{ + int32_t xs_ups_start = xs_ups; + int32_t ys_ups_start = ys_ups; + lv_color32_t * dest_c32 = (lv_color32_t *)dest_buf; + + int32_t x; + for(x = 0; x < x_end; x++) { + xs_ups = xs_ups_start + ((xs_step * x) >> 8); + ys_ups = ys_ups_start + ((ys_step * x) >> 8); + + int32_t xs_int = xs_ups >> 8; + int32_t ys_int = ys_ups >> 8; + + /*Fully out of the image*/ + if(xs_int < 0 || xs_int >= src_w || ys_int < 0 || ys_int >= src_h) { + *((uint32_t *)&dest_c32[x]) = 0L; + continue; + } + + /*Get the direction the hor and ver neighbor + *`fract` will be in range of 0x00..0xFF and `next` (+/-1) indicates the direction*/ + int32_t xs_fract = xs_ups & 0xFF; + int32_t ys_fract = ys_ups & 0xFF; + + int32_t x_next; + int32_t y_next; + if(xs_fract < 0x80) { + x_next = -1; + xs_fract = (0x7F - xs_fract) * 2; + } + else { + x_next = 1; + xs_fract = (xs_fract - 0x80) * 2; + } + if(ys_fract < 0x80) { + y_next = -1; + ys_fract = (0x7F - ys_fract) * 2; + } + else { + y_next = 1; + ys_fract = (ys_fract - 0x80) * 2; + } + + const uint8_t * src_tmp = src; + src_tmp += ys_int * src_stride + xs_int; + dest_c32[x].red = dest_c32[x].green = dest_c32[x].blue = src_tmp[0]; + dest_c32[x].alpha = 255; + if(aa && + xs_int + x_next >= 0 && + xs_int + x_next <= src_w - 1 && + ys_int + y_next >= 0 && + ys_int + y_next <= src_h - 1) { + + lv_opa_t a_ver = src_tmp[x_next]; + lv_opa_t a_hor = src_tmp[y_next * src_stride]; + + if(a_ver != src_tmp[0]) a_ver = ((a_ver * ys_fract) + (src_tmp[0] * (0x100 - ys_fract))) >> 8; + if(a_hor != src_tmp[0]) a_hor = ((a_hor * xs_fract) + (src_tmp[0] * (0x100 - xs_fract))) >> 8; + dest_c32[x].red = dest_c32[x].green = dest_c32[x].blue = (a_ver + a_hor) >> 1; + } + else { + /*Partially out of the image*/ + if((xs_int == 0 && x_next < 0) || (xs_int == src_w - 1 && x_next > 0)) { + dest_c32[x].alpha = (src_tmp[0] * (0xFF - xs_fract)) >> 8; + } + else if((ys_int == 0 && y_next < 0) || (ys_int == src_h - 1 && y_next > 0)) { + dest_c32[x].alpha = (src_tmp[0] * (0xFF - ys_fract)) >> 8; + } + } + } +} + +#endif + +#endif + static void transform_point_upscaled(point_transform_dsc_t * t, int32_t xin, int32_t yin, int32_t * xout, int32_t * yout) { diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_triangle.c index 311325b3d..4d42c4e3c 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_triangle.c @@ -6,16 +6,19 @@ /********************* * INCLUDES *********************/ +#include "lv_draw_sw_mask_private.h" +#include "blend/lv_draw_sw_blend_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" #if LV_USE_DRAW_SW #include "../../misc/lv_math.h" #include "../../stdlib/lv_mem.h" -#include "../../misc/lv_area.h" +#include "../../misc/lv_area_private.h" #include "../../misc/lv_color.h" #include "../../stdlib/lv_string.h" -#include "../lv_draw_triangle.h" -#include "lv_draw_sw_gradient.h" +#include "../lv_draw_triangle_private.h" +#include "lv_draw_sw_gradient_private.h" /********************* * DEFINES @@ -52,7 +55,7 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_ bool is_common; lv_area_t draw_area; - is_common = _lv_area_intersect(&draw_area, &tri_area, draw_unit->clip_area); + is_common = lv_area_intersect(&draw_area, &tri_area, draw_unit->clip_area); if(!is_common) return; lv_point_t p[3]; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_vector.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_vector.c index 8a4bca92a..4b99a47e9 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_vector.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_vector.c @@ -6,6 +6,9 @@ /********************* * INCLUDES *********************/ +#include "../lv_image_decoder_private.h" +#include "../lv_draw_vector_private.h" +#include "../lv_draw_private.h" #include "lv_draw_sw.h" #if LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG @@ -49,15 +52,15 @@ typedef struct { * MACROS **********************/ -static void _lv_area_to_tvg(_tvg_rect * rect, const lv_area_t * area) +static void lv_area_to_tvg(_tvg_rect * rect, const lv_area_t * area) { rect->x = area->x1; rect->y = area->y1; - rect->w = lv_area_get_width(area); - rect->h = lv_area_get_height(area); + rect->w = lv_area_get_width(area) - 1; + rect->h = lv_area_get_height(area) - 1; } -static void _lv_color_to_tvg(_tvg_color * color, const lv_color32_t * c, lv_opa_t opa) +static void lv_color_to_tvg(_tvg_color * color, const lv_color32_t * c, lv_opa_t opa) { color->r = c->red; color->g = c->green; @@ -65,7 +68,7 @@ static void _lv_color_to_tvg(_tvg_color * color, const lv_color32_t * c, lv_opa_ color->a = LV_OPA_MIX2(c->alpha, opa); } -static void _lv_matrix_to_tvg(Tvg_Matrix * tm, const lv_matrix_t * m) +static void lv_matrix_to_tvg(Tvg_Matrix * tm, const lv_matrix_t * m) { tm->e11 = m->m[0][0]; tm->e12 = m->m[0][1]; @@ -135,7 +138,7 @@ static void _set_paint_shape(Tvg_Paint * obj, const lv_vector_path_t * p) } } -static Tvg_Stroke_Cap _lv_stroke_cap_to_tvg(lv_vector_stroke_cap_t cap) +static Tvg_Stroke_Cap lv_stroke_cap_to_tvg(lv_vector_stroke_cap_t cap) { switch(cap) { case LV_VECTOR_STROKE_CAP_SQUARE: @@ -149,7 +152,7 @@ static Tvg_Stroke_Cap _lv_stroke_cap_to_tvg(lv_vector_stroke_cap_t cap) } } -static Tvg_Stroke_Join _lv_stroke_join_to_tvg(lv_vector_stroke_join_t join) +static Tvg_Stroke_Join lv_stroke_join_to_tvg(lv_vector_stroke_join_t join) { switch(join) { case LV_VECTOR_STROKE_JOIN_BEVEL: @@ -163,7 +166,7 @@ static Tvg_Stroke_Join _lv_stroke_join_to_tvg(lv_vector_stroke_join_t join) } } -static Tvg_Stroke_Fill _lv_spread_to_tvg(lv_vector_gradient_spread_t sp) +static Tvg_Stroke_Fill lv_spread_to_tvg(lv_vector_gradient_spread_t sp) { switch(sp) { case LV_VECTOR_GRADIENT_SPREAD_PAD: @@ -180,10 +183,10 @@ static Tvg_Stroke_Fill _lv_spread_to_tvg(lv_vector_gradient_spread_t sp) static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t * grad, const lv_matrix_t * matrix) { - const lv_grad_dsc_t * g = &grad->grad; - Tvg_Color_Stop * stops = (Tvg_Color_Stop *)lv_malloc(sizeof(Tvg_Color_Stop) * g->stops_count); - for(uint8_t i = 0; i < g->stops_count; i++) { - const lv_gradient_stop_t * s = &(g->stops[i]); + Tvg_Color_Stop * stops = (Tvg_Color_Stop *)lv_malloc(sizeof(Tvg_Color_Stop) * grad->stops_count); + LV_ASSERT_MALLOC(stops); + for(uint16_t i = 0; i < grad->stops_count; i++) { + const lv_gradient_stop_t * s = &(grad->stops[i]); stops[i].offset = s->frac / 255.0f; stops[i].r = s->color.red; @@ -192,36 +195,26 @@ static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t stops[i].a = s->opa; } - tvg_gradient_set_color_stops(gradient, stops, g->stops_count); - tvg_gradient_set_spread(gradient, _lv_spread_to_tvg(grad->spread)); + tvg_gradient_set_color_stops(gradient, stops, grad->stops_count); + tvg_gradient_set_spread(gradient, lv_spread_to_tvg(grad->spread)); Tvg_Matrix mtx; - _lv_matrix_to_tvg(&mtx, matrix); + lv_matrix_to_tvg(&mtx, matrix); tvg_gradient_set_transform(gradient, &mtx); lv_free(stops); } static void _set_paint_stroke_gradient(Tvg_Paint * obj, const lv_vector_gradient_t * g, const lv_matrix_t * m) { - float x, y, w, h; - tvg_paint_get_bounds(obj, &x, &y, &w, &h, false); - Tvg_Gradient * grad = NULL; if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { grad = tvg_radial_gradient_new(); - tvg_radial_gradient_set(grad, g->cx + x, g->cy + y, g->cr); + tvg_radial_gradient_set(grad, g->cx, g->cy, g->cr); _setup_gradient(grad, g, m); tvg_shape_set_stroke_radial_gradient(obj, grad); } else { grad = tvg_linear_gradient_new(); - - if(g->grad.dir == LV_GRAD_DIR_VER) { - tvg_linear_gradient_set(grad, x, y, x, y + h); - } - else { - tvg_linear_gradient_set(grad, x, y, x + w, y); - } - + tvg_linear_gradient_set(grad, g->x1, g->y1, g->x2, g->y2); _setup_gradient(grad, g, m); tvg_shape_set_stroke_linear_gradient(obj, grad); } @@ -231,7 +224,7 @@ static void _set_paint_stroke(Tvg_Paint * obj, const lv_vector_stroke_dsc_t * ds { if(dsc->style == LV_VECTOR_DRAW_STYLE_SOLID) { _tvg_color c; - _lv_color_to_tvg(&c, &dsc->color, dsc->opa); + lv_color_to_tvg(&c, &dsc->color, dsc->opa); tvg_shape_set_stroke_color(obj, c.r, c.g, c.b, c.a); } else { /*gradient*/ @@ -240,8 +233,8 @@ static void _set_paint_stroke(Tvg_Paint * obj, const lv_vector_stroke_dsc_t * ds tvg_shape_set_stroke_width(obj, dsc->width); tvg_shape_set_stroke_miterlimit(obj, dsc->miter_limit); - tvg_shape_set_stroke_cap(obj, _lv_stroke_cap_to_tvg(dsc->cap)); - tvg_shape_set_stroke_join(obj, _lv_stroke_join_to_tvg(dsc->join)); + tvg_shape_set_stroke_cap(obj, lv_stroke_cap_to_tvg(dsc->cap)); + tvg_shape_set_stroke_join(obj, lv_stroke_join_to_tvg(dsc->join)); if(!lv_array_is_empty(&dsc->dash_pattern)) { float * dash_array = lv_array_front(&dsc->dash_pattern); @@ -249,7 +242,7 @@ static void _set_paint_stroke(Tvg_Paint * obj, const lv_vector_stroke_dsc_t * ds } } -static Tvg_Fill_Rule _lv_fill_rule_to_tvg(lv_vector_fill_t rule) +static Tvg_Fill_Rule lv_fill_rule_to_tvg(lv_vector_fill_t rule) { switch(rule) { case LV_VECTOR_FILL_NONZERO: @@ -263,26 +256,16 @@ static Tvg_Fill_Rule _lv_fill_rule_to_tvg(lv_vector_fill_t rule) static void _set_paint_fill_gradient(Tvg_Paint * obj, const lv_vector_gradient_t * g, const lv_matrix_t * m) { - float x, y, w, h; - tvg_paint_get_bounds(obj, &x, &y, &w, &h, false); - Tvg_Gradient * grad = NULL; if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { grad = tvg_radial_gradient_new(); - tvg_radial_gradient_set(grad, g->cx + x, g->cy + y, g->cr); + tvg_radial_gradient_set(grad, g->cx, g->cy, g->cr); _setup_gradient(grad, g, m); tvg_shape_set_radial_gradient(obj, grad); } else { grad = tvg_linear_gradient_new(); - - if(g->grad.dir == LV_GRAD_DIR_VER) { - tvg_linear_gradient_set(grad, x, y, x, y + h); - } - else { - tvg_linear_gradient_set(grad, x, y, x + w, y); - } - + tvg_linear_gradient_set(grad, g->x1, g->y1, g->x2, g->y2); _setup_gradient(grad, g, m); tvg_shape_set_linear_gradient(obj, grad); } @@ -293,6 +276,7 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const { lv_image_decoder_dsc_t decoder_dsc; lv_image_decoder_args_t args = { 0 }; + args.premultiply = 1; lv_result_t res = lv_image_decoder_open(&decoder_dsc, p->src, &args); if(res != LV_RESULT_OK) { LV_LOG_ERROR("Failed to open image"); @@ -322,7 +306,7 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const tvg_paint_set_opacity(img, p->opa); Tvg_Matrix mtx; - _lv_matrix_to_tvg(&mtx, m); + lv_matrix_to_tvg(&mtx, m); tvg_paint_set_transform(img, &mtx); tvg_canvas_push(canvas, img); lv_image_decoder_close(&decoder_dsc); @@ -331,11 +315,11 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const static void _set_paint_fill(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_vector_fill_dsc_t * dsc, const lv_matrix_t * matrix) { - tvg_shape_set_fill_rule(obj, _lv_fill_rule_to_tvg(dsc->fill_rule)); + tvg_shape_set_fill_rule(obj, lv_fill_rule_to_tvg(dsc->fill_rule)); if(dsc->style == LV_VECTOR_DRAW_STYLE_SOLID) { _tvg_color c; - _lv_color_to_tvg(&c, &dsc->color, dsc->opa); + lv_color_to_tvg(&c, &dsc->color, dsc->opa); tvg_shape_set_fill_color(obj, c.r, c.g, c.b, c.a); } else if(dsc->style == LV_VECTOR_DRAW_STYLE_PATTERN) { @@ -353,7 +337,7 @@ static void _set_paint_fill(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_vecto } } -static Tvg_Blend_Method _lv_blend_to_tvg(lv_vector_blend_t blend) +static Tvg_Blend_Method lv_blend_to_tvg(lv_vector_blend_t blend) { switch(blend) { case LV_VECTOR_BLEND_SRC_OVER: @@ -378,7 +362,7 @@ static Tvg_Blend_Method _lv_blend_to_tvg(lv_vector_blend_t blend) static void _set_paint_blend_mode(Tvg_Paint * obj, lv_vector_blend_t blend) { - tvg_paint_set_blend_method(obj, _lv_blend_to_tvg(blend)); + tvg_paint_set_blend_method(obj, lv_blend_to_tvg(blend)); } static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc) @@ -389,10 +373,10 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve if(!path) { /*clear*/ _tvg_rect rc; - _lv_area_to_tvg(&rc, &dsc->scissor_area); + lv_area_to_tvg(&rc, &dsc->scissor_area); _tvg_color c; - _lv_color_to_tvg(&c, &dsc->fill_dsc.color, dsc->fill_dsc.opa); + lv_color_to_tvg(&c, &dsc->fill_dsc.color, dsc->fill_dsc.opa); Tvg_Matrix mtx = { 1.0f, 0.0f, 0.0f, @@ -405,7 +389,7 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve } else { Tvg_Matrix mtx; - _lv_matrix_to_tvg(&mtx, &dsc->matrix); + lv_matrix_to_tvg(&mtx, &dsc->matrix); _set_paint_matrix(obj, &mtx); _set_paint_shape(obj, path); @@ -442,14 +426,18 @@ void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc } void * buf = draw_buf->data; - int32_t width = lv_area_get_width(&layer->buf_area); - int32_t height = lv_area_get_height(&layer->buf_area); + int32_t width = lv_area_get_width(&layer->buf_area) - 1; + int32_t height = lv_area_get_height(&layer->buf_area) - 1; uint32_t stride = draw_buf->header.stride; Tvg_Canvas * canvas = tvg_swcanvas_create(); tvg_swcanvas_set_target(canvas, buf, stride / 4, width, height, TVG_COLORSPACE_ARGB8888); + _tvg_rect rc; + lv_area_to_tvg(&rc, draw_unit->clip_area); + tvg_canvas_set_viewport(canvas, (int32_t)rc.x, (int32_t)rc.y, (int32_t)rc.w, (int32_t)rc.h); + lv_ll_t * task_list = dsc->task_list; - _lv_vector_for_each_destroy_tasks(task_list, _task_draw_cb, canvas); + lv_vector_for_each_destroy_tasks(task_list, _task_draw_cb, canvas); if(tvg_canvas_draw(canvas) == TVG_RESULT_SUCCESS) { tvg_canvas_sync(canvas); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_buf_vg_lite.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_buf_vg_lite.c index 65b085ca0..de0b4b90b 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_buf_vg_lite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_buf_vg_lite.c @@ -11,6 +11,7 @@ #if LV_USE_DRAW_VG_LITE +#include "../lv_draw_buf_private.h" #include "lv_vg_lite_utils.h" /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c index e461550ff..145c00757 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.c @@ -11,13 +11,14 @@ #if LV_USE_DRAW_VG_LITE -#include "../lv_draw.h" +#include "../lv_draw_private.h" #include "lv_draw_vg_lite_type.h" #include "lv_vg_lite_path.h" #include "lv_vg_lite_utils.h" #include "lv_vg_lite_decoder.h" #include "lv_vg_lite_grad.h" #include "lv_vg_lite_pending.h" +#include "lv_vg_lite_stroke.h" /********************* * DEFINES @@ -72,7 +73,10 @@ void lv_draw_vg_lite_init(void) unit->base_unit.delete_cb = draw_delete; lv_vg_lite_image_dsc_init(unit); - lv_vg_lite_grad_init(unit); +#if LV_USE_VECTOR_GRAPHIC + lv_vg_lite_grad_init(unit, LV_VG_LITE_GRAD_CACHE_CNT); + lv_vg_lite_stroke_init(unit, LV_VG_LITE_STROKE_CACHE_CNT); +#endif lv_vg_lite_path_init(unit); lv_vg_lite_decoder_init(); } @@ -112,6 +116,19 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u) vg_lite_identity(&u->global_matrix); vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix); +#if LV_DRAW_TRANSFORM_USE_MATRIX + vg_lite_matrix_t layer_matrix; + lv_vg_lite_matrix(&layer_matrix, &t->matrix); + lv_vg_lite_matrix_multiply(&u->global_matrix, &layer_matrix); + + /* Crop out extra pixels drawn due to scaling accuracy issues */ + if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { + lv_area_t scissor_area = layer->phy_clip_area; + lv_area_move(&scissor_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_vg_lite_set_scissor_area(&scissor_area); + } +#endif + switch(t->type) { case LV_DRAW_TASK_TYPE_LABEL: lv_draw_vg_lite_label(draw_unit, t->draw_dsc, &t->area); @@ -170,17 +187,17 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) /* Return 0 is no selection, some tasks can be supported by other units. */ if(!t || t->preferred_draw_unit_id != VG_LITE_DRAW_UNIT_ID) { lv_vg_lite_finish(u); - return -1; + return LV_DRAW_UNIT_IDLE; + } + + /* Return if target buffer format is not supported. */ + if(!lv_vg_lite_is_dest_cf_supported(layer->color_format)) { + return LV_DRAW_UNIT_IDLE; } void * buf = lv_draw_layer_alloc_buf(layer); if(!buf) { - return -1; - } - - /* Return if target buffer format is not supported. */ - if(!lv_vg_lite_is_dest_cf_supported(layer->draw_buf->header.cf)) { - return -1; + return LV_DRAW_UNIT_IDLE; } t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; @@ -203,6 +220,12 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) { LV_UNUSED(draw_unit); + /* Return if target buffer format is not supported. */ + const lv_draw_dsc_base_t * base_dsc = task->draw_dsc; + if(!lv_vg_lite_is_dest_cf_supported(base_dsc->layer->color_format)) { + return -1; + } + switch(task->type) { case LV_DRAW_TASK_TYPE_LABEL: case LV_DRAW_TASK_TYPE_FILL: @@ -244,7 +267,10 @@ static int32_t draw_delete(lv_draw_unit_t * draw_unit) lv_draw_vg_lite_unit_t * unit = (lv_draw_vg_lite_unit_t *)draw_unit; lv_vg_lite_image_dsc_deinit(unit); +#if LV_USE_VECTOR_GRAPHIC lv_vg_lite_grad_deinit(unit); + lv_vg_lite_stroke_deinit(unit); +#endif lv_vg_lite_path_deinit(unit); lv_vg_lite_decoder_deinit(); return 1; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.h index 8b5cb3b46..63ff7f504 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite.h @@ -1,10 +1,10 @@ /** - * @file lv_vg_lite_draw.h + * @file lv_draw_vg_lite.h * */ -#ifndef LV_VG_LITE_DRAW_H -#define LV_VG_LITE_DRAW_H +#ifndef LV_DRAW_VG_LITE_H +#define LV_DRAW_VG_LITE_H #ifdef __cplusplus extern "C" { @@ -20,6 +20,12 @@ extern "C" { #include "../lv_draw.h" #include "../../draw/lv_draw_vector.h" +#include "../../draw/lv_draw_arc.h" +#include "../../draw/lv_draw_rect.h" +#include "../../draw/lv_draw_image.h" +#include "../../draw/lv_draw_label.h" +#include "../../draw/lv_draw_line.h" +#include "../../draw/lv_draw_triangle.h" /********************* * DEFINES @@ -81,4 +87,4 @@ void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_tas } /*extern "C"*/ #endif -#endif /*LV_VG_LITE_DRAW_H*/ +#endif /*LV_DRAW_VG_LITE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c index 74e63bbaf..68893c0e4 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_arc.c @@ -7,6 +7,9 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "../lv_image_decoder_private.h" +#include "../lv_draw_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -52,17 +55,10 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) { - if(dsc->opa <= LV_OPA_MIN) - return; - if(dsc->width <= 0) - return; - if(dsc->start_angle == dsc->end_angle) - return; - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) { + if(!lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) { /*Fully clipped, nothing to do*/ return; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c index f60b72f33..445ab1a5f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_border.c @@ -7,6 +7,8 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "../lv_draw_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -42,17 +44,10 @@ void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) { - if(dsc->opa <= LV_OPA_MIN) - return; - if(dsc->width == 0) - return; - if(dsc->side == LV_BORDER_SIDE_NONE) - return; - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) { + if(!lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) { /*Fully clipped, nothing to do*/ return; } @@ -78,13 +73,13 @@ void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, w, h, - r_out, r_out); + r_out); /* inner rect */ lv_vg_lite_path_append_rect(path, coords->x1 + border_w, coords->y1 + border_w, w - border_w * 2, h - border_w * 2, - r_in, r_in); + r_in); lv_vg_lite_path_end(path); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_box_shadow.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_box_shadow.c index e5cc00897..cad9500f8 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_box_shadow.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_box_shadow.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -54,13 +55,10 @@ void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_sh shadow_area.y1 = core_area.y1 - dsc->width / 2 - 1; shadow_area.y2 = core_area.y2 + dsc->width / 2 + 1; - lv_opa_t opa = dsc->opa; - if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; - /*Get clipped draw area which is the real draw area. *It is always the same or inside `shadow_area`*/ lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &shadow_area, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, &shadow_area, draw_unit->clip_area)) return; LV_PROFILER_BEGIN; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c index ea52815eb..cae20a8fc 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_fill.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -46,14 +47,10 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) { - if(dsc->opa <= LV_OPA_MIN) { - return; - } - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) { + if(!lv_area_intersect(&clip_area, coords, draw_unit->clip_area)) { /*Fully clipped, nothing to do*/ return; } @@ -75,7 +72,7 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH); lv_vg_lite_path_set_bonding_box_area(path, &clip_area); - lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, w, h, r, r); + lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, w, h, r); lv_vg_lite_path_end(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); @@ -85,17 +82,19 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * LV_VG_LITE_ASSERT_MATRIX(&matrix); if(dsc->grad.dir != LV_GRAD_DIR_NONE) { - vg_lite_matrix_t grad_matrix; - lv_vg_lite_grad_area_to_matrix(&grad_matrix, coords, dsc->grad.dir); - lv_vg_lite_draw_linear_grad( +#if LV_USE_VECTOR_GRAPHIC + lv_vg_lite_draw_grad_helper( u, &u->target_buffer, vg_lite_path, + coords, &dsc->grad, - &grad_matrix, &matrix, VG_LITE_FILL_EVEN_ODD, VG_LITE_BLEND_SRC_OVER); +#else + LV_LOG_WARN("Gradient fill is not supported without VECTOR_GRAPHIC"); +#endif } else { /* normal fill */ vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c index 10b217bcf..84ce9d268 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_img.c @@ -7,6 +7,10 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "../lv_image_decoder_private.h" +#include "../lv_draw_image_private.h" +#include "../lv_draw_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -44,17 +48,13 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords, bool no_cache) { - if(dsc->opa <= LV_OPA_MIN) { - return; - } - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; /* The coordinates passed in by coords are not transformed, * so the transformed area needs to be calculated once. */ lv_area_t image_tf_area; - _lv_image_buf_get_transformed_area( + lv_image_buf_get_transformed_area( &image_tf_area, lv_area_get_width(coords), lv_area_get_height(coords), @@ -65,7 +65,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * lv_area_move(&image_tf_area, coords->x1, coords->y1); lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, &image_tf_area, draw_unit->clip_area)) { + if(!lv_area_intersect(&clip_area, &image_tf_area, draw_unit->clip_area)) { /*Fully clipped, nothing to do*/ return; } @@ -80,20 +80,17 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * } vg_lite_color_t color = 0; - if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(decoder_dsc.decoded->header.cf) || dsc->recolor_opa > LV_OPA_MIN) { + if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(decoder_dsc.decoded->header.cf) || dsc->recolor_opa > LV_OPA_TRANSP) { /* alpha image and image recolor */ src_buf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; color = lv_vg_lite_color(dsc->recolor, LV_OPA_MIX2(dsc->opa, dsc->recolor_opa), true); } - else if(dsc->opa < LV_OPA_MAX) { + else if(dsc->opa < LV_OPA_COVER) { /* normal image opa */ src_buf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; lv_memset(&color, dsc->opa, sizeof(color)); } - bool has_trasform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - vg_lite_filter_t filter = has_trasform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; - vg_lite_matrix_t matrix; vg_lite_identity(&matrix); lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); @@ -102,8 +99,11 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf); LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); + bool no_transform = lv_matrix_is_identity_or_translation((const lv_matrix_t *)&matrix); + vg_lite_filter_t filter = no_transform ? VG_LITE_FILTER_POINT : VG_LITE_FILTER_BI_LINEAR; + /* If clipping is not required, blit directly */ - if(_lv_area_is_in(&image_tf_area, draw_unit->clip_area, false)) { + if(lv_area_is_in(&image_tf_area, draw_unit->clip_area, false) && dsc->clip_radius <= 0) { /* The image area is the coordinates relative to the image itself */ lv_area_t src_area = *coords; lv_area_move(&src_area, -coords->x1, -coords->y1); @@ -125,11 +125,31 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * } else { lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); - lv_vg_lite_path_append_rect( - path, - clip_area.x1, clip_area.y1, - lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), - 0, 0); + + if(dsc->clip_radius) { + int32_t width = lv_area_get_width(coords); + int32_t height = lv_area_get_height(coords); + float r_short = LV_MIN(width, height) / 2.0f; + float radius = LV_MIN(dsc->clip_radius, r_short); + + /** + * When clip_radius is enabled, the clipping edges + * are aligned with the image edges + */ + lv_vg_lite_path_append_rect( + path, + coords->x1, coords->y1, + width, height, + radius); + } + else { + lv_vg_lite_path_append_rect( + path, + clip_area.x1, clip_area.y1, + lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), + 0); + } + lv_vg_lite_path_set_bonding_box_area(path, &clip_area); lv_vg_lite_path_end(path); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c index 6c422aecb..0ad4b15b0 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -7,6 +7,9 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "../../libs/freetype/lv_freetype_private.h" +#include "../lv_draw_label_private.h" #include "lv_draw_vg_lite.h" #include "../../lvgl.h" @@ -63,8 +66,6 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d void lv_draw_vg_lite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) { - if(dsc->opa <= LV_OPA_MIN) return; - LV_PROFILER_BEGIN; #if LV_USE_FREETYPE @@ -141,7 +142,7 @@ static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * gly static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc) { lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, u->base_unit.clip_area, dsc->letter_coords)) { + if(!lv_area_intersect(&clip_area, u->base_unit.clip_area, dsc->letter_coords)) { return; } @@ -165,7 +166,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); /* If clipping is not required, blit directly */ - if(_lv_area_is_in(&image_area, u->base_unit.clip_area, false)) { + if(lv_area_is_in(&image_area, u->base_unit.clip_area, false)) { /* The image area is the coordinates relative to the image itself */ lv_area_t src_area = image_area; lv_area_move(&src_area, -image_area.x1, -image_area.y1); @@ -190,7 +191,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d path, clip_area.x1, clip_area.y1, lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), - 0, 0); + 0); lv_vg_lite_path_set_bonding_box_area(path, &clip_area); lv_vg_lite_path_end(path); @@ -200,6 +201,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d vg_lite_matrix_t path_matrix; vg_lite_identity(&path_matrix); lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix); + LV_VG_LITE_ASSERT_MATRIX(&path_matrix); LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( @@ -211,7 +213,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d &matrix, VG_LITE_BLEND_SRC_OVER, VG_LITE_PATTERN_COLOR, - color, + 0, color, VG_LITE_FILTER_LINEAR)); LV_PROFILER_END_TAG("vg_lite_draw_pattern"); @@ -233,7 +235,7 @@ static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_ { /* get clip area */ lv_area_t path_clip_area; - if(!_lv_area_intersect(&path_clip_area, u->base_unit.clip_area, dsc->letter_coords)) { + if(!lv_area_intersect(&path_clip_area, u->base_unit.clip_area, dsc->letter_coords)) { return; } @@ -245,21 +247,26 @@ static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_ lv_vg_lite_path_t * outline = (lv_vg_lite_path_t *)dsc->glyph_data; lv_point_t pos = {dsc->letter_coords->x1, dsc->letter_coords->y1}; + /* scale size */ + float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font)); /* calc convert matrix */ - float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font)); vg_lite_matrix_t matrix; vg_lite_identity(&matrix); + /* matrix for drawing, different from matrix for calculating the bonding box */ + vg_lite_matrix_t draw_matrix; + vg_lite_identity(&draw_matrix); + + lv_vg_lite_matrix_multiply(&draw_matrix, &u->global_matrix); + /* convert to vg-lite coordinate */ + vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &draw_matrix); vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &matrix); - /* scale size */ + vg_lite_scale(scale, scale, &draw_matrix); vg_lite_scale(scale, scale, &matrix); - /* Cartesian coordinates to LCD coordinates */ - lv_vg_lite_matrix_flip_y(&matrix); - /* calc inverse matrix */ vg_lite_matrix_t result; if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { @@ -277,20 +284,16 @@ static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_ /* Since the font uses Cartesian coordinates, the y coordinates need to be reversed */ lv_vg_lite_path_set_bonding_box(outline, p1_res.x, p2_res.y, p2_res.x, p1_res.y); - /* Move to the position relative to the first address of the buffer */ - lv_layer_t * layer = u->base_unit.target_layer; - vg_lite_translate(-layer->buf_area.x1 / scale, layer->buf_area.y1 / scale, &matrix); - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(outline); LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(&matrix); + LV_VG_LITE_ASSERT_MATRIX(&draw_matrix); LV_PROFILER_BEGIN_TAG("vg_lite_draw"); LV_VG_LITE_CHECK_ERROR(vg_lite_draw( &u->target_buffer, vg_lite_path, VG_LITE_FILL_NON_ZERO, - &matrix, VG_LITE_BLEND_SRC_OVER, lv_vg_lite_color(dsc->color, dsc->opa, true))); + &draw_matrix, VG_LITE_BLEND_SRC_OVER, lv_vg_lite_color(dsc->color, dsc->opa, true))); LV_PROFILER_END_TAG("vg_lite_draw"); /* Flush in time to avoid accumulation of drawing commands */ @@ -307,23 +310,28 @@ static void vg_lite_outline_push(const lv_freetype_outline_event_param_t * param lv_freetype_outline_type_t type = param->type; switch(type) { + + /** + * Reverse the Y-axis coordinate direction to achieve + * the conversion from Cartesian coordinate system to LCD coordinate system + */ case LV_FREETYPE_OUTLINE_END: lv_vg_lite_path_end(outline); break; case LV_FREETYPE_OUTLINE_MOVE_TO: - lv_vg_lite_path_move_to(outline, param->to.x, param->to.y); + lv_vg_lite_path_move_to(outline, param->to.x, -param->to.y); break; case LV_FREETYPE_OUTLINE_LINE_TO: - lv_vg_lite_path_line_to(outline, param->to.x, param->to.y); + lv_vg_lite_path_line_to(outline, param->to.x, -param->to.y); break; case LV_FREETYPE_OUTLINE_CUBIC_TO: - lv_vg_lite_path_cubic_to(outline, param->control1.x, param->control1.y, - param->control2.x, param->control2.y, - param->to.x, param->to.y); + lv_vg_lite_path_cubic_to(outline, param->control1.x, -param->control1.y, + param->control2.x, -param->control2.y, + param->to.x, -param->to.y); break; case LV_FREETYPE_OUTLINE_CONIC_TO: - lv_vg_lite_path_quad_to(outline, param->control1.x, param->control1.y, - param->to.x, param->to.y); + lv_vg_lite_path_quad_to(outline, param->control1.x, -param->control1.y, + param->to.x, -param->to.y); break; default: LV_LOG_ERROR("unknown point type: %d", type); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_layer.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_layer.c index f79f4188f..8f2a17e80 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_layer.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_layer.c @@ -42,7 +42,7 @@ void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t const lv_area_t * coords) { lv_layer_t * layer = (lv_layer_t *)draw_dsc->src; - struct _lv_draw_vg_lite_unit_t * u = (struct _lv_draw_vg_lite_unit_t *)draw_unit; + struct lv_draw_vg_lite_unit_t * u = (struct lv_draw_vg_lite_unit_t *)draw_unit; /*It can happen that nothing was draw on a layer and therefore its buffer is not allocated. *In this case just return. */ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c index f986950cc..501e8b653 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_line.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -44,11 +45,6 @@ void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) { - if(dsc->opa <= LV_OPA_MIN) - return; - if(dsc->width == 0) - return; - float p1_x = dsc->p1.x; float p1_y = dsc->p1.y; float p2_x = dsc->p2.x; @@ -65,7 +61,7 @@ void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * rel_clip_area.y1 = (int32_t)(LV_MIN(p1_y, p2_y) - half_w); rel_clip_area.y2 = (int32_t)(LV_MAX(p1_y, p2_y) + half_w); - if(!_lv_area_intersect(&rel_clip_area, &rel_clip_area, draw_unit->clip_area)) { + if(!lv_area_intersect(&rel_clip_area, &rel_clip_area, draw_unit->clip_area)) { return; /*Fully clipped, nothing to do*/ } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c index a7cbda0cb..e6c0decb2 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c @@ -7,12 +7,16 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" +#include "../sw/lv_draw_sw_mask_private.h" +#include "../lv_draw_mask_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE #include "lv_vg_lite_utils.h" #include "lv_draw_vg_lite_type.h" +#include "lv_vg_lite_path.h" /********************* * DEFINES @@ -44,12 +48,17 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re LV_UNUSED(coords); lv_area_t draw_area; - if(!_lv_area_intersect(&draw_area, &dsc->area, draw_unit->clip_area)) { + if(!lv_area_intersect(&draw_area, &dsc->area, draw_unit->clip_area)) { return; } LV_PROFILER_BEGIN; +#if LV_USE_VG_LITE_THORVG + /** + * ThorVG does not yet support simulating the VG_LITE_BLEND_DST_IN blend mode, + * and uses software rendering to achieve this + */ lv_draw_sw_mask_radius_param_t param; lv_draw_sw_mask_radius_init(¶m, &dsc->area, dsc->radius, false); @@ -87,6 +96,48 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re lv_free(mask_buf); lv_draw_sw_mask_free_param(¶m); +#else + /* Using hardware rendering masks */ + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + + int32_t w = lv_area_get_width(&dsc->area); + int32_t h = lv_area_get_height(&dsc->area); + float r = dsc->radius; + if(dsc->radius) { + float r_short = LV_MIN(w, h) / 2.0f; + r = LV_MIN(r, r_short); + } + + lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); + lv_vg_lite_path_set_quality(path, VG_LITE_HIGH); + lv_vg_lite_path_set_bonding_box_area(path, &draw_area); + + /* Use rounded rectangles and normal rectangles of the same size to nest the cropped area */ + lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, r); + lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, 0); + lv_vg_lite_path_end(path); + + vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); + + vg_lite_matrix_t * matrix = &u->global_matrix; + + LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); + LV_VG_LITE_ASSERT_PATH(vg_lite_path); + LV_VG_LITE_ASSERT_MATRIX(matrix); + + /* Use VG_LITE_BLEND_DST_IN (Sa * D) blending mode to make the corners transparent */ + LV_PROFILER_BEGIN_TAG("vg_lite_draw"); + LV_VG_LITE_CHECK_ERROR(vg_lite_draw( + &u->target_buffer, + vg_lite_path, + VG_LITE_FILL_EVEN_ODD, + matrix, + VG_LITE_BLEND_DST_IN, + 0)); + LV_PROFILER_END_TAG("vg_lite_draw"); + + lv_vg_lite_path_drop(u, path); +#endif /*LV_USE_VG_LITE_THORVG*/ LV_PROFILER_END; } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c index 868f23a54..e0258984f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_triangle.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ +#include "../../misc/lv_area_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE @@ -42,8 +43,6 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc) { - if(dsc->bg_opa <= LV_OPA_MIN) return; - lv_area_t tri_area; tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); tri_area.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); @@ -52,7 +51,7 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle bool is_common; lv_area_t clip_area; - is_common = _lv_area_intersect(&clip_area, &tri_area, draw_unit->clip_area); + is_common = lv_area_intersect(&clip_area, &tri_area, draw_unit->clip_area); if(!is_common) return; LV_PROFILER_BEGIN; @@ -78,17 +77,19 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle LV_VG_LITE_ASSERT_MATRIX(&matrix); if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { - vg_lite_matrix_t grad_matrix; - lv_vg_lite_grad_area_to_matrix(&grad_matrix, &tri_area, dsc->bg_grad.dir); - lv_vg_lite_draw_linear_grad( +#if LV_USE_VECTOR_GRAPHIC + lv_vg_lite_draw_grad_helper( u, &u->target_buffer, vg_lite_path, + &tri_area, &dsc->bg_grad, - &grad_matrix, &matrix, VG_LITE_FILL_EVEN_ODD, VG_LITE_BLEND_SRC_OVER); +#else + LV_LOG_WARN("Gradient fill is not supported without VECTOR_GRAPHIC"); +#endif } else { /* normal fill */ vg_lite_color_t color = lv_vg_lite_color(dsc->bg_color, dsc->bg_opa, true); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_type.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_type.h index 3609f9280..d325be51b 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_type.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_type.h @@ -18,7 +18,7 @@ extern "C" { #if LV_USE_DRAW_VG_LITE -#include "../lv_draw.h" +#include "../lv_draw_private.h" #include "../../misc/lv_array.h" #if LV_USE_VG_LITE_THORVG @@ -35,18 +35,23 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_vg_lite_pending_t; +struct lv_vg_lite_pending_t; -struct _lv_draw_vg_lite_unit_t { +struct lv_draw_vg_lite_unit_t { lv_draw_unit_t base_unit; lv_draw_task_t * task_act; - struct _lv_vg_lite_pending_t * image_dsc_pending; + + struct lv_vg_lite_pending_t * image_dsc_pending; + lv_cache_t * grad_cache; - struct _lv_vg_lite_pending_t * grad_pending; + struct lv_vg_lite_pending_t * grad_pending; + + lv_cache_t * stroke_cache; + uint16_t flush_count; vg_lite_buffer_t target_buffer; vg_lite_matrix_t global_matrix; - struct _lv_vg_lite_path_t * global_path; + struct lv_vg_lite_path_t * global_path; bool path_in_use; }; @@ -64,4 +69,4 @@ struct _lv_draw_vg_lite_unit_t { } /*extern "C"*/ #endif -#endif /*LV_VG_LITE_DRAW_H*/ +#endif /*LV_DRAW_VG_LITE_TYPE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c index 0485c0b6e..a70caf804 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_draw_vg_lite_vector.c @@ -7,6 +7,8 @@ * INCLUDES *********************/ +#include "../lv_image_decoder_private.h" +#include "../lv_draw_vector_private.h" #include "lv_draw_vg_lite.h" #if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC @@ -16,6 +18,8 @@ #include "lv_vg_lite_pending.h" #include "lv_vg_lite_utils.h" #include "lv_vg_lite_grad.h" +#include "lv_vg_lite_stroke.h" +#include /********************* * DEFINES @@ -25,20 +29,18 @@ * TYPEDEFS **********************/ +typedef void * path_drop_data_t; +typedef void (*path_drop_func_t)(struct lv_draw_vg_lite_unit_t *, path_drop_data_t); + /********************** * STATIC PROTOTYPES **********************/ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc); -static void lv_matrix_to_vg(vg_lite_matrix_t * desy, const lv_matrix_t * src); static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src); -static void lv_path_opa_to_vg(lv_vg_lite_path_t * dest, const lv_vector_draw_dsc_t * dsc); -static void lv_stroke_to_vg(lv_vg_lite_path_t * dest, const lv_vector_stroke_dsc_t * dsc); +static vg_lite_path_type_t lv_path_opa_to_path_type(const lv_vector_draw_dsc_t * dsc); static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend); static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule); -static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread); -static vg_lite_cap_style_t lv_stroke_cap_to_vg(lv_vector_stroke_cap_t cap); -static vg_lite_join_style_t lv_stroke_join_to_vg(lv_vector_stroke_join_t join); /********************** * STATIC VARIABLES @@ -62,7 +64,7 @@ void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_tas return; LV_PROFILER_BEGIN; - _lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, draw_unit); + lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, draw_unit); LV_PROFILER_END; } @@ -73,10 +75,10 @@ void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_tas static vg_lite_color_t lv_color32_to_vg(lv_color32_t color, lv_opa_t opa) { uint8_t a = LV_OPA_MIX2(color.alpha, opa); - if(a < LV_OPA_MAX) { - color.red = LV_UDIV255(color.red * opa); - color.green = LV_UDIV255(color.green * opa); - color.blue = LV_UDIV255(color.blue * opa); + if(a < LV_OPA_COVER) { + color.red = LV_UDIV255(color.red * a); + color.green = LV_UDIV255(color.green * a); + color.blue = LV_UDIV255(color.blue * a); } return (uint32_t)a << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red; } @@ -105,28 +107,72 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec /* transform matrix */ vg_lite_matrix_t matrix; - lv_matrix_to_vg(&matrix, &dsc->matrix); + lv_vg_lite_matrix(&matrix, &dsc->matrix); LV_VG_LITE_ASSERT_MATRIX(&matrix); /* convert path */ lv_vg_lite_path_t * lv_vg_path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_path_to_vg(lv_vg_path, path); - vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(lv_vg_path); - LV_VG_LITE_ASSERT_PATH(vg_path); + + /* get path bounds */ + float min_x, min_y, max_x, max_y; + lv_vg_lite_path_get_bonding_box(lv_vg_path, &min_x, &min_y, &max_x, &max_y); /* convert path type */ - lv_path_opa_to_vg(lv_vg_path, dsc); + vg_lite_path_type_t path_type = lv_path_opa_to_path_type(dsc); /* convert blend mode and fill rule */ vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode); vg_lite_fill_t fill = lv_fill_to_vg(dsc->fill_dsc.fill_rule); - /* convert stroke style */ - lv_stroke_to_vg(lv_vg_path, &dsc->stroke_dsc); + /* set default path drop function and data */ + path_drop_func_t path_drop_func = (path_drop_func_t)lv_vg_lite_path_drop; + path_drop_data_t path_drop_data = lv_vg_path; - /* get path bounds */ - float min_x, min_y, max_x, max_y; - lv_vg_lite_path_get_bonding_box(lv_vg_path, &min_x, &min_y, &max_x, &max_y); + /* If it is fill mode, the end op code should be added */ + if(path_type == VG_LITE_DRAW_ZERO + || path_type == VG_LITE_DRAW_FILL_PATH + || path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + lv_vg_lite_path_end(lv_vg_path); + } + + /* convert stroke style */ + if(path_type == VG_LITE_DRAW_STROKE_PATH + || path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + lv_cache_entry_t * stroke_cache_entey = lv_vg_lite_stroke_get(u, lv_vg_path, &dsc->stroke_dsc); + + if(!stroke_cache_entey) { + LV_LOG_ERROR("convert stroke failed"); + + /* drop original path */ + lv_vg_lite_path_drop(u, lv_vg_path); + return; + } + + lv_vg_lite_path_t * ori_path = lv_vg_path; + const vg_lite_path_t * ori_vg_path = lv_vg_lite_path_get_path(ori_path); + + lv_vg_lite_path_t * stroke_path = lv_vg_lite_stroke_get_path(stroke_cache_entey); + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(stroke_path); + + /* set stroke params */ + LV_VG_LITE_CHECK_ERROR(vg_lite_set_path_type(vg_path, path_type)); + vg_path->stroke_color = lv_color32_to_vg(dsc->stroke_dsc.color, dsc->stroke_dsc.opa); + vg_path->quality = ori_vg_path->quality; + lv_memcpy(vg_path->bounding_box, ori_vg_path->bounding_box, sizeof(ori_vg_path->bounding_box)); + + /* change path to stroke path */ + LV_LOG_TRACE("change path to stroke path: %p -> %p", (void *)lv_vg_path, (void *)stroke_path); + lv_vg_path = stroke_path; + path_drop_func = (path_drop_func_t)lv_vg_lite_stroke_drop; + path_drop_data = stroke_cache_entey; + + /* drop original path */ + lv_vg_lite_path_drop(u, ori_path); + } + + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(lv_vg_path); + LV_VG_LITE_ASSERT_PATH(vg_path); if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { /* set scissor area */ @@ -137,6 +183,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec vg_lite_matrix_t result; if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { LV_LOG_ERROR("no inverse matrix"); + path_drop_func(u, path_drop_data); LV_PROFILER_END; return; } @@ -177,7 +224,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec lv_matrix_multiply(&m, &dsc->fill_dsc.matrix); vg_lite_matrix_t pattern_matrix; - lv_matrix_to_vg(&pattern_matrix, &m); + lv_vg_lite_matrix(&pattern_matrix, &m); vg_lite_color_t recolor = lv_vg_lite_color(dsc->fill_dsc.img_dsc.recolor, dsc->fill_dsc.img_dsc.recolor_opa, true); @@ -193,8 +240,8 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec &pattern_matrix, blend, VG_LITE_PATTERN_COLOR, - recolor, vg_color, + recolor, VG_LITE_FILTER_BI_LINEAR)); LV_PROFILER_END_TAG("vg_lite_draw_pattern"); @@ -203,39 +250,18 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec } break; case LV_VECTOR_DRAW_STYLE_GRADIENT: { - /* draw gradient */ - lv_vector_gradient_style_t style = dsc->fill_dsc.gradient.style; - vg_lite_gradient_spreadmode_t spreadmode = lv_spread_to_vg(dsc->fill_dsc.gradient.spread); - LV_UNUSED(spreadmode); + vg_lite_matrix_t grad_matrix; + lv_vg_lite_matrix(&grad_matrix, &dsc->fill_dsc.matrix); - if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) { - vg_lite_matrix_t grad_matrix, fill_matrix; - lv_area_t grad_area; - lv_area_set(&grad_area, (int32_t)min_x, (int32_t)min_y, (int32_t)max_x, (int32_t)max_y); - lv_vg_lite_grad_area_to_matrix(&grad_matrix, &grad_area, LV_GRAD_DIR_HOR); - - lv_matrix_to_vg(&fill_matrix, &dsc->fill_dsc.matrix); - lv_vg_lite_matrix_multiply(&grad_matrix, &matrix); - lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix); - - lv_vg_lite_draw_linear_grad( - u, - &u->target_buffer, - vg_path, - &dsc->fill_dsc.gradient.grad, - &grad_matrix, - &matrix, - fill, - blend); - } - else if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { - if(vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) { - /* TODO: radial gradient */ - } - else { - LV_LOG_WARN("radial gradient is not supported"); - } - } + lv_vg_lite_draw_grad( + u, + &u->target_buffer, + vg_path, + &dsc->fill_dsc.gradient, + &grad_matrix, + &matrix, + fill, + blend); } break; default: @@ -247,7 +273,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec lv_vg_lite_flush(u); /* drop path */ - lv_vg_lite_path_drop(u, lv_vg_path); + path_drop_func(u, path_drop_data); if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { /* disable scissor */ @@ -257,11 +283,6 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec LV_PROFILER_END; } -static void lv_matrix_to_vg(vg_lite_matrix_t * dest, const lv_matrix_t * src) -{ - lv_memcpy(dest, src, sizeof(lv_matrix_t)); -} - static vg_lite_quality_t lv_quality_to_vg(lv_vector_path_quality_t quality) { switch(quality) { @@ -282,10 +303,10 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src lv_vg_lite_path_set_quality(dest, lv_quality_to_vg(src->quality)); /* init bounds */ - float min_x = __FLT_MAX__; - float min_y = __FLT_MAX__; - float max_x = __FLT_MIN__; - float max_y = __FLT_MIN__; + float min_x = FLT_MAX; + float min_y = FLT_MAX; + float max_x = FLT_MIN; + float max_y = FLT_MIN; #define CMP_BOUNDS(point) \ do { \ @@ -341,56 +362,28 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src } } - lv_vg_lite_path_end(dest); lv_vg_lite_path_set_bonding_box(dest, min_x, min_y, max_x, max_y); LV_PROFILER_END; } -static void lv_path_opa_to_vg(lv_vg_lite_path_t * dest, const lv_vector_draw_dsc_t * dsc) +static vg_lite_path_type_t lv_path_opa_to_path_type(const lv_vector_draw_dsc_t * dsc) { - vg_lite_path_type_t path_type = VG_LITE_DRAW_ZERO; lv_opa_t fill_opa = dsc->fill_dsc.opa; lv_opa_t stroke_opa = dsc->stroke_dsc.opa; if(fill_opa > LV_OPA_0 && stroke_opa > LV_OPA_0) { - path_type = VG_LITE_DRAW_FILL_STROKE_PATH; - } - else if(fill_opa == LV_OPA_0 && stroke_opa > LV_OPA_0) { - path_type = VG_LITE_DRAW_STROKE_PATH; - } - else if(fill_opa > LV_OPA_0) { - path_type = VG_LITE_DRAW_FILL_PATH; + return VG_LITE_DRAW_FILL_STROKE_PATH; } - LV_VG_LITE_CHECK_ERROR(vg_lite_set_path_type(lv_vg_lite_path_get_path(dest), path_type)); -} - -static void lv_stroke_to_vg(lv_vg_lite_path_t * dest, const lv_vector_stroke_dsc_t * dsc) -{ - LV_ASSERT_NULL(dest); - LV_ASSERT_NULL(dsc); - - /* if stroke opa is 0, no need to set stroke */ - if(dsc->opa == LV_OPA_0) { - return; + if(fill_opa == LV_OPA_0 && stroke_opa > LV_OPA_0) { + return VG_LITE_DRAW_STROKE_PATH; } - vg_lite_path_t * path = lv_vg_lite_path_get_path(dest); + if(fill_opa > LV_OPA_0) { + return VG_LITE_DRAW_FILL_PATH; + } - LV_VG_LITE_CHECK_ERROR( - vg_lite_set_stroke( - path, - lv_stroke_cap_to_vg(dsc->cap), - lv_stroke_join_to_vg(dsc->join), - dsc->width, - dsc->miter_limit, - lv_array_front(&dsc->dash_pattern), - dsc->dash_pattern.size, - dsc->width / 2, - lv_color32_to_vg(dsc->color, dsc->opa)) - ); - - LV_VG_LITE_CHECK_ERROR(vg_lite_update_stroke(path)); + return VG_LITE_DRAW_ZERO; } static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend) @@ -431,46 +424,4 @@ static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule) } } -static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread) -{ - switch(spread) { - case LV_VECTOR_GRADIENT_SPREAD_PAD: - return VG_LITE_GRADIENT_SPREAD_PAD; - case LV_VECTOR_GRADIENT_SPREAD_REPEAT: - return VG_LITE_GRADIENT_SPREAD_REPEAT; - case LV_VECTOR_GRADIENT_SPREAD_REFLECT: - return VG_LITE_GRADIENT_SPREAD_REFLECT; - default: - return VG_LITE_GRADIENT_SPREAD_FILL; - } -} - -static vg_lite_cap_style_t lv_stroke_cap_to_vg(lv_vector_stroke_cap_t cap) -{ - switch(cap) { - case LV_VECTOR_STROKE_CAP_SQUARE: - return VG_LITE_CAP_SQUARE; - case LV_VECTOR_STROKE_CAP_ROUND: - return VG_LITE_CAP_ROUND; - case LV_VECTOR_STROKE_CAP_BUTT: - return VG_LITE_CAP_BUTT; - default: - return VG_LITE_CAP_SQUARE; - } -} - -static vg_lite_join_style_t lv_stroke_join_to_vg(lv_vector_stroke_join_t join) -{ - switch(join) { - case LV_VECTOR_STROKE_JOIN_BEVEL: - return VG_LITE_JOIN_BEVEL; - case LV_VECTOR_STROKE_JOIN_ROUND: - return VG_LITE_JOIN_ROUND; - case LV_VECTOR_STROKE_JOIN_MITER: - return VG_LITE_JOIN_MITER; - default: - return VG_LITE_JOIN_BEVEL; - } -} - #endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_decoder.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_decoder.c index a0f052356..bb7a784bb 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_decoder.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_decoder.c @@ -7,20 +7,29 @@ * INCLUDES *********************/ +#include "../lv_image_decoder_private.h" #include "lv_vg_lite_decoder.h" #if LV_USE_DRAW_VG_LITE #include "lv_vg_lite_utils.h" +#include +#include +#include "../../core/lv_global.h" /********************* * DEFINES *********************/ +#define DECODER_NAME "VG_LITE" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /* VG_LITE_INDEX1, 2, and 4 require endian flipping + bit flipping, * so for simplicity, they are uniformly converted to I8 for display. */ #define DEST_IMG_FORMAT LV_COLOR_FORMAT_I8 +#define IS_CONV_INDEX_FORMAT(cf) (cf == LV_COLOR_FORMAT_I1 || cf == LV_COLOR_FORMAT_I2 || cf == LV_COLOR_FORMAT_I4) /* Since the palette and index image are next to each other, * the palette size needs to be aligned to ensure that the image is aligned. @@ -32,15 +41,11 @@ * TYPEDEFS **********************/ -typedef struct { - lv_draw_buf_t yuv; /*A draw buffer struct for yuv variable image*/ -} decoder_data_t; - /********************** * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * src, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static void image_color32_pre_mul(lv_color32_t * img_data, uint32_t px_size); @@ -63,7 +68,8 @@ void lv_vg_lite_decoder_init(void) lv_image_decoder_set_info_cb(decoder, decoder_info); lv_image_decoder_set_open_cb(decoder, decoder_open); lv_image_decoder_set_close_cb(decoder, decoder_close); - lv_image_decoder_set_cache_free_cb(decoder, NULL); /*Use general cache free method*/ + + decoder->name = DECODER_NAME; } void lv_vg_lite_decoder_deinit(void) @@ -144,23 +150,24 @@ static void image_decode_to_index8_line(uint8_t * dest, const uint8_t * src, int } } -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { - lv_result_t res = lv_bin_decoder_info(decoder, src, header); + lv_result_t res = lv_bin_decoder_info(decoder, dsc, header); if(res != LV_RESULT_OK) { return res; } - if(LV_COLOR_FORMAT_IS_YUV(header->cf)) { - return LV_RESULT_OK; + if(!IS_CONV_INDEX_FORMAT(header->cf)) { + return LV_RESULT_INVALID; } - if(LV_COLOR_FORMAT_IS_INDEXED(header->cf)) { - header->cf = DEST_IMG_FORMAT; - return LV_RESULT_OK; + if(header->flags & LV_IMAGE_FLAGS_COMPRESSED) { + LV_LOG_WARN("NOT Supported compressed index format: %d", header->cf); + return LV_RESULT_INVALID; } - return LV_RESULT_INVALID; + header->cf = DEST_IMG_FORMAT; + return LV_RESULT_OK; } static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) @@ -178,43 +185,22 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ int32_t width = dsc->header.w; int32_t height = dsc->header.h; - /*In case of uncompressed formats the image stored in the ROM/RAM. - *So simply give its pointer*/ - const uint8_t * image_data = ((lv_image_dsc_t *)dsc->src)->data; - uint32_t image_data_size = ((lv_image_dsc_t *)dsc->src)->data_size; - - /* if is YUV format, no need to copy */ - if(LV_COLOR_FORMAT_IS_YUV(src_cf)) { - decoder_data_t * decoder_data = dsc->user_data; - if(decoder_data == NULL) { - decoder_data = lv_malloc_zeroed(sizeof(decoder_data_t)); - LV_ASSERT_MALLOC(decoder_data); - } - lv_draw_buf_t * draw_buf = &decoder_data->yuv; - uint32_t stride = lv_draw_buf_width_to_stride(width, src_cf); - lv_draw_buf_init(draw_buf, width, height, src_cf, stride, (void *)image_data, image_data_size); - - /* Use alloced bit to indicate we should not free the memory */ - draw_buf->header.flags &= ~LV_IMAGE_FLAGS_ALLOCATED; - - /* Do not add this kind of image to cache, since its life is managed by user. */ - dsc->args.no_cache = true; - - dsc->decoded = draw_buf; - return LV_RESULT_OK; - } - /* create draw buf */ - lv_draw_buf_t * draw_buf = lv_draw_buf_create(width, height, DEST_IMG_FORMAT, LV_STRIDE_AUTO); + lv_draw_buf_t * draw_buf = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, width, height, DEST_IMG_FORMAT, + LV_STRIDE_AUTO); if(draw_buf == NULL) { return LV_RESULT_INVALID; } + + lv_draw_buf_clear(draw_buf, NULL); dsc->decoded = draw_buf; uint32_t src_stride = image_stride(&src_img_buf.header); uint32_t dest_stride = draw_buf->header.stride; - const uint8_t * src = image_data; + /*In case of uncompressed formats the image stored in the ROM/RAM. + *So simply give its pointer*/ + const uint8_t * src = ((lv_image_dsc_t *)dsc->src)->data; uint8_t * dest = draw_buf->data; /* index format only */ @@ -226,7 +212,7 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ /* copy palette */ lv_memcpy(dest, src, palette_size_bytes); - if(!dsc->args.premultiply) { + if(dsc->args.premultiply) { /* pre-multiply palette */ image_color32_pre_mul((lv_color32_t *)dest, palette_size); draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED; @@ -243,11 +229,6 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ dest += dest_stride; } - /* invalidate D-Cache */ - lv_draw_buf_invalidate_cache(draw_buf, NULL); - LV_LOG_INFO("image %p (W%" LV_PRId32 " x H%" LV_PRId32 ", buffer: %p, cf: %d) decode finish", - image_data, width, height, draw_buf->data, src_cf); - return LV_RESULT_OK; } @@ -277,12 +258,15 @@ static lv_result_t decoder_open_file(lv_image_decoder_t * decoder, lv_image_deco return LV_RESULT_INVALID; } - lv_draw_buf_t * draw_buf = lv_draw_buf_create(width, height, DEST_IMG_FORMAT, LV_STRIDE_AUTO); + lv_draw_buf_t * draw_buf = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, width, height, DEST_IMG_FORMAT, + LV_STRIDE_AUTO); if(draw_buf == NULL) { lv_fs_close(&file); return LV_RESULT_INVALID; } + lv_draw_buf_clear(draw_buf, NULL); + /* get stride */ uint32_t src_stride = image_stride(&src_header); uint32_t dest_stride = draw_buf->header.stride; @@ -340,12 +324,6 @@ static lv_result_t decoder_open_file(lv_image_decoder_t * decoder, lv_image_deco lv_free(src_temp); lv_fs_close(&file); - - /* invalidate D-Cache */ - lv_draw_buf_invalidate_cache(draw_buf, NULL); - - LV_LOG_INFO("image %s (W%" LV_PRId32 " x H%" LV_PRId32 ", buffer: %p cf: %d) decode finish", - path, width, height, draw_buf->data, src_header.cf); return LV_RESULT_OK; failed: @@ -359,16 +337,6 @@ failed: return LV_RESULT_INVALID; } -static void decoder_draw_buf_free(lv_draw_buf_t * draw_buf) -{ - if((draw_buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) == 0) { - /* This must be the yuv variable image. */ - return; - } - - lv_draw_buf_destroy(draw_buf); -} - /** * Decode an image using the vg_lite gpu. * @param decoder pointer to the decoder @@ -392,7 +360,10 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(dsc->args.no_cache) return res; -#if LV_CACHE_DEF_SIZE > 0 + /*If the image cache is disabled, just return the decoded image*/ + if(!lv_image_cache_is_enabled()) return res; + + /*Add the decoded image to the cache*/ if(res == LV_RESULT_OK) { lv_image_cache_data_t search_key; search_key.src_type = dsc->src_type; @@ -402,13 +373,12 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d lv_cache_entry_t * entry = lv_image_decoder_add_to_cache(decoder, &search_key, dsc->decoded, NULL); if(entry == NULL) { - decoder_draw_buf_free((lv_draw_buf_t *)dsc->decoded); + lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); dsc->decoded = NULL; return LV_RESULT_INVALID; } dsc->cache_entry = entry; } -#endif return res; } @@ -417,12 +387,7 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * { LV_UNUSED(decoder); /*Unused*/ - if(dsc->args.no_cache || LV_CACHE_DEF_SIZE == 0) - decoder_draw_buf_free((lv_draw_buf_t *)dsc->decoded); - else - lv_cache_release(dsc->cache, dsc->cache_entry, NULL); - - if(decoder->user_data) free(decoder->user_data); + if(dsc->args.no_cache || !lv_image_cache_is_enabled()) lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); } #endif /*LV_USE_DRAW_VG_LITE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.c index 526867190..5158d057d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.c @@ -7,37 +7,61 @@ * INCLUDES *********************/ +#include "../lv_draw_vector_private.h" #include "lv_vg_lite_grad.h" -#if LV_USE_DRAW_VG_LITE +#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC #include "lv_draw_vg_lite_type.h" #include "lv_vg_lite_pending.h" +#include "lv_vg_lite_math.h" +#include "../../misc/lv_types.h" +#include "../../stdlib/lv_string.h" /********************* * DEFINES *********************/ +#define SQUARE(x) ((x)*(x)) + +#ifndef M_PI + #define M_PI 3.1415926f +#endif + /********************** * TYPEDEFS **********************/ +typedef enum { + GRAD_TYPE_UNKNOWN, + GRAD_TYPE_LINEAR, + GRAD_TYPE_LINEAR_EXT, + GRAD_TYPE_RADIAL, +} grad_type_t; + typedef struct { - vg_lite_linear_gradient_t vg_grad; - lv_grad_dsc_t lv_grad; + grad_type_t type; + lv_vector_gradient_t lv; + union { + vg_lite_linear_gradient_t linear; + vg_lite_ext_linear_gradient_t linear_ext; + vg_lite_radial_gradient_t radial; + } vg; } grad_item_t; /********************** * STATIC PROTOTYPES **********************/ -static vg_lite_linear_gradient_t * lv_vg_lite_linear_grad_get(struct _lv_draw_vg_lite_unit_t * u, - const lv_grad_dsc_t * grad); - +static grad_item_t * grad_get(struct lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad); +static void grad_cache_release_cb(void * entry, void * user_data); static bool grad_create_cb(grad_item_t * item, void * user_data); static void grad_free_cb(grad_item_t * item, void * user_data); static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const grad_item_t * rhs); -static void grad_cache_release_cb(void * entry, void * user_data); + +static grad_type_t lv_grad_style_to_type(lv_vector_gradient_style_t style); +static void grad_point_to_matrix(vg_lite_matrix_t * grad_matrix, float x1, float y1, float x2, float y2); +static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread); /********************** * STATIC VARIABLES @@ -51,7 +75,7 @@ static void grad_cache_release_cb(void * entry, void * user_data); * GLOBAL FUNCTIONS **********************/ -void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u) +void lv_vg_lite_grad_init(struct lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt) { LV_ASSERT_NULL(u); @@ -61,106 +85,252 @@ void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u) .free_cb = (lv_cache_free_cb_t)grad_free_cb, }; - u->grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(grad_item_t), LV_VG_LITE_GRAD_CACHE_SIZE, ops); - LV_ASSERT_NULL(u->grad_cache); - + u->grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(grad_item_t), cache_cnt, ops); + lv_cache_set_name(u->grad_cache, "VG_GRAD"); u->grad_pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4); lv_vg_lite_pending_set_free_cb(u->grad_pending, grad_cache_release_cb, u->grad_cache); } -void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u) +void lv_vg_lite_grad_deinit(struct lv_draw_vg_lite_unit_t * u) { LV_ASSERT_NULL(u); + LV_ASSERT_NULL(u->grad_pending) lv_vg_lite_pending_destroy(u->grad_pending); + u->grad_pending = NULL; lv_cache_destroy(u->grad_cache, NULL); + u->grad_cache = NULL; } -void lv_vg_lite_grad_area_to_matrix(vg_lite_matrix_t * grad_matrix, const lv_area_t * area, lv_grad_dir_t dir) -{ - LV_ASSERT_NULL(grad_matrix); - LV_ASSERT_NULL(area); - - vg_lite_identity(grad_matrix); - vg_lite_translate(area->x1, area->y1, grad_matrix); - - switch(dir) { - case LV_GRAD_DIR_VER: - vg_lite_scale(1, lv_area_get_height(area) / 256.0f, grad_matrix); - vg_lite_rotate(90, grad_matrix); - break; - - case LV_GRAD_DIR_HOR: - vg_lite_scale(lv_area_get_width(area) / 256.0f, 1, grad_matrix); - break; - - default: - break; - } -} - -void lv_vg_lite_draw_linear_grad( - struct _lv_draw_vg_lite_unit_t * u, +bool lv_vg_lite_draw_grad( + struct lv_draw_vg_lite_unit_t * u, vg_lite_buffer_t * buffer, vg_lite_path_t * path, - const lv_grad_dsc_t * grad, + const lv_vector_gradient_t * grad, const vg_lite_matrix_t * grad_matrix, const vg_lite_matrix_t * matrix, vg_lite_fill_t fill, vg_lite_blend_t blend) { LV_ASSERT_NULL(u); - LV_ASSERT_NULL(buffer); - LV_ASSERT_NULL(path); - LV_ASSERT_NULL(grad); - LV_ASSERT_NULL(grad_matrix); - LV_ASSERT_NULL(matrix); - - LV_PROFILER_BEGIN; - - vg_lite_linear_gradient_t * gradient = lv_vg_lite_linear_grad_get(u, grad); - LV_ASSERT_NULL(gradient); - if(!gradient) { - LV_LOG_ERROR("Failed to get linear gradient"); - LV_PROFILER_END; - return; - } - - vg_lite_matrix_t * grad_mat_p = vg_lite_get_grad_matrix(gradient); - LV_ASSERT_NULL(grad_mat_p); - *grad_mat_p = *grad_matrix; - LV_VG_LITE_ASSERT_DEST_BUFFER(buffer); - LV_VG_LITE_ASSERT_SRC_BUFFER(&gradient->image); LV_VG_LITE_ASSERT_PATH(path); - LV_VG_LITE_ASSERT_MATRIX(grad_mat_p); + LV_ASSERT_NULL(grad); + LV_VG_LITE_ASSERT_MATRIX(grad_matrix); LV_VG_LITE_ASSERT_MATRIX(matrix); - LV_PROFILER_BEGIN_TAG("vg_lite_draw_grad"); - LV_VG_LITE_CHECK_ERROR(vg_lite_draw_grad( - buffer, - path, - fill, - (vg_lite_matrix_t *)matrix, - gradient, - blend)); - LV_PROFILER_END_TAG("vg_lite_draw_grad"); + /* check radial gradient is supported */ + if(grad->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { + if(!vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) { + LV_LOG_INFO("radial gradient is not supported"); + return false; + } - LV_PROFILER_END; + /* check if the radius is valid */ + if(grad->cr <= 0) { + LV_LOG_INFO("radius: %f is not valid", grad->cr); + return false; + } + } + + /* check spread mode is supported */ + if(grad->spread == LV_VECTOR_GRADIENT_SPREAD_REPEAT || grad->spread == LV_VECTOR_GRADIENT_SPREAD_REFLECT) { + if(!vg_lite_query_feature(gcFEATURE_BIT_VG_IM_REPEAT_REFLECT)) { + LV_LOG_INFO("repeat/reflect spread(%d) is not supported", grad->spread); + return false; + } + } + + LV_PROFILER_BEGIN_TAG("grad_get"); + grad_item_t * grad_item = grad_get(u, grad); + LV_PROFILER_END_TAG("grad_get"); + if(!grad_item) { + LV_LOG_WARN("Failed to get gradient, style: %d", grad->style); + return false; + } + LV_ASSERT(grad_item->lv.style == grad->style); + + switch(grad_item->type) { + case GRAD_TYPE_LINEAR: { + vg_lite_linear_gradient_t * linear_grad = &grad_item->vg.linear; + vg_lite_matrix_t * grad_mat_p = vg_lite_get_grad_matrix(linear_grad); + LV_ASSERT_NULL(grad_mat_p); + vg_lite_identity(grad_mat_p); + lv_vg_lite_matrix_multiply(grad_mat_p, grad_matrix); + grad_point_to_matrix(grad_mat_p, grad->x1, grad->y1, grad->x2, grad->y2); + + LV_VG_LITE_ASSERT_SRC_BUFFER(&linear_grad->image); + + LV_PROFILER_BEGIN_TAG("vg_lite_draw_grad"); + LV_VG_LITE_CHECK_ERROR(vg_lite_draw_grad( + buffer, + path, + fill, + (vg_lite_matrix_t *)matrix, + linear_grad, + blend)); + LV_PROFILER_END_TAG("vg_lite_draw_grad"); + } + break; + case GRAD_TYPE_LINEAR_EXT: { + vg_lite_ext_linear_gradient_t * linear_grad = &grad_item->vg.linear_ext; + vg_lite_matrix_t * grad_mat_p = vg_lite_get_linear_grad_matrix(linear_grad); + LV_ASSERT_NULL(grad_mat_p); + *grad_mat_p = *grad_matrix; + + LV_VG_LITE_ASSERT_SRC_BUFFER(&linear_grad->image); + + LV_PROFILER_BEGIN_TAG("vg_lite_draw_linear_grad"); + LV_VG_LITE_CHECK_ERROR(vg_lite_draw_linear_grad( + buffer, + path, + fill, + (vg_lite_matrix_t *)matrix, + linear_grad, + 0, + blend, + VG_LITE_FILTER_LINEAR)); + LV_PROFILER_END_TAG("vg_lite_draw_linear_grad"); + } + break; + + case GRAD_TYPE_RADIAL: { + vg_lite_radial_gradient_t * radial = &grad_item->vg.radial; + vg_lite_matrix_t * grad_mat_p = vg_lite_get_radial_grad_matrix(radial); + LV_ASSERT_NULL(grad_mat_p); + *grad_mat_p = *grad_matrix; + + LV_VG_LITE_ASSERT_SRC_BUFFER(&grad_item->vg.radial.image); + + LV_PROFILER_BEGIN_TAG("vg_lite_draw_radial_grad"); + LV_VG_LITE_CHECK_ERROR( + vg_lite_draw_radial_grad( + buffer, + path, + fill, + (vg_lite_matrix_t *)matrix, + &grad_item->vg.radial, + 0, + blend, + VG_LITE_FILTER_LINEAR)); + LV_PROFILER_END_TAG("vg_lite_draw_radial_grad"); + } + break; + + default: + LV_LOG_ERROR("Unsupported gradient type: %d", grad_item->type); + return false; + } + + return true; +} + +bool lv_vg_lite_draw_grad_helper( + struct lv_draw_vg_lite_unit_t * u, + vg_lite_buffer_t * buffer, + vg_lite_path_t * path, + const lv_area_t * area, + const lv_grad_dsc_t * grad_dsc, + const vg_lite_matrix_t * matrix, + vg_lite_fill_t fill, + vg_lite_blend_t blend) +{ + LV_ASSERT_NULL(u); + LV_VG_LITE_ASSERT_DEST_BUFFER(buffer); + LV_VG_LITE_ASSERT_PATH(path); + LV_ASSERT_NULL(area); + LV_ASSERT_NULL(grad_dsc); + LV_VG_LITE_ASSERT_MATRIX(matrix); + + lv_vector_gradient_t grad; + lv_memzero(&grad, sizeof(grad)); + + grad.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; + grad.stops_count = grad_dsc->stops_count; + lv_memcpy(grad.stops, grad_dsc->stops, sizeof(lv_gradient_stop_t) * grad_dsc->stops_count); + + /*convert to spread mode*/ +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + switch(grad_dsc->extend) { + case LV_GRAD_EXTEND_PAD: + grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; + break; + case LV_GRAD_EXTEND_REPEAT: + grad.spread = LV_VECTOR_GRADIENT_SPREAD_REPEAT; + break; + case LV_GRAD_EXTEND_REFLECT: + grad.spread = LV_VECTOR_GRADIENT_SPREAD_REFLECT; + break; + default: + LV_LOG_WARN("Unsupported gradient extend mode: %d", grad_dsc->extend); + grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; + break; + } +#else + grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; +#endif + + switch(grad_dsc->dir) { + case LV_GRAD_DIR_VER: + grad.x1 = area->x1; + grad.y1 = area->y1; + grad.x2 = area->x1; + grad.y2 = area->y2 + 1; + break; + + case LV_GRAD_DIR_HOR: + grad.x1 = area->x1; + grad.y1 = area->y1; + grad.x2 = area->x2 + 1; + grad.y2 = area->y1; + break; + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + case LV_GRAD_DIR_LINEAR: { + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + + grad.x1 = lv_pct_to_px(grad_dsc->params.linear.start.x, w) + area->x1; + grad.y1 = lv_pct_to_px(grad_dsc->params.linear.start.y, h) + area->y1; + grad.x2 = lv_pct_to_px(grad_dsc->params.linear.end.x, w) + area->x1; + grad.y2 = lv_pct_to_px(grad_dsc->params.linear.end.y, h) + area->y1; + } + break; + + case LV_GRAD_DIR_RADIAL: { + grad.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + + grad.cx = lv_pct_to_px(grad_dsc->params.radial.focal.x, w) + area->x1; + grad.cy = lv_pct_to_px(grad_dsc->params.radial.focal.y, h) + area->y1; + int32_t end_extent_x = lv_pct_to_px(grad_dsc->params.radial.end_extent.x, w) + area->x1; + int32_t end_extent_y = lv_pct_to_px(grad_dsc->params.radial.end_extent.y, h) + area->y1; + grad.cr = LV_MAX(end_extent_x - grad.cx, end_extent_y - grad.cy); + } + break; +#endif + + default: + LV_LOG_WARN("Unsupported gradient direction: %d", grad_dsc->dir); + return false; + } + + return lv_vg_lite_draw_grad(u, buffer, path, &grad, matrix, matrix, fill, blend); } /********************** * STATIC FUNCTIONS **********************/ -static vg_lite_linear_gradient_t * lv_vg_lite_linear_grad_get(struct _lv_draw_vg_lite_unit_t * u, - const lv_grad_dsc_t * grad) +static grad_item_t * grad_get(struct lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad) { LV_ASSERT_NULL(u); LV_ASSERT_NULL(grad); grad_item_t search_key; - lv_memzero(&search_key, sizeof(grad_item_t)); - search_key.lv_grad = *grad; + lv_memzero(&search_key, sizeof(search_key)); + search_key.type = lv_grad_style_to_type(grad->style); + search_key.lv = *grad; lv_cache_entry_t * cache_node_entry = lv_cache_acquire(u->grad_cache, &search_key, NULL); if(cache_node_entry == NULL) { @@ -181,17 +351,45 @@ static vg_lite_linear_gradient_t * lv_vg_lite_linear_grad_get(struct _lv_draw_vg /* Add the new entry to the pending list */ lv_vg_lite_pending_add(u->grad_pending, &cache_node_entry); - grad_item_t * item = lv_cache_entry_get_data(cache_node_entry); - return &item->vg_grad; + return lv_cache_entry_get_data(cache_node_entry); } -static bool grad_create_cb(grad_item_t * item, void * user_data) +static void grad_cache_release_cb(void * entry, void * user_data) { - LV_UNUSED(user_data); + lv_cache_entry_t ** entry_p = entry; + lv_cache_t * cache = user_data; + lv_cache_release(cache, * entry_p, NULL); +} +static vg_lite_color_ramp_t * grad_create_color_ramp(const lv_vector_gradient_t * grad) +{ + LV_ASSERT_NULL(grad); + + vg_lite_color_ramp_t * color_ramp = lv_malloc(sizeof(vg_lite_color_ramp_t) * grad->stops_count); + LV_ASSERT_MALLOC(color_ramp); + if(!color_ramp) { + LV_LOG_ERROR("malloc failed for color_ramp"); + return NULL; + } + + for(uint16_t i = 0; i < grad->stops_count; i++) { + color_ramp[i].stop = grad->stops[i].frac / 255.0f; + lv_color_t c = grad->stops[i].color; + + color_ramp[i].red = c.red / 255.0f; + color_ramp[i].green = c.green / 255.0f; + color_ramp[i].blue = c.blue / 255.0f; + color_ramp[i].alpha = grad->stops[i].opa / 255.0f; + } + + return color_ramp; +} + +static bool linear_grad_create(grad_item_t * item) +{ LV_PROFILER_BEGIN; - vg_lite_error_t err = vg_lite_init_grad(&item->vg_grad); + vg_lite_error_t err = vg_lite_init_grad(&item->vg.linear); if(err != VG_LITE_SUCCESS) { LV_PROFILER_END; LV_LOG_ERROR("init grad error(%d): %s", (int)err, lv_vg_lite_error_string(err)); @@ -202,42 +400,283 @@ static bool grad_create_cb(grad_item_t * item, void * user_data) vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS]; /* Gradient setup */ - uint8_t cnt = item->lv_grad.stops_count; - LV_ASSERT(cnt < VLC_MAX_GRADIENT_STOPS); - for(uint8_t i = 0; i < cnt; i++) { - stops[i] = item->lv_grad.stops[i].frac; - const lv_color_t * c = &item->lv_grad.stops[i].color; - lv_opa_t opa = item->lv_grad.stops[i].opa; + if(item->lv.stops_count > VLC_MAX_GRADIENT_STOPS) { + LV_LOG_WARN("Gradient stops limited: %d, max: %d", item->lv.stops_count, VLC_MAX_GRADIENT_STOPS); + item->lv.stops_count = VLC_MAX_GRADIENT_STOPS; + } + + for(uint16_t i = 0; i < item->lv.stops_count; i++) { + stops[i] = item->lv.stops[i].frac; + const lv_color_t * c = &item->lv.stops[i].color; + lv_opa_t opa = item->lv.stops[i].opa; /* lvgl color -> gradient color */ lv_color_t grad_color = lv_color_make(c->blue, c->green, c->red); colors[i] = lv_vg_lite_color(grad_color, opa, true); } - LV_VG_LITE_CHECK_ERROR(vg_lite_set_grad(&item->vg_grad, cnt, colors, stops)); + LV_VG_LITE_CHECK_ERROR(vg_lite_set_grad(&item->vg.linear, item->lv.stops_count, colors, stops)); LV_PROFILER_BEGIN_TAG("vg_lite_update_grad"); - LV_VG_LITE_CHECK_ERROR(vg_lite_update_grad(&item->vg_grad)); + LV_VG_LITE_CHECK_ERROR(vg_lite_update_grad(&item->vg.linear)); LV_PROFILER_END_TAG("vg_lite_update_grad"); LV_PROFILER_END; return true; } +static bool linear_ext_grad_create(grad_item_t * item) +{ + LV_PROFILER_BEGIN; + + if(item->lv.stops_count > VLC_MAX_COLOR_RAMP_STOPS) { + LV_LOG_WARN("Gradient stops limited: %d, max: %d", item->lv.stops_count, VLC_MAX_GRADIENT_STOPS); + item->lv.stops_count = VLC_MAX_COLOR_RAMP_STOPS; + } + + vg_lite_color_ramp_t * color_ramp = grad_create_color_ramp(&item->lv); + if(!color_ramp) { + LV_PROFILER_END; + return false; + } + + const vg_lite_linear_gradient_parameter_t grad_param = { + .X0 = item->lv.x1, + .Y0 = item->lv.y1, + .X1 = item->lv.x2, + .Y1 = item->lv.y2, + }; + + vg_lite_ext_linear_gradient_t linear_grad; + lv_memzero(&linear_grad, sizeof(linear_grad)); + + LV_PROFILER_BEGIN_TAG("vg_lite_set_linear_grad"); + LV_VG_LITE_CHECK_ERROR( + vg_lite_set_linear_grad( + &linear_grad, + item->lv.stops_count, + color_ramp, + grad_param, + lv_spread_to_vg(item->lv.spread), + 1)); + LV_PROFILER_END_TAG("vg_lite_set_linear_grad"); + + LV_PROFILER_BEGIN_TAG("vg_lite_update_linear_grad"); + vg_lite_error_t err = vg_lite_update_linear_grad(&linear_grad); + LV_PROFILER_END_TAG("vg_lite_update_linear_grad"); + if(err == VG_LITE_SUCCESS) { + item->vg.linear_ext = linear_grad; + } + else { + LV_LOG_ERROR("update grad error(%d): %s", (int)err, lv_vg_lite_error_string(err)); + } + + lv_free(color_ramp); + + LV_PROFILER_END; + return err == VG_LITE_SUCCESS; +} + +static bool radial_grad_create(grad_item_t * item) +{ + LV_PROFILER_BEGIN; + + if(item->lv.stops_count > VLC_MAX_COLOR_RAMP_STOPS) { + LV_LOG_WARN("Gradient stops limited: %d, max: %d", item->lv.stops_count, VLC_MAX_GRADIENT_STOPS); + item->lv.stops_count = VLC_MAX_COLOR_RAMP_STOPS; + } + + vg_lite_color_ramp_t * color_ramp = grad_create_color_ramp(&item->lv); + if(!color_ramp) { + LV_PROFILER_END; + return false; + } + + const vg_lite_radial_gradient_parameter_t grad_param = { + .cx = item->lv.cx, + .cy = item->lv.cy, + .r = item->lv.cr, + .fx = item->lv.cx, + .fy = item->lv.cy, + }; + + vg_lite_radial_gradient_t radial_grad; + lv_memzero(&radial_grad, sizeof(radial_grad)); + + LV_PROFILER_BEGIN_TAG("vg_lite_set_radial_grad"); + LV_VG_LITE_CHECK_ERROR( + vg_lite_set_radial_grad( + &radial_grad, + item->lv.stops_count, + color_ramp, + grad_param, + lv_spread_to_vg(item->lv.spread), + 1)); + LV_PROFILER_END_TAG("vg_lite_set_radial_grad"); + + LV_PROFILER_BEGIN_TAG("vg_lite_update_radial_grad"); + vg_lite_error_t err = vg_lite_update_radial_grad(&radial_grad); + LV_PROFILER_END_TAG("vg_lite_update_radial_grad"); + if(err == VG_LITE_SUCCESS) { + item->vg.radial = radial_grad; + } + else { + LV_LOG_ERROR("update radial grad error(%d): %s", (int)err, lv_vg_lite_error_string(err)); + } + + lv_free(color_ramp); + + LV_PROFILER_END; + return err == VG_LITE_SUCCESS; +} + +static grad_type_t lv_grad_style_to_type(lv_vector_gradient_style_t style) +{ + if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) { + return vg_lite_query_feature(gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT) ? GRAD_TYPE_LINEAR_EXT : GRAD_TYPE_LINEAR; + } + + if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { + return GRAD_TYPE_RADIAL; + } + + LV_LOG_WARN("unknown gradient style: %d", style); + return GRAD_TYPE_UNKNOWN; +} + +static void grad_point_to_matrix(vg_lite_matrix_t * grad_matrix, float x1, float y1, float x2, float y2) +{ + vg_lite_translate(x1, y1, grad_matrix); + + float angle = atan2f(y2 - y1, x2 - x1) * 180.0f / (float)M_PI; + vg_lite_rotate(angle, grad_matrix); + float length = sqrtf(SQUARE(x2 - x1) + SQUARE(y2 - y1)); + vg_lite_scale(length / 256.0f, 1, grad_matrix); +} + +static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread) +{ + switch(spread) { + case LV_VECTOR_GRADIENT_SPREAD_PAD: + return VG_LITE_GRADIENT_SPREAD_PAD; + case LV_VECTOR_GRADIENT_SPREAD_REPEAT: + return VG_LITE_GRADIENT_SPREAD_REPEAT; + case LV_VECTOR_GRADIENT_SPREAD_REFLECT: + return VG_LITE_GRADIENT_SPREAD_REFLECT; + default: + LV_LOG_WARN("unknown spread mode: %d", spread); + break; + } + + return VG_LITE_GRADIENT_SPREAD_FILL; +} + +static bool grad_create_cb(grad_item_t * item, void * user_data) +{ + LV_UNUSED(user_data); + item->type = lv_grad_style_to_type(item->lv.style); + switch(item->type) { + case GRAD_TYPE_LINEAR: + return linear_grad_create(item); + + case GRAD_TYPE_LINEAR_EXT: + return linear_ext_grad_create(item); + + case GRAD_TYPE_RADIAL: + return radial_grad_create(item); + + default: + LV_LOG_ERROR("unknown gradient type: %d", item->type); + break; + } + + return false; +} + static void grad_free_cb(grad_item_t * item, void * user_data) { LV_UNUSED(user_data); - LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&item->vg_grad)); + switch(item->type) { + case GRAD_TYPE_LINEAR: + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&item->vg.linear)); + break; + + case GRAD_TYPE_LINEAR_EXT: + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_linear_grad(&item->vg.linear_ext)); + break; + + case GRAD_TYPE_RADIAL: + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_radial_grad(&item->vg.radial)); + break; + + default: + LV_LOG_ERROR("unknown gradient type: %d", item->type); + break; + } } static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const grad_item_t * rhs) { - if(lhs->lv_grad.stops_count != rhs->lv_grad.stops_count) { - return lhs->lv_grad.stops_count > rhs->lv_grad.stops_count ? 1 : -1; + /* compare type first */ + if(lhs->type != rhs->type) { + return lhs->type > rhs->type ? 1 : -1; } - int cmp_res = memcmp(lhs->lv_grad.stops, rhs->lv_grad.stops, - sizeof(lv_gradient_stop_t) * lhs->lv_grad.stops_count); + /* compare spread mode */ + if(lhs->lv.spread != rhs->lv.spread) { + return lhs->lv.spread > rhs->lv.spread ? 1 : -1; + } + + /* compare gradient parameters */ + switch(lhs->type) { + case GRAD_TYPE_LINEAR: + /* no extra compare needed */ + break; + + case GRAD_TYPE_LINEAR_EXT: + if(!math_equal(lhs->lv.x1, rhs->lv.x1)) { + return lhs->lv.x1 > rhs->lv.x1 ? 1 : -1; + } + + if(!math_equal(lhs->lv.y1, rhs->lv.y1)) { + return lhs->lv.y1 > rhs->lv.y1 ? 1 : -1; + } + + if(!math_equal(lhs->lv.x2, rhs->lv.x2)) { + return lhs->lv.x2 > rhs->lv.x2 ? 1 : -1; + } + + if(!math_equal(lhs->lv.y2, rhs->lv.y2)) { + return lhs->lv.y2 > rhs->lv.y2 ? 1 : -1; + } + break; + + case GRAD_TYPE_RADIAL: + if(!math_equal(lhs->lv.cx, rhs->lv.cx)) { + return lhs->lv.cx > rhs->lv.cx ? 1 : -1; + } + + if(!math_equal(lhs->lv.cy, rhs->lv.cy)) { + return lhs->lv.cy > rhs->lv.cy ? 1 : -1; + } + + if(!math_equal(lhs->lv.cr, rhs->lv.cr)) { + return lhs->lv.cr > rhs->lv.cr ? 1 : -1; + } + break; + + default: + LV_LOG_ERROR("unknown gradient type: %d", lhs->type); + break; + } + + /* compare stops count and stops */ + if(lhs->lv.stops_count != rhs->lv.stops_count) { + return lhs->lv.stops_count > rhs->lv.stops_count ? 1 : -1; + } + + int cmp_res = lv_memcmp(lhs->lv.stops, rhs->lv.stops, + sizeof(lv_gradient_stop_t) * lhs->lv.stops_count); if(cmp_res != 0) { return cmp_res > 0 ? 1 : -1; } @@ -245,11 +684,4 @@ static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const gra return 0; } -static void grad_cache_release_cb(void * entry, void * user_data) -{ - lv_cache_entry_t ** entry_p = entry; - lv_cache_t * cache = user_data; - lv_cache_release(cache, *entry_p, NULL); -} - -#endif /*LV_USE_DRAW_VG_LITE*/ +#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.h index d709ade46..d8b9d1f97 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_grad.h @@ -16,7 +16,7 @@ extern "C" { #include "../../lvgl.h" -#if LV_USE_DRAW_VG_LITE +#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC #include "lv_vg_lite_utils.h" @@ -32,29 +32,35 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u); +void lv_vg_lite_grad_init(struct lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt); -void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u); +void lv_vg_lite_grad_deinit(struct lv_draw_vg_lite_unit_t * u); -void lv_vg_lite_grad_area_to_matrix(vg_lite_matrix_t * grad_matrix, const lv_area_t * area, lv_grad_dir_t dir); - -void lv_vg_lite_draw_linear_grad( - struct _lv_draw_vg_lite_unit_t * u, +bool lv_vg_lite_draw_grad( + struct lv_draw_vg_lite_unit_t * u, vg_lite_buffer_t * buffer, vg_lite_path_t * path, - const lv_grad_dsc_t * grad, + const lv_vector_gradient_t * grad, const vg_lite_matrix_t * grad_matrix, const vg_lite_matrix_t * matrix, vg_lite_fill_t fill, vg_lite_blend_t blend); -void lv_vg_lite_linear_grad_release_all(struct _lv_draw_vg_lite_unit_t * u); +bool lv_vg_lite_draw_grad_helper( + struct lv_draw_vg_lite_unit_t * u, + vg_lite_buffer_t * buffer, + vg_lite_path_t * path, + const lv_area_t * area, + const lv_grad_dsc_t * grad_dsc, + const vg_lite_matrix_t * matrix, + vg_lite_fill_t fill, + vg_lite_blend_t blend); /********************** * MACROS **********************/ -#endif /*LV_USE_DRAW_VG_LITE*/ +#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.c index 08b180bf8..52b4bb950 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.c @@ -46,7 +46,9 @@ float math_fast_inv_sqrtf(float number) x2 = number * 0.5f; y = number; i = *(int32_t *)&y; /* evil floating point bit level hacking */ - i = 0x5f3759df - (i >> 1); /* what the fuck? */ + i = 0x5f3759df /* floating-point representation of an approximation of {\sqrt {2^{127}}}} see https://en.wikipedia.org/wiki/Fast_inverse_square_root. */ + - (i >> + 1); y = *(float *)&i; y = y * (threehalfs - (x2 * y * y)); /* 1st iteration */ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.h index 5607333b4..3b4b45d75 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_math.h @@ -40,7 +40,7 @@ extern "C" { #define MATH_SQRTF(x) sqrtf(x) #define MATH_RADIANS(deg) ((deg) * DEG_TO_RAD) -#define MATH_DEGRESS(rad) ((rad) * RAD_TO_DEG) +#define MATH_DEGREES(rad) ((rad) * RAD_TO_DEG) /********************** * TYPEDEFS diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c index 3efe5070c..1c530072a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.c @@ -34,7 +34,7 @@ * TYPEDEFS **********************/ -struct _lv_vg_lite_path_t { +struct lv_vg_lite_path_t { vg_lite_path_t base; size_t mem_size; uint8_t format_len; @@ -63,14 +63,14 @@ typedef struct { * GLOBAL FUNCTIONS **********************/ -void lv_vg_lite_path_init(struct _lv_draw_vg_lite_unit_t * unit) +void lv_vg_lite_path_init(struct lv_draw_vg_lite_unit_t * unit) { LV_ASSERT_NULL(unit); unit->global_path = lv_vg_lite_path_create(VG_LITE_FP32); unit->path_in_use = false; } -void lv_vg_lite_path_deinit(struct _lv_draw_vg_lite_unit_t * unit) +void lv_vg_lite_path_deinit(struct lv_draw_vg_lite_unit_t * unit) { LV_ASSERT_NULL(unit); LV_ASSERT(!unit->path_in_use); @@ -111,7 +111,7 @@ void lv_vg_lite_path_destroy(lv_vg_lite_path_t * path) LV_PROFILER_END; } -lv_vg_lite_path_t * lv_vg_lite_path_get(struct _lv_draw_vg_lite_unit_t * unit, vg_lite_format_t data_format) +lv_vg_lite_path_t * lv_vg_lite_path_get(struct lv_draw_vg_lite_unit_t * unit, vg_lite_format_t data_format) { LV_ASSERT_NULL(unit); LV_ASSERT_NULL(unit->global_path); @@ -121,7 +121,7 @@ lv_vg_lite_path_t * lv_vg_lite_path_get(struct _lv_draw_vg_lite_unit_t * unit, v return unit->global_path; } -void lv_vg_lite_path_drop(struct _lv_draw_vg_lite_unit_t * unit, lv_vg_lite_path_t * path) +void lv_vg_lite_path_drop(struct lv_draw_vg_lite_unit_t * unit, lv_vg_lite_path_t * path) { LV_ASSERT_NULL(unit); LV_ASSERT_NULL(path); @@ -218,10 +218,10 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path) lv_vg_lite_path_bounds_t bounds; /* init bounds */ - bounds.min_x = __FLT_MAX__; - bounds.min_y = __FLT_MAX__; - bounds.max_x = __FLT_MIN__; - bounds.max_y = __FLT_MIN__; + bounds.min_x = FLT_MAX; + bounds.min_y = FLT_MAX; + bounds.max_x = FLT_MIN; + bounds.max_y = FLT_MIN; /* calc bounds */ lv_vg_lite_path_for_each_data(lv_vg_lite_path_get_path(path), path_bounds_iter_cb, &bounds); @@ -327,26 +327,26 @@ void lv_vg_lite_path_end(lv_vg_lite_path_t * path) { LV_ASSERT_NULL(path); lv_vg_lite_path_append_op(path, VLC_OP_END); + path->base.add_end = 1; } void lv_vg_lite_path_append_rect( lv_vg_lite_path_t * path, float x, float y, float w, float h, - float rx, float ry) + float r) { LV_PROFILER_BEGIN; - const float half_w = w * 0.5f; - const float half_h = h * 0.5f; + const float half_w = w / 2.0f; + const float half_h = h / 2.0f; /*clamping cornerRadius by minimum size*/ - if(rx > half_w) - rx = half_w; - if(ry > half_h) - ry = half_h; + const float r_max = LV_MIN(half_w, half_h); + if(r > r_max) + r = r_max; /*rectangle*/ - if(rx == 0 && ry == 0) { + if(r <= 0) { lv_vg_lite_path_move_to(path, x, y); lv_vg_lite_path_line_to(path, x + w, y); lv_vg_lite_path_line_to(path, x + w, y + h); @@ -357,24 +357,44 @@ void lv_vg_lite_path_append_rect( } /*circle*/ - if(math_equal(rx, half_w) && math_equal(ry, half_h)) { - lv_vg_lite_path_append_circle(path, x + (w * 0.5f), y + (h * 0.5f), rx, ry); + if(math_equal(r, half_w) && math_equal(r, half_h)) { + lv_vg_lite_path_append_circle(path, x + half_w, y + half_h, r, r); LV_PROFILER_END; return; } - /*rounded rectangle*/ - float hrx = rx * 0.5f; - float hry = ry * 0.5f; - lv_vg_lite_path_move_to(path, x + rx, y); - lv_vg_lite_path_line_to(path, x + w - rx, y); - lv_vg_lite_path_cubic_to(path, x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry); - lv_vg_lite_path_line_to(path, x + w, y + h - ry); - lv_vg_lite_path_cubic_to(path, x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h); - lv_vg_lite_path_line_to(path, x + rx, y + h); - lv_vg_lite_path_cubic_to(path, x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry); - lv_vg_lite_path_line_to(path, x, y + ry); - lv_vg_lite_path_cubic_to(path, x, y + ry - hry, x + rx - hrx, y, x + rx, y); + /* Get the control point offset for rounded cases */ + const float offset = r * PATH_ARC_MAGIC; + + /* Rounded rectangle case */ + /* Starting point */ + lv_vg_lite_path_move_to(path, x + r, y); + + /* Top side */ + lv_vg_lite_path_line_to(path, x + w - r, y); + + /* Top-right corner */ + lv_vg_lite_path_cubic_to(path, x + w - r + offset, y, x + w, y + r - offset, x + w, y + r); + + /* Right side */ + lv_vg_lite_path_line_to(path, x + w, y + h - r); + + /* Bottom-right corner*/ + lv_vg_lite_path_cubic_to(path, x + w, y + h - r + offset, x + w - r + offset, y + h, x + w - r, y + h); + + /* Bottom side */ + lv_vg_lite_path_line_to(path, x + r, y + h); + + /* Bottom-left corner */ + lv_vg_lite_path_cubic_to(path, x + r - offset, y + h, x, y + h - r + offset, x, y + h - r); + + /* Left side*/ + lv_vg_lite_path_line_to(path, x, y + r); + + /* Top-left corner */ + lv_vg_lite_path_cubic_to(path, x, y + r - offset, x + r - offset, y, x + r, y); + + /* Ending point */ lv_vg_lite_path_close(path); LV_PROFILER_END; } @@ -589,6 +609,15 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_ } } +void lv_vg_lite_path_append_path(lv_vg_lite_path_t * dest, const lv_vg_lite_path_t * src) +{ + LV_ASSERT_NULL(dest); + LV_ASSERT_NULL(src); + + LV_ASSERT(dest->base.format == dest->base.format); + lv_vg_lite_path_append_data(dest, src->base.path, src->base.path_length); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h index c7172e6fe..6854b079a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_path.h @@ -22,8 +22,8 @@ extern "C" { * DEFINES *********************/ -typedef struct _lv_vg_lite_path_t lv_vg_lite_path_t; -typedef struct _lv_draw_vg_lite_unit_t lv_draw_vg_lite_unit_t; +typedef struct lv_vg_lite_path_t lv_vg_lite_path_t; +typedef struct lv_draw_vg_lite_unit_t lv_draw_vg_lite_unit_t; typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len); @@ -87,7 +87,7 @@ void lv_vg_lite_path_end(lv_vg_lite_path_t * path); void lv_vg_lite_path_append_rect(lv_vg_lite_path_t * path, float x, float y, float w, float h, - float rx, float ry); + float r); void lv_vg_lite_path_append_circle(lv_vg_lite_path_t * path, float cx, float cy, @@ -105,6 +105,8 @@ void lv_vg_lite_path_append_arc(lv_vg_lite_path_t * path, float sweep, bool pie); +void lv_vg_lite_path_append_path(lv_vg_lite_path_t * dest, const lv_vg_lite_path_t * src); + uint8_t lv_vg_lite_vlc_op_arg_len(uint8_t vlc_op); uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.c index 044417207..b8429f0f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.c @@ -19,7 +19,7 @@ * TYPEDEFS **********************/ -struct _lv_vg_lite_pending_t { +struct lv_vg_lite_pending_t { lv_array_t objs; lv_vg_lite_pending_free_cb_t free_cb; void * user_data; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.h index 8def9dcf5..bf439b74d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_pending.h @@ -26,7 +26,7 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct _lv_vg_lite_pending_t lv_vg_lite_pending_t; +typedef struct lv_vg_lite_pending_t lv_vg_lite_pending_t; typedef void (*lv_vg_lite_pending_free_cb_t)(void * obj, void * user_data); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.c new file mode 100644 index 000000000..1b8a20248 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.c @@ -0,0 +1,310 @@ +/** + * @file lv_vg_lite_stroke.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_vg_lite_stroke.h" + +#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC + +#include "lv_vg_lite_path.h" +#include "lv_draw_vg_lite_type.h" +#include "lv_vg_lite_math.h" +#include "../lv_draw_vector_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + /* stroke path */ + lv_vg_lite_path_t * path; + + /* stroke parameters */ + float width; + lv_vector_stroke_cap_t cap; + lv_vector_stroke_join_t join; + uint16_t miter_limit; + lv_array_t dash_pattern; +} stroke_item_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static bool stroke_create_cb(stroke_item_t * item, void * user_data); +static void stroke_free_cb(stroke_item_t * item, void * user_data); +static lv_cache_compare_res_t stroke_compare_cb(const stroke_item_t * lhs, const stroke_item_t * rhs); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_vg_lite_stroke_init(struct lv_draw_vg_lite_unit_t * unit, uint32_t cache_cnt) +{ + LV_ASSERT_NULL(unit); + + const lv_cache_ops_t ops = { + .compare_cb = (lv_cache_compare_cb_t)stroke_compare_cb, + .create_cb = (lv_cache_create_cb_t)stroke_create_cb, + .free_cb = (lv_cache_free_cb_t)stroke_free_cb, + }; + + unit->stroke_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(stroke_item_t), cache_cnt, ops); + lv_cache_set_name(unit->stroke_cache, "VG_STROKE"); +} + +void lv_vg_lite_stroke_deinit(struct lv_draw_vg_lite_unit_t * unit) +{ + LV_ASSERT_NULL(unit); + LV_ASSERT_NULL(unit->stroke_cache); + lv_cache_destroy(unit->stroke_cache, NULL); + unit->stroke_cache = NULL; +} + +static vg_lite_cap_style_t lv_stroke_cap_to_vg(lv_vector_stroke_cap_t cap) +{ + switch(cap) { + case LV_VECTOR_STROKE_CAP_SQUARE: + return VG_LITE_CAP_SQUARE; + case LV_VECTOR_STROKE_CAP_ROUND: + return VG_LITE_CAP_ROUND; + case LV_VECTOR_STROKE_CAP_BUTT: + return VG_LITE_CAP_BUTT; + default: + return VG_LITE_CAP_SQUARE; + } +} + +static vg_lite_join_style_t lv_stroke_join_to_vg(lv_vector_stroke_join_t join) +{ + switch(join) { + case LV_VECTOR_STROKE_JOIN_BEVEL: + return VG_LITE_JOIN_BEVEL; + case LV_VECTOR_STROKE_JOIN_ROUND: + return VG_LITE_JOIN_ROUND; + case LV_VECTOR_STROKE_JOIN_MITER: + return VG_LITE_JOIN_MITER; + default: + return VG_LITE_JOIN_BEVEL; + } +} + +lv_cache_entry_t * lv_vg_lite_stroke_get(struct lv_draw_vg_lite_unit_t * unit, + struct lv_vg_lite_path_t * path, + const lv_vector_stroke_dsc_t * dsc) +{ + LV_ASSERT_NULL(unit); + LV_ASSERT_NULL(path); + LV_ASSERT_NULL(dsc); + + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(path); + + if(vg_path->format != VG_LITE_FP32) { + LV_LOG_ERROR("only support VG_LITE_FP32 format"); + return NULL; + } + + /* prepare search key */ + stroke_item_t search_key; + lv_memzero(&search_key, sizeof(search_key)); + search_key.cap = dsc->cap; + search_key.join = dsc->join; + search_key.width = dsc->width; + search_key.miter_limit = dsc->miter_limit; + + /* A one-time read-only array that only copies the pointer but not the content */ + search_key.dash_pattern = dsc->dash_pattern; + search_key.path = path; + + lv_cache_entry_t * cache_node_entry = lv_cache_acquire(unit->stroke_cache, &search_key, &search_key); + if(cache_node_entry) { + return cache_node_entry; + } + + cache_node_entry = lv_cache_acquire_or_create(unit->stroke_cache, &search_key, &search_key); + if(cache_node_entry == NULL) { + LV_LOG_ERROR("stroke cache creating failed"); + return NULL; + } + + return cache_node_entry; +} + +struct lv_vg_lite_path_t * lv_vg_lite_stroke_get_path(lv_cache_entry_t * cache_entry) +{ + LV_ASSERT_NULL(cache_entry); + + stroke_item_t * stroke_item = lv_cache_entry_get_data(cache_entry); + LV_ASSERT_NULL(stroke_item); + return stroke_item->path; +} + +void lv_vg_lite_stroke_drop(struct lv_draw_vg_lite_unit_t * unit, + lv_cache_entry_t * cache_entry) +{ + LV_ASSERT_NULL(unit); + LV_ASSERT_NULL(cache_entry); + lv_cache_release(unit->stroke_cache, cache_entry, NULL); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool stroke_create_cb(stroke_item_t * item, void * user_data) +{ + LV_ASSERT_NULL(item); + + stroke_item_t * src = user_data; + LV_ASSERT_NULL(src); + + lv_memzero(item, sizeof(stroke_item_t)); + + /* copy path */ + item->path = lv_vg_lite_path_create(VG_LITE_FP32); + lv_vg_lite_path_append_path(item->path, src->path); + + /* copy parameters */ + item->cap = src->cap; + item->join = src->join; + item->width = src->width; + item->miter_limit = src->miter_limit; + + /* copy dash pattern */ + uint32_t size = lv_array_size(&src->dash_pattern); + if(size) { + lv_array_init(&item->dash_pattern, size, sizeof(float)); + lv_array_copy(&item->dash_pattern, &src->dash_pattern); + } + + /* update parameters */ + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(item->path); + LV_VG_LITE_CHECK_ERROR(vg_lite_set_path_type(vg_path, VG_LITE_DRAW_STROKE_PATH)); + + vg_lite_error_t error = vg_lite_set_stroke( + vg_path, + lv_stroke_cap_to_vg(item->cap), + lv_stroke_join_to_vg(item->join), + item->width, + item->miter_limit, + lv_array_front(&item->dash_pattern), + size, + item->width / 2, + 0); + + if(error != VG_LITE_SUCCESS) { + LV_LOG_ERROR("vg_lite_set_stroke failed: %d(%s)", (int)error, lv_vg_lite_error_string(error)); + stroke_free_cb(item, NULL); + return false; + } + + const vg_lite_pointer * ori_path = vg_path->path; + const vg_lite_uint32_t ori_path_length = vg_path->path_length; + + LV_PROFILER_BEGIN_TAG("vg_lite_update_stroke"); + error = vg_lite_update_stroke(vg_path); + LV_PROFILER_END_TAG("vg_lite_update_stroke"); + + /* check if path is changed */ + LV_ASSERT_MSG(vg_path->path_length == ori_path_length, "vg_path->path_length should not change"); + LV_ASSERT_MSG(vg_path->path == ori_path, "vg_path->path should not change"); + + if(error != VG_LITE_SUCCESS) { + LV_LOG_ERROR("vg_lite_update_stroke failed: %d(%s)", (int)error, lv_vg_lite_error_string(error)); + stroke_free_cb(item, NULL); + return false; + } + + return true; +} + +static void stroke_free_cb(stroke_item_t * item, void * user_data) +{ + LV_UNUSED(user_data); + LV_ASSERT_NULL(item); + + lv_array_deinit(&item->dash_pattern); + lv_vg_lite_path_destroy(item->path); + lv_memzero(item, sizeof(stroke_item_t)); +} + +static lv_cache_compare_res_t path_compare(const vg_lite_path_t * lhs, const vg_lite_path_t * rhs) +{ + LV_VG_LITE_ASSERT_PATH(lhs); + LV_VG_LITE_ASSERT_PATH(rhs); + + LV_ASSERT(lhs->format == VG_LITE_FP32); + LV_ASSERT(rhs->format == VG_LITE_FP32); + + if(lhs->path_length != rhs->path_length) { + return lhs->path_length > rhs->path_length ? 1 : -1; + } + + int cmp_res = lv_memcmp(lhs->path, rhs->path, lhs->path_length); + if(cmp_res != 0) { + return cmp_res > 0 ? 1 : -1; + } + + return 0; +} + +static lv_cache_compare_res_t stroke_compare_cb(const stroke_item_t * lhs, const stroke_item_t * rhs) +{ + if(lhs->width != lhs->width) { + return lhs->width > lhs->width ? 1 : -1; + } + + if(lhs->cap != rhs->cap) { + return lhs->cap > rhs->cap ? 1 : -1; + } + + if(lhs->join != rhs->join) { + return lhs->join > rhs->join ? 1 : -1; + } + + if(lhs->miter_limit != rhs->miter_limit) { + return lhs->miter_limit > rhs->miter_limit ? 1 : -1; + } + + uint32_t lhs_dash_pattern_size = lv_array_size(&lhs->dash_pattern); + uint32_t rhs_dash_pattern_size = lv_array_size(&rhs->dash_pattern); + + if(lhs_dash_pattern_size != rhs_dash_pattern_size) { + return lhs_dash_pattern_size > rhs_dash_pattern_size ? 1 : -1; + } + + if(lhs_dash_pattern_size > 0 && rhs_dash_pattern_size > 0) { + LV_ASSERT(lhs->dash_pattern.element_size == sizeof(float)); + LV_ASSERT(rhs->dash_pattern.element_size == sizeof(float)); + + const float * lhs_dash_pattern = lv_array_front(&lhs->dash_pattern); + const float * rhs_dash_pattern = lv_array_front(&rhs->dash_pattern); + + /* compare dash pattern */ + int cmp_res = lv_memcmp(lhs_dash_pattern, rhs_dash_pattern, lhs_dash_pattern_size * sizeof(float)); + if(cmp_res != 0) { + return cmp_res > 0 ? 1 : -1; + } + } + + return path_compare(lv_vg_lite_path_get_path(lhs->path), lv_vg_lite_path_get_path(rhs->path)); +} + +#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.h new file mode 100644 index 000000000..4a0602d62 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_stroke.h @@ -0,0 +1,84 @@ +/** + * @file lv_vg_lite_stroke.h + * + */ + +#ifndef LV_VG_LITE_STROKE_H +#define LV_VG_LITE_STROKE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_vg_lite_utils.h" + +#if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_vg_lite_path_t; + +struct lv_draw_vg_lite_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the stroke module + * @param unit pointer to the unit + */ +void lv_vg_lite_stroke_init(struct lv_draw_vg_lite_unit_t * unit, uint32_t cache_cnt); + +/** + * Deinitialize the stroke module + * @param unit pointer to the unit + */ +void lv_vg_lite_stroke_deinit(struct lv_draw_vg_lite_unit_t * unit); + +/** + * Get the stroke cache entry + * @param unit pointer to the unit + * @param path pointer to the path + * @param dsc pointer to the stroke descriptor + * @return pointer to the stroke cache entry + */ +lv_cache_entry_t * lv_vg_lite_stroke_get(struct lv_draw_vg_lite_unit_t * unit, + struct lv_vg_lite_path_t * path, + const lv_vector_stroke_dsc_t * dsc); + +/** + * Get the path of a stroke + * @param cache_entry pointer to the stroke cache entry + * @return pointer to the path + */ +struct lv_vg_lite_path_t * lv_vg_lite_stroke_get_path(lv_cache_entry_t * cache_entry); + +/** + * Drop the stroke cache entry + * @param unit pointer to the unit + * @param stroke pointer to the stroke + */ +void lv_vg_lite_stroke_drop(struct lv_draw_vg_lite_unit_t * unit, lv_cache_entry_t * cache_entry); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_VG_LITE_STROKE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c index cb212fb63..e2b763692 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ +#include "../lv_image_decoder_private.h" #include "lv_vg_lite_utils.h" #if LV_USE_DRAW_VG_LITE @@ -17,6 +18,7 @@ #include "lv_vg_lite_grad.h" #include "lv_draw_vg_lite_type.h" #include +#include /********************* * DEFINES @@ -90,7 +92,7 @@ void lv_vg_lite_dump_info(void) vg_lite_uint32_t mem_avail = 0; vg_lite_get_mem_size(&mem_avail); - LV_LOG_USER("Memory Avaliable: %" LV_PRId32 " Bytes", (uint32_t)mem_avail); + LV_LOG_USER("Memory Available: %" LV_PRId32 " Bytes", (uint32_t)mem_avail); } const char * lv_vg_lite_error_string(vg_lite_error_t error) @@ -162,6 +164,7 @@ const char * lv_vg_lite_feature_string(vg_lite_feature_t feature) FEATURE_ENUM_TO_STRING(YUV_TILED_INPUT); FEATURE_ENUM_TO_STRING(AYUV_INPUT); FEATURE_ENUM_TO_STRING(16PIXELS_ALIGN); + FEATURE_ENUM_TO_STRING(DEC_COMPRESS_2_0); default: break; } @@ -274,15 +277,102 @@ void lv_vg_lite_path_dump_info(const vg_lite_path_t * path) LV_ASSERT(len > 0); - LV_LOG_USER("address: %p", path->path); + LV_LOG_USER("address: %p", (void *)path->path); LV_LOG_USER("length: %d", (int)len); LV_LOG_USER("bonding box: (%0.2f, %0.2f) - (%0.2f, %0.2f)", path->bounding_box[0], path->bounding_box[1], path->bounding_box[2], path->bounding_box[3]); LV_LOG_USER("format: %d", (int)path->format); LV_LOG_USER("quality: %d", (int)path->quality); + LV_LOG_USER("path_changed: %d", (int)path->path_changed); + LV_LOG_USER("pdata_internal: %d", (int)path->pdata_internal); + LV_LOG_USER("type: %d", (int)path->path_type); + LV_LOG_USER("add_end: %d", (int)path->add_end); lv_vg_lite_path_for_each_data(path, path_data_print_cb, NULL); + + if(path->stroke) { + LV_LOG_USER("stroke_path: %p", (void *)path->stroke_path); + LV_LOG_USER("stroke_size: %d", (int)path->stroke_size); + LV_LOG_USER("stroke_color: 0x%X", (int)path->stroke_color); + lv_vg_lite_stroke_dump_info(path->stroke); + } +} + +void lv_vg_lite_stroke_dump_info(const vg_lite_stroke_t * stroke) +{ + LV_ASSERT(stroke != NULL); + LV_LOG_USER("stroke: %p", (void *)stroke); + + /* Stroke parameters */ + LV_LOG_USER("cap_style: 0x%X", (int)stroke->cap_style); + LV_LOG_USER("join_style: 0x%X", (int)stroke->join_style); + LV_LOG_USER("line_width: %f", stroke->line_width); + LV_LOG_USER("miter_limit: %f", stroke->miter_limit); + + LV_LOG_USER("dash_pattern: %p", (void *)stroke->dash_pattern); + LV_LOG_USER("pattern_count: %d", (int)stroke->pattern_count); + if(stroke->dash_pattern) { + for(int i = 0; i < (int)stroke->pattern_count; i++) { + LV_LOG_USER("dash_pattern[%d]: %f", i, stroke->dash_pattern[i]); + } + } + + LV_LOG_USER("dash_phase: %f", stroke->dash_phase); + LV_LOG_USER("dash_length: %f", stroke->dash_length); + LV_LOG_USER("dash_index: %d", (int)stroke->dash_index); + LV_LOG_USER("half_width: %f", stroke->half_width); + + /* Total length of stroke dash patterns. */ + LV_LOG_USER("pattern_length: %f", stroke->pattern_length); + + /* For fast checking. */ + LV_LOG_USER("miter_square: %f", stroke->miter_square); + + /* Temp storage of stroke subPath. */ + LV_LOG_USER("path_points: %p", (void *)stroke->path_points); + LV_LOG_USER("path_end: %p", (void *)stroke->path_end); + LV_LOG_USER("point_count: %d", (int)stroke->point_count); + + LV_LOG_USER("left_point: %p", (void *)stroke->left_point); + LV_LOG_USER("right_point: %p", (void *)stroke->right_point); + LV_LOG_USER("stroke_points: %p", (void *)stroke->stroke_points); + LV_LOG_USER("stroke_end: %p", (void *)stroke->stroke_end); + LV_LOG_USER("stroke_count: %d", (int)stroke->stroke_count); + + /* Divide stroke path according to move or move_rel for avoiding implicit closure. */ + LV_LOG_USER("path_list_divide: %p", (void *)stroke->path_list_divide); + + /* pointer to current divided path data. */ + LV_LOG_USER("cur_list: %p", (void *)stroke->cur_list); + + /* Flag that add end_path in driver. */ + LV_LOG_USER("add_end: %d", (int)stroke->add_end); + LV_LOG_USER("dash_reset: %d", (int)stroke->dash_reset); + + /* Sub path list. */ + LV_LOG_USER("stroke_paths: %p", (void *)stroke->stroke_paths); + + /* Last sub path. */ + LV_LOG_USER("last_stroke: %p", (void *)stroke->last_stroke); + + /* Swing area handling. */ + LV_LOG_USER("swing_handling: %d", (int)stroke->swing_handling); + LV_LOG_USER("swing_deltax: %f", stroke->swing_deltax); + LV_LOG_USER("swing_deltay: %f", stroke->swing_deltay); + LV_LOG_USER("swing_start: %p", (void *)stroke->swing_start); + LV_LOG_USER("swing_stroke: %p", (void *)stroke->swing_stroke); + LV_LOG_USER("swing_length: %f", stroke->swing_length); + LV_LOG_USER("swing_centlen: %f", stroke->swing_centlen); + LV_LOG_USER("swing_count: %d", (int)stroke->swing_count); + LV_LOG_USER("need_swing: %d", (int)stroke->need_swing); + LV_LOG_USER("swing_ccw: %d", (int)stroke->swing_ccw); + + LV_LOG_USER("stroke_length: %f", stroke->stroke_length); + LV_LOG_USER("stroke_size: %d", (int)stroke->stroke_size); + + LV_LOG_USER("fattened: %d", (int)stroke->fattened); + LV_LOG_USER("closed: %d", (int)stroke->closed); } void lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer) @@ -397,7 +487,7 @@ vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf) return VG_LITE_NV12; default: - LV_LOG_ERROR("unsupport color format: %d", cf); + LV_LOG_ERROR("unsupported color format: %d", cf); break; } @@ -488,7 +578,7 @@ void lv_vg_lite_buffer_format_bytes( *mul = 3; break; default: - LV_LOG_ERROR("unsupport color format: 0x%" PRIx32, (uint32_t)format); + LV_LOG_ERROR("unsupported color format: 0x%" PRIx32, (uint32_t)format); LV_ASSERT(false); break; } @@ -500,7 +590,7 @@ uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_fo uint32_t mul, div, align; lv_vg_lite_buffer_format_bytes(color_format, &mul, &div, &align); - return LV_VG_LITE_ALIGN((w * mul / div), align); + return LV_VG_LITE_ALIGN(((w * mul + div - 1) / div), align); } uint32_t lv_vg_lite_width_align(uint32_t w) @@ -517,6 +607,7 @@ void lv_vg_lite_buffer_init( const void * ptr, int32_t width, int32_t height, + uint32_t stride, vg_lite_buffer_format_t format, bool tiled) { @@ -539,8 +630,13 @@ void lv_vg_lite_buffer_init( buffer->transparency_mode = VG_LITE_IMAGE_OPAQUE; buffer->width = width; buffer->height = height; - lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align); - buffer->stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align); + if(stride == LV_STRIDE_AUTO) { + lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align); + buffer->stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align); + } + else { + buffer->stride = stride; + } if(format == VG_LITE_NV12) { lv_yuv_buf_t * frame_p = (lv_yuv_buf_t *)ptr; @@ -567,6 +663,7 @@ void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_bu const uint8_t * ptr = draw_buf->data; int32_t width = draw_buf->header.w; int32_t height = draw_buf->header.h; + uint32_t stride = draw_buf->header.stride; vg_lite_buffer_format_t format = lv_vg_lite_vg_fmt(draw_buf->header.cf); if(LV_COLOR_FORMAT_IS_INDEXED(draw_buf->header.cf)) { @@ -578,7 +675,7 @@ void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_bu width = lv_vg_lite_width_align(width); - lv_vg_lite_buffer_init(buffer, ptr, width, height, format, false); + lv_vg_lite_buffer_init(buffer, ptr, width, height, stride, format, false); /* Alpha image need to be multiplied by color */ if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(draw_buf->header.cf)) { @@ -629,6 +726,7 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds args.stride_align = true; args.use_indexed = true; args.no_cache = no_cache; + args.flush_cache = true; lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args); if(res != LV_RESULT_OK) { @@ -660,13 +758,13 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds return true; } -void lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit) +void lv_vg_lite_image_dsc_init(struct lv_draw_vg_lite_unit_t * unit) { unit->image_dsc_pending = lv_vg_lite_pending_create(sizeof(lv_image_decoder_dsc_t), 4); lv_vg_lite_pending_set_free_cb(unit->image_dsc_pending, image_dsc_free_cb, NULL); } -void lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit) +void lv_vg_lite_image_dsc_deinit(struct lv_draw_vg_lite_unit_t * unit) { lv_vg_lite_pending_destroy(unit->image_dsc_pending); unit->image_dsc_pending = NULL; @@ -680,6 +778,15 @@ void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area) rect->height = lv_area_get_height(area); } +#if LV_USE_MATRIX + +void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src) +{ + lv_memcpy(dest, src, sizeof(lv_matrix_t)); +} + +#endif + uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format) { uint32_t size = 0; @@ -704,7 +811,7 @@ uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format) vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul) { - if(pre_mul && opa < LV_OPA_MAX) { + if(pre_mul && opa < LV_OPA_COVER) { color.red = LV_UDIV255(color.red * opa); color.green = LV_UDIV255(color.green * opa); color.blue = LV_UDIV255(color.blue * opa); @@ -714,7 +821,7 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul) vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) { - if(lv_vg_lite_support_blend_normal()) { + if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ return VG_LITE_BLEND_NORMAL_LVGL; @@ -735,6 +842,9 @@ vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ + if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { + return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER; + } return VG_LITE_BLEND_SRC_OVER; case LV_BLEND_MODE_ADDITIVE: /**< Add the respective color channels*/ @@ -887,10 +997,26 @@ bool lv_vg_lite_path_check(const vg_lite_path_t * path) return false; } - uint8_t end_op_code = VLC_GET_OP_CODE(end - fmt_len); - if(end_op_code != VLC_OP_END) { - LV_LOG_ERROR("%d (%s) -> is NOT VLC_OP_END", end_op_code, lv_vg_lite_vlc_op_string(end_op_code)); - return false; + switch(path->path_type) { + case VG_LITE_DRAW_ZERO: + case VG_LITE_DRAW_FILL_PATH: + case VG_LITE_DRAW_FILL_STROKE_PATH: { + /* Check end op code */ + uint8_t end_op_code = VLC_GET_OP_CODE(end - fmt_len); + if(end_op_code != VLC_OP_END) { + LV_LOG_ERROR("%d (%s) -> is NOT VLC_OP_END", end_op_code, lv_vg_lite_vlc_op_string(end_op_code)); + return false; + } + } + break; + + case VG_LITE_DRAW_STROKE_PATH: + /* No need to check stroke path end */ + break; + + default: + LV_LOG_ERROR("path type(%d) is invalid", (int)path->path_type); + return false; } return true; @@ -915,7 +1041,15 @@ bool lv_vg_lite_matrix_check(const vg_lite_matrix_t * matrix) bool lv_vg_lite_support_blend_normal(void) { - return vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT); + if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { + return true; + } + + if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { + return true; + } + + return false; } bool lv_vg_lite_16px_align(void) @@ -944,11 +1078,6 @@ void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_ lv_memcpy(matrix, &temp, sizeof(temp)); } -void lv_vg_lite_matrix_flip_y(vg_lite_matrix_t * matrix) -{ - matrix->m[1][1] = -matrix->m[1][1]; -} - bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix) { vg_lite_float_t det00, det01, det02; @@ -1008,27 +1137,43 @@ lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * ma { lv_point_precise_t p; const vg_lite_float_t (*m)[3] = matrix->m; - p.x = (lv_value_precise_t)(point->x * m[0][0] + point->y * m[0][1] + m[0][2]); - p.y = (lv_value_precise_t)(point->x * m[1][0] + point->y * m[1][1] + m[1][2]); + p.x = (lv_value_precise_t)roundf(point->x * m[0][0] + point->y * m[0][1] + m[0][2]); + p.y = (lv_value_precise_t)roundf(point->x * m[1][0] + point->y * m[1][1] + m[1][2]); return p; } void lv_vg_lite_set_scissor_area(const lv_area_t * area) { +#if VGLITE_RELEASE_VERSION <= VGLITE_MAKE_VERSION(4,0,57) + /** + * In the new version of VG-Lite, vg_lite_set_scissor no longer needs to call vg_lite_enable_scissor and + * vg_lite_disable_scissor APIs. + * + * Original description in the manual: + * Description: This is a legacy scissor API function that can be used to set and enable a single scissor rectangle + * for the render target. This scissor API is supported by a different hardware mechanism other than the mask layer, + * and it is not enabled/disabled by vg_lite_enable_scissor and vg_lite_disable_scissor APIs. + */ LV_VG_LITE_CHECK_ERROR(vg_lite_enable_scissor()); +#endif LV_VG_LITE_CHECK_ERROR(vg_lite_set_scissor( area->x1, area->y1, - lv_area_get_width(area), - lv_area_get_height(area))); + area->x2 + 1, + area->y2 + 1)); } void lv_vg_lite_disable_scissor(void) { - LV_VG_LITE_CHECK_ERROR(vg_lite_disable_scissor()); + /* Restore full screen scissor */ + LV_VG_LITE_CHECK_ERROR(vg_lite_set_scissor( + 0, + 0, + LV_HOR_RES, + LV_VER_RES)); } -void lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u) +void lv_vg_lite_flush(struct lv_draw_vg_lite_unit_t * u) { LV_ASSERT_NULL(u); LV_PROFILER_BEGIN; @@ -1056,7 +1201,7 @@ void lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u) LV_PROFILER_END; } -void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u) +void lv_vg_lite_finish(struct lv_draw_vg_lite_unit_t * u) { LV_ASSERT_NULL(u); LV_PROFILER_BEGIN; @@ -1064,7 +1209,9 @@ void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u) LV_VG_LITE_CHECK_ERROR(vg_lite_finish()); /* Clear all gradient caches reference */ - lv_vg_lite_pending_remove_all(u->grad_pending); + if(u->grad_pending) { + lv_vg_lite_pending_remove_all(u->grad_pending); + } /* Clear image decoder dsc reference */ lv_vg_lite_pending_remove_all(u->image_dsc_pending); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h index c50d600c5..62e65620d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/vg_lite/lv_vg_lite_utils.h @@ -71,7 +71,7 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_draw_vg_lite_unit_t; +struct lv_draw_vg_lite_unit_t; /********************** * GLOBAL PROTOTYPES @@ -91,6 +91,8 @@ const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op); void lv_vg_lite_path_dump_info(const vg_lite_path_t * path); +void lv_vg_lite_stroke_dump_info(const vg_lite_stroke_t * stroke); + void lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer); void lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix); @@ -118,6 +120,7 @@ void lv_vg_lite_buffer_init( const void * ptr, int32_t width, int32_t height, + uint32_t stride, vg_lite_buffer_format_t format, bool tiled); @@ -130,9 +133,9 @@ void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, bool no_cache); -void lv_vg_lite_image_dsc_init(struct _lv_draw_vg_lite_unit_t * unit); +void lv_vg_lite_image_dsc_init(struct lv_draw_vg_lite_unit_t * unit); -void lv_vg_lite_image_dsc_deinit(struct _lv_draw_vg_lite_unit_t * unit); +void lv_vg_lite_image_dsc_deinit(struct lv_draw_vg_lite_unit_t * unit); vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode); @@ -142,6 +145,12 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul); void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area); +#if LV_USE_MATRIX + +void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src); + +#endif + /* Param checker */ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src); @@ -158,8 +167,6 @@ bool lv_vg_lite_16px_align(void); void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult); -void lv_vg_lite_matrix_flip_y(vg_lite_matrix_t * matrix); - bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix); lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix, const lv_point_precise_t * point); @@ -168,9 +175,9 @@ void lv_vg_lite_set_scissor_area(const lv_area_t * area); void lv_vg_lite_disable_scissor(void); -void lv_vg_lite_flush(struct _lv_draw_vg_lite_unit_t * u); +void lv_vg_lite_flush(struct lv_draw_vg_lite_unit_t * u); -void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u); +void lv_vg_lite_finish(struct lv_draw_vg_lite_unit_t * u); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.c b/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.c index faa2212bf..29e0168d9 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.c @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #include #include @@ -91,6 +93,8 @@ static int drm_setup_buffers(drm_dev_t * drm_dev); static void drm_flush_wait(lv_display_t * drm_dev); static void drm_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static uint32_t tick_get_cb(void); + /********************** * STATIC VARIABLES **********************/ @@ -108,6 +112,8 @@ static void drm_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_ lv_display_t * lv_linux_drm_create(void) { + lv_tick_set_cb(tick_get_cb); + drm_dev_t * drm_dev = lv_malloc_zeroed(sizeof(drm_dev_t)); LV_ASSERT_MALLOC(drm_dev); if(drm_dev == NULL) return NULL; @@ -152,9 +158,12 @@ void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t conne int32_t width = drm_dev->mmWidth; size_t buf_size = LV_MIN(drm_dev->drm_bufs[1].size, drm_dev->drm_bufs[0].size); + /* Resolution must be set first because if the screen is smaller than the size passed + * to lv_display_create then the buffers aren't big enough for LV_DISPLAY_RENDER_MODE_DIRECT. + */ + lv_display_set_resolution(disp, hor_res, ver_res); lv_display_set_buffers(disp, drm_dev->drm_bufs[1].map, drm_dev->drm_bufs[0].map, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); - lv_display_set_resolution(disp, hor_res, ver_res); if(width) { lv_display_set_dpi(disp, DIV_ROUND_UP(hor_res * 25400, width * 1000)); @@ -832,4 +841,12 @@ static void drm_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_ } } +static uint32_t tick_get_cb(void) +{ + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + uint64_t time_ms = t.tv_sec * 1000 + (t.tv_nsec / 1000000); + return time_ms; +} + #endif /*LV_USE_LINUX_DRM*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.h index a75d19586..ee32466ca 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/drm/lv_linux_drm.h @@ -1,5 +1,5 @@ /** - * @file lv_linux_drm_h + * @file lv_linux_drm.h * */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.c b/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.c index cf529a25d..076ada41a 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #if LV_LINUX_FBDEV_BSD #include @@ -26,6 +26,9 @@ #include #endif /* LV_LINUX_FBDEV_BSD */ +#include "../../../display/lv_display_private.h" +#include "../../../draw/sw/lv_draw_sw.h" + /********************* * DEFINES *********************/ @@ -57,6 +60,8 @@ typedef struct { struct fb_fix_screeninfo finfo; #endif /* LV_LINUX_FBDEV_BSD */ char * fbp; + uint8_t * rotated_buf; + size_t rotated_buf_size; long int screensize; int fbfd; bool force_refresh; @@ -91,11 +96,7 @@ static uint32_t tick_get_cb(void); lv_display_t * lv_linux_fbdev_create(void) { - static bool inited = false; - if(!inited) { - lv_tick_set_cb(tick_get_cb); - inited = true; - } + lv_tick_set_cb(tick_get_cb); lv_linux_fb_t * dsc = lv_malloc_zeroed(sizeof(lv_linux_fb_t)); LV_ASSERT_MALLOC(dsc); @@ -228,8 +229,8 @@ void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file) draw_buf_2 = malloc(draw_buf_size); } - lv_display_set_buffers(disp, draw_buf, draw_buf_2, draw_buf_size, LV_LINUX_FBDEV_RENDER_MODE); lv_display_set_resolution(disp, hor_res, ver_res); + lv_display_set_buffers(disp, draw_buf, draw_buf_2, draw_buf_size, LV_LINUX_FBDEV_RENDER_MODE); if(width > 0) { lv_display_set_dpi(disp, DIV_ROUND_UP(hor_res * 254, width * 10)); @@ -253,28 +254,83 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo { lv_linux_fb_t * dsc = lv_display_get_driver_data(disp); - if(dsc->fbp == NULL || - area->x2 < 0 || area->y2 < 0 || - area->x1 > (int32_t)dsc->vinfo.xres - 1 || area->y1 > (int32_t)dsc->vinfo.yres - 1) { + if(dsc->fbp == NULL) { lv_display_flush_ready(disp); return; } int32_t w = lv_area_get_width(area); - uint32_t px_size = lv_color_format_get_size(lv_display_get_color_format(disp)); - uint32_t color_pos = (area->x1 + dsc->vinfo.xoffset) * px_size + area->y1 * dsc->finfo.line_length; - uint32_t fb_pos = color_pos + dsc->vinfo.yoffset * dsc->finfo.line_length; + int32_t h = lv_area_get_height(area); + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t px_size = lv_color_format_get_size(cf); + + lv_area_t rotated_area; + lv_display_rotation_t rotation = lv_display_get_rotation(disp); + + /* Not all framebuffer kernel drivers support hardware rotation, so we need to handle it in software here */ + if(rotation != LV_DISPLAY_ROTATION_0 && LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) { + /* (Re)allocate temporary buffer if needed */ + size_t buf_size = w * h * px_size; + if(!dsc->rotated_buf || dsc->rotated_buf_size != buf_size) { + dsc->rotated_buf = realloc(dsc->rotated_buf, buf_size); + dsc->rotated_buf_size = buf_size; + } + + /* Rotate the pixel buffer */ + uint32_t w_stride = lv_draw_buf_width_to_stride(w, cf); + uint32_t h_stride = lv_draw_buf_width_to_stride(h, cf); + + switch(rotation) { + case LV_DISPLAY_ROTATION_0: + break; + case LV_DISPLAY_ROTATION_90: + lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf); + break; + case LV_DISPLAY_ROTATION_180: + lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, w_stride, rotation, cf); + break; + case LV_DISPLAY_ROTATION_270: + lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf); + break; + } + color_p = dsc->rotated_buf; + + /* Rotate the area */ + rotated_area = *area; + lv_display_rotate_area(disp, &rotated_area); + area = &rotated_area; + + if(rotation != LV_DISPLAY_ROTATION_180) { + w = lv_area_get_width(area); + h = lv_area_get_height(area); + } + } + + /* Ensure that we're within the framebuffer's bounds */ + if(area->x2 < 0 || area->y2 < 0 || area->x1 > (int32_t)dsc->vinfo.xres - 1 || area->y1 > (int32_t)dsc->vinfo.yres - 1) { + lv_display_flush_ready(disp); + return; + } + + uint32_t fb_pos = + (area->x1 + dsc->vinfo.xoffset) * px_size + + (area->y1 + dsc->vinfo.yoffset) * dsc->finfo.line_length; uint8_t * fbp = (uint8_t *)dsc->fbp; int32_t y; if(LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_DIRECT) { + uint32_t color_pos = + area->x1 * px_size + + area->y1 * disp->hor_res * px_size; + for(y = area->y1; y <= area->y2; y++) { lv_memcpy(&fbp[fb_pos], &color_p[color_pos], w * px_size); fb_pos += dsc->finfo.line_length; - color_pos += dsc->finfo.line_length; + color_pos += disp->hor_res * px_size; } } else { + w = lv_area_get_width(area); for(y = area->y1; y <= area->y2; y++) { lv_memcpy(&fbp[fb_pos], color_p, w * px_size); fb_pos += dsc->finfo.line_length; @@ -294,10 +350,9 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo static uint32_t tick_get_cb(void) { - struct timeval tv_now; - gettimeofday(&tv_now, NULL); - uint64_t time_ms; - time_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000; + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + uint64_t time_ms = t.tv_sec * 1000 + (t.tv_nsec / 1000000); return time_ms; } diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.h index c14e9734c..2c41aec19 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/fb/lv_linux_fbdev.h @@ -1,10 +1,10 @@ /** - * @file lv_linux_fb_dev_h + * @file lv_linux_fbdev.h * */ -#ifndef LV_LINUX_FB_DEV_H -#define LV_LINUX_FB_DEV_H +#ifndef LV_LINUX_FBDEV_H +#define LV_LINUX_FBDEV_H #ifdef __cplusplus extern "C" { @@ -49,4 +49,4 @@ void lv_linux_fbdev_set_force_refresh(lv_display_t * disp, bool enabled); } /* extern "C" */ #endif -#endif /* LV_LINUX_FB_DEV_H */ +#endif /* LV_LINUX_FBDEV_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/ili9341/lv_ili9341.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/ili9341/lv_ili9341.h index c93fcba03..78e90306b 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/ili9341/lv_ili9341.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/ili9341/lv_ili9341.h @@ -1,5 +1,5 @@ -/* - * lv_ili9341.h +/** + * @file lv_ili9341.h * * This driver is just a wrapper around the generic MIPI compatible LCD controller driver * diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.c b/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.c index 46bcf1b5a..e27e4c860 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.c @@ -295,7 +295,7 @@ static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation break; case LV_DISPLAY_ROTATION_90: set_swap_xy(drv, !drv->swap_xy); - set_mirror(drv, !drv->mirror_x, drv->mirror_y); + set_mirror(drv, drv->mirror_x, !drv->mirror_y); break; case LV_DISPLAY_ROTATION_180: set_swap_xy(drv, drv->swap_xy); @@ -303,7 +303,7 @@ static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation break; case LV_DISPLAY_ROTATION_270: set_swap_xy(drv, !drv->swap_xy); - set_mirror(drv, drv->mirror_x, !drv->mirror_y); + set_mirror(drv, !drv->mirror_x, drv->mirror_y); break; } send_cmd(drv, LV_LCD_CMD_SET_ADDRESS_MODE, (uint8_t[]) { diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.h index ae5c0ef14..8daa5e044 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/lcd/lv_lcd_generic_mipi.h @@ -1,5 +1,5 @@ -/* - * lv_lcd_generic_mipi.h +/** + * @file lv_lcd_generic_mipi.h * * Generic driver for controllers adhering to the MIPI DBI/DCS specification * diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c b/lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c new file mode 100644 index 000000000..15b67846d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.c @@ -0,0 +1,360 @@ +/** + * @file lv_renesas_glcdc.c + * + */ + +/********************* + *PLATFORM ABSTRACTION + *********************/ + +#ifdef _RENESAS_RA_ + #define USE_FREE_RTOS (BSP_CFG_RTOS == 2) +#else // RX with SMC code generation + #ifndef _RENESAS_RX_ + #define _RENESAS_RX_ 1 + #endif + #define USE_FREE_RTOS 1 + #define DISPLAY_HSIZE_INPUT0 LCD_CH0_IN_GR2_HSIZE + #define DISPLAY_VSIZE_INPUT0 LCD_CH0_IN_GR2_VSIZE +#endif /*_RENESAS_RA_*/ + +/********************* + * INCLUDES + *********************/ +#include "lv_renesas_glcdc.h" + +#if LV_USE_RENESAS_GLCDC + +#ifdef _RENESAS_RA_ + #include "LVGL_thread.h" +#else /* RX */ + #include "hal_data.h" + #include "platform.h" + #include "r_glcdc_rx_if.h" + #include "r_glcdc_rx_pinset.h" +#endif /*_RENESAS_RA_*/ + +#include +#include "../../../display/lv_display_private.h" +#include "../../../draw/sw/lv_draw_sw.h" + +/********************* + * DEFINES + *********************/ +#define BYTES_PER_PIXEL 2 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode); +static void glcdc_init(void); +static void give_vsync_sem_and_yield(void); +static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map); +static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_t * px_map); +static void flush_wait_direct(lv_display_t * display); +static void flush_wait_partial(lv_display_t * display); + +#ifdef _RENESAS_RX_ + static void enable_dave2d_drw_interrupt(void); +#endif /*_RENESAS_RX_*/ + +/********************** + * STATIC VARIABLES + **********************/ + +#ifdef _RENESAS_RX_ +static uint8_t fb_background[2][LCD_CH0_IN_GR2_HSIZE * LCD_CH0_IN_GR2_VSIZE * BYTES_PER_PIXEL]__attribute__(( + section(".framebuffer"), aligned(64), used)); +static SemaphoreHandle_t _SemaphoreVsync = NULL; +static glcdc_cfg_t g_config; +static glcdc_runtime_cfg_t g_layer_change; + +/* A global variable that Dave 2D driver relies on. (Being auto generated on RA platforms)*/ +display_t g_display0_cfg; +#endif /*_RENESAS_RX_*/ + +static void * rotation_buffer = NULL; +static uint32_t partial_buffer_size = 0; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_renesas_glcdc_direct_create(void) +{ + return glcdc_create(&fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]), + LV_DISPLAY_RENDER_MODE_DIRECT); +} + +lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size) +{ + partial_buffer_size = buf_size; + return glcdc_create(buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL); +} + +/*This function is declared in and being used by FSP generated code modules*/ +#ifdef _RENESAS_RA_ +void glcdc_callback(display_callback_args_t * p_args) +{ + if(DISPLAY_EVENT_LINE_DETECTION == p_args->event) { + give_vsync_sem_and_yield(); + } + else if(DISPLAY_EVENT_GR1_UNDERFLOW == p_args->event) { + __BKPT(0); /*Layer 1 Underrun*/ + } + else if(DISPLAY_EVENT_GR2_UNDERFLOW == p_args->event) { + __BKPT(0); /*Layer 2 Underrun*/ + } + else { /*DISPLAY_EVENT_FRAME_END*/ + __BKPT(0); + } +} +#else /* RX */ +void glcdc_callback(glcdc_callback_args_t * p_args) +{ + if(GLCDC_EVENT_LINE_DETECTION == p_args->event) { + give_vsync_sem_and_yield(); + } + else if(GLCDC_EVENT_GR1_UNDERFLOW == p_args->event) { + while(1); /*Layer 1 Underrun*/ + } + else if(GLCDC_EVENT_GR2_UNDERFLOW == p_args->event) { + while(1); /*Layer 2 Underrun*/ + } + else {/*DISPLAY_EVENT_FRAME_END*/ + while(1); + } +} +#endif /*_RENESAS_RA_*/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode) +{ +#ifdef _RENESAS_RA_ + glcdc_init(); +#else + g_display0_cfg.input->format = LCD_CH0_IN_GR2_FORMAT; + _SemaphoreVsync = xSemaphoreCreateBinary(); + + glcdc_init(); + enable_dave2d_drw_interrupt(); +#endif /*_RENESAS_RA_*/ + + lv_display_t * display = lv_display_create(DISPLAY_HSIZE_INPUT0, DISPLAY_VSIZE_INPUT0); + + if(render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) { + lv_display_set_flush_cb(display, flush_direct); + lv_display_set_flush_wait_cb(display, flush_wait_direct); + } + else if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { + lv_display_set_flush_cb(display, flush_partial); + lv_display_set_flush_wait_cb(display, flush_wait_partial); + } + else { + LV_ASSERT(0); + } + + lv_display_set_buffers(display, buf1, buf2, buf_size, render_mode); + + return display; +} + +static void give_vsync_sem_and_yield(void) +{ +#if USE_FREE_RTOS + BaseType_t context_switch; + + /*Set Vsync semaphore*/ + xSemaphoreGiveFromISR(_SemaphoreVsync, &context_switch); + + /*Return to the highest priority available task*/ + portYIELD_FROM_ISR(context_switch); +#else +#endif /*USE_FREE_RTOS*/ +} + +static void glcdc_init(void) +{ + /* Fill the Frame buffer with black colour (0x0000 in RGB565), for a clean start after previous runs */ + lv_memzero(fb_background, sizeof(fb_background)); + +#ifdef _RENESAS_RA_ + /* Initialize GLCDC driver */ + uint8_t * p_fb = &fb_background[1][0]; + fsp_err_t err; + + err = R_GLCDC_Open(&g_display0_ctrl, &g_display0_cfg); + if(FSP_SUCCESS != err) { + __BKPT(0); + } + + err = R_GLCDC_Start(&g_display0_ctrl); + if(FSP_SUCCESS != err) { + __BKPT(0); + } + + do { + err = + R_GLCDC_BufferChange(&g_display0_ctrl, + (uint8_t *) p_fb, + (display_frame_layer_t) 0); + } while(FSP_ERR_INVALID_UPDATE_TIMING == err); +#else /* RX */ + glcdc_err_t err; + glcdc_runtime_cfg_t layer_change; + + R_GLCDC_PinSet(); + + err = R_GLCDC_Open(&g_config); + if(GLCDC_SUCCESS != err) { + while(1); + } + + err = R_GLCDC_Control(GLCDC_CMD_START_DISPLAY, &g_config); + if(GLCDC_SUCCESS != err) { + while(1); + } + + g_layer_change.input = g_config.input[GLCDC_FRAME_LAYER_2]; + g_layer_change.chromakey = g_config.chromakey[GLCDC_FRAME_LAYER_2]; + g_layer_change.blend = g_config.blend[GLCDC_FRAME_LAYER_2]; + + layer_change.input.p_base = (uint32_t *)&fb_background[1][0]; + + do { + err = R_GLCDC_LayerChange(GLCDC_FRAME_LAYER_2, &g_layer_change); + } while(GLCDC_ERR_INVALID_UPDATE_TIMING == err); +#endif /*_RENESAS_RA_*/ +} + +static void flush_direct(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) +{ + FSP_PARAMETER_NOT_USED(area); + /*Display the frame buffer pointed by px_map*/ + + if(!lv_display_flush_is_last(display)) return; + +#if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED) + /* Invalidate cache - so the HW can access any data written by the CPU */ + SCB_CleanInvalidateDCache_by_Addr(px_map, sizeof(fb_background[0])); +#endif + +#ifdef _RENESAS_RA_ + R_GLCDC_BufferChange(&g_display0_ctrl, + (uint8_t *) px_map, + (display_frame_layer_t) 0); +#else /* RX */ + glcdc_err_t err; + + g_layer_change.input.p_base = (uint32_t *)px_map; + + do { + err = R_GLCDC_LayerChange(GLCDC_FRAME_LAYER_2, &g_layer_change); + } while(GLCDC_ERR_INVALID_UPDATE_TIMING == err); +#endif /*_RENESAS_RA_*/ +} + +static void flush_wait_direct(lv_display_t * display) +{ + if(!lv_display_flush_is_last(display)) return; + +#if USE_FREE_RTOS + /*If Vsync semaphore has already been set, clear it then wait to avoid tearing*/ + if(uxSemaphoreGetCount(_SemaphoreVsync)) { + xSemaphoreTake(_SemaphoreVsync, 10); + } + + xSemaphoreTake(_SemaphoreVsync, portMAX_DELAY); +#endif /*USE_FREE_RTOS*/ + +} + +static void flush_partial(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) +{ + uint16_t * img = (uint16_t *)px_map; + + lv_area_t rotated_area; + lv_color_format_t cf = lv_display_get_color_format(display); + lv_display_rotation_t rotation = lv_display_get_rotation(display); + + if(rotation != LV_DISPLAY_ROTATION_0) { + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + uint32_t w_stride = lv_draw_buf_width_to_stride(w, cf); + uint32_t h_stride = lv_draw_buf_width_to_stride(h, cf); + + // only allocate if rotation is actually being used + if(!rotation_buffer) { + rotation_buffer = lv_malloc(partial_buffer_size); + LV_ASSERT_MALLOC(rotation_buffer); + } + + if(rotation == LV_DISPLAY_ROTATION_180) + lv_draw_sw_rotate(img, rotation_buffer, w, h, w_stride, w_stride, rotation, cf); + else /* 90 or 270 */ + lv_draw_sw_rotate(img, rotation_buffer, w, h, w_stride, h_stride, rotation, cf); + + img = rotation_buffer; + + rotated_area = *area; + lv_display_rotate_area(display, &rotated_area); + area = &rotated_area; + } + + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + + uint16_t * fb = (uint16_t *)fb_background[1]; + + fb = fb + area->y1 * DISPLAY_HSIZE_INPUT0; + fb = fb + area->x1; + + int32_t i; + for(i = 0; i < h; i++) { + lv_memcpy(fb, img, w * BYTES_PER_PIXEL); + +#if defined(RENESAS_CORTEX_M85) && (BSP_CFG_DCACHE_ENABLED) + SCB_CleanInvalidateDCache_by_Addr(fb, w * BYTES_PER_PIXEL); +#endif + fb += DISPLAY_HSIZE_INPUT0; + img += w; + } +} + +static void flush_wait_partial(lv_display_t * display) +{ + LV_UNUSED(display); + + return; +} + +#ifdef _RENESAS_RX_ +extern void drw_int_isr(void); + +static void enable_dave2d_drw_interrupt(void) +{ + bsp_int_ctrl_t grpal1; + + /* Specify the priority of the group interrupt. */ + grpal1.ipl = 5; + + /* Use the BSP API to register the interrupt handler for DRW2D. */ + R_BSP_InterruptWrite(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, (bsp_int_cb_t)drw_int_isr); + + /* Use the BSP API to enable the group interrupt. */ + R_BSP_InterruptControl(BSP_INT_SRC_AL1_DRW2D_DRW_IRQ, BSP_INT_CMD_GROUP_INTERRUPT_ENABLE, (void *)&grpal1); +} +#endif /*_RENESAS_RX_*/ + +#endif /*LV_USE_RENESAS_GLCDC*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.h new file mode 100644 index 000000000..0558614e5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/renesas_glcdc/lv_renesas_glcdc.h @@ -0,0 +1,57 @@ +/** + * @file lv_renesas_glcdc.h + * + */ + +#ifndef LV_RENESAS_GLCDC_H +#define LV_RENESAS_GLCDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../display/lv_display.h" + +#if LV_USE_RENESAS_GLCDC + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a display using Renesas' GLCDC peripherial in DIRECT render mode + * @return pointer to the created display + */ +lv_display_t * lv_renesas_glcdc_direct_create(void); + +/** + * Create a display using Renesas' GLCDC peripherial in PARTIAL render mode + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + * @param buf_size buffer size in byte + * @return pointer to the created display + */ +lv_display_t * lv_renesas_glcdc_partial_create(void * buf1, void * buf2, size_t buf_size); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_RENESAS_GLCDC */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_RENESAS_GLCDC_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/st7735/lv_st7735.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/st7735/lv_st7735.h index 062cfe31b..72dd1a94c 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/st7735/lv_st7735.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/st7735/lv_st7735.h @@ -1,5 +1,5 @@ -/* - * lv_st7735.h +/** + * @file lv_st7735.h * * This driver is just a wrapper around the generic MIPI compatible LCD controller driver * diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/st7789/lv_st7789.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/st7789/lv_st7789.h index 5cd301948..5f1acada7 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/st7789/lv_st7789.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/st7789/lv_st7789.h @@ -1,5 +1,5 @@ -/* - * lv_st7789.h +/** + * @file lv_st7789.h * * This driver is just a wrapper around the generic MIPI compatible LCD controller driver * diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/st7796/lv_st7796.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/st7796/lv_st7796.h index c34dfe681..924eecb43 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/st7796/lv_st7796.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/st7796/lv_st7796.h @@ -1,5 +1,5 @@ -/* - * lv_st7796.h +/** + * @file lv_st7796.h * * This driver is just a wrapper around the generic MIPI compatible LCD controller driver * diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.cpp b/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.cpp index 64e3ee6ab..1cb7b45ff 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.cpp +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.cpp @@ -1,5 +1,5 @@ /** - * @file lv_tft_espi.c + * @file lv_tft_espi.cpp * */ @@ -26,6 +26,7 @@ typedef struct { * STATIC PROTOTYPES **********************/ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void resolution_changed_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -53,9 +54,10 @@ lv_display_t * lv_tft_espi_create(uint32_t hor_res, uint32_t ver_res, void * buf dsc->tft = new TFT_eSPI(hor_res, ver_res); dsc->tft->begin(); /* TFT init */ - dsc->tft->setRotation(3); /* Landscape orientation, flipped */ + dsc->tft->setRotation(0); lv_display_set_driver_data(disp, (void *)dsc); lv_display_set_flush_cb(disp, flush_cb); + lv_display_add_event_cb(disp, resolution_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); lv_display_set_buffers(disp, (void *)buf, NULL, buf_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL); return disp; } @@ -80,4 +82,29 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_m } +static void resolution_changed_event_cb(lv_event_t * e) +{ + lv_display_t * disp = (lv_display_t *)lv_event_get_target(e); + lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp); + int32_t hor_res = lv_display_get_horizontal_resolution(disp); + int32_t ver_res = lv_display_get_vertical_resolution(disp); + lv_display_rotation_t rot = lv_display_get_rotation(disp); + + /* handle rotation */ + switch(rot) { + case LV_DISPLAY_ROTATION_0: + dsc->tft->setRotation(0); /* Portrait orientation */ + break; + case LV_DISPLAY_ROTATION_90: + dsc->tft->setRotation(1); /* Landscape orientation */ + break; + case LV_DISPLAY_ROTATION_180: + dsc->tft->setRotation(2); /* Portrait orientation, flipped */ + break; + case LV_DISPLAY_ROTATION_270: + dsc->tft->setRotation(3); /* Landscape orientation, flipped */ + break; + } +} + #endif /*LV_USE_TFT_ESPI*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.h index 101057565..a8f49f892 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/tft_espi/lv_tft_espi.h @@ -1,5 +1,5 @@ /** - * @file lv_linux_fb_dev_h + * @file lv_tft_espi.h * */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.c b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.c index 010ad4274..e7d31ecff 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.c @@ -12,6 +12,7 @@ #include #include #include +#include #include /*To detect BSD*/ #ifdef BSD #include @@ -179,6 +180,26 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) goto err_after_open; } + /* Detect the minimum and maximum values of the input device for calibration. */ + + if(indev_type == LV_INDEV_TYPE_POINTER) { + struct input_absinfo absinfo; + if(ioctl(dsc->fd, EVIOCGABS(ABS_X), &absinfo) == 0) { + dsc->min_x = absinfo.minimum; + dsc->max_x = absinfo.maximum; + } + else { + LV_LOG_ERROR("ioctl EVIOCGABS(ABS_X) failed: %s", strerror(errno)); + } + if(ioctl(dsc->fd, EVIOCGABS(ABS_Y), &absinfo) == 0) { + dsc->min_y = absinfo.minimum; + dsc->max_y = absinfo.maximum; + } + else { + LV_LOG_ERROR("ioctl EVIOCGABS(ABS_Y) failed: %s", strerror(errno)); + } + } + lv_indev_t * indev = lv_indev_create(); if(indev == NULL) goto err_after_open; lv_indev_set_type(indev, indev_type); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.c b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.c new file mode 100644 index 000000000..849cbf58b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.c @@ -0,0 +1,391 @@ +/** + * @file lv_glfw_window.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_glfw_window_private.h" +#if LV_USE_OPENGLES +#include +#include "../../core/lv_refr.h" +#include "../../stdlib/lv_string.h" +#include "../../core/lv_global.h" +#include "../../display/lv_display_private.h" +#include "../../indev/lv_indev.h" +#include "../../lv_init.h" +#include "../../misc/lv_area_private.h" + +#include +#include + +#include "lv_opengles_driver.h" +#include "lv_opengles_texture.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void window_update_handler(lv_timer_t * t); +static uint32_t lv_glfw_tick_count_callback(void); +static lv_glfw_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window); +static void glfw_error_cb(int error, const char * description); +static int lv_glfw_init(void); +static int lv_glew_init(void); +static void lv_glfw_timer_init(void); +static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev); +static void lv_glfw_window_quit(void); +static void window_close_callback(GLFWwindow * window); +static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods); +static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods); +static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos); +static void proc_mouse(lv_glfw_window_t * window); +static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data); +static void framebuffer_size_callback(GLFWwindow * window, int width, int height); + +/********************** + * STATIC VARIABLES + **********************/ +static bool glfw_inited; +static bool glew_inited; +static lv_timer_t * update_handler_timer; +static lv_ll_t glfw_window_ll; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev) +{ + if(lv_glfw_init() != 0) { + return NULL; + } + + lv_glfw_window_t * window = lv_ll_ins_tail(&glfw_window_ll); + LV_ASSERT_MALLOC(window); + if(window == NULL) return NULL; + lv_memzero(window, sizeof(*window)); + + /* Create window with graphics context */ + lv_glfw_window_t * existing_window = lv_ll_get_head(&glfw_window_ll); + window->window = glfwCreateWindow(hor_res, ver_res, "LVGL Simulator", NULL, + existing_window ? existing_window->window : NULL); + if(window->window == NULL) { + LV_LOG_ERROR("glfwCreateWindow fail."); + lv_ll_remove(&glfw_window_ll, window); + lv_free(window); + return NULL; + } + + window->hor_res = hor_res; + window->ver_res = ver_res; + lv_ll_init(&window->textures, sizeof(lv_glfw_texture_t)); + window->use_indev = use_mouse_indev; + + glfwSetWindowUserPointer(window->window, window); + lv_glfw_timer_init(); + lv_glfw_window_config(window->window, use_mouse_indev); + lv_glew_init(); + glfwMakeContextCurrent(window->window); + lv_opengles_init(); + + return window; +} + +void lv_glfw_window_delete(lv_glfw_window_t * window) +{ + glfwDestroyWindow(window->window); + if(window->use_indev) { + lv_glfw_texture_t * texture; + LV_LL_READ(&window->textures, texture) { + lv_indev_delete(texture->indev); + } + } + lv_ll_clear(&window->textures); + lv_ll_remove(&glfw_window_ll, window); + lv_free(window); + + if(lv_ll_is_empty(&glfw_window_ll)) { + lv_glfw_window_quit(); + } +} + +lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w, int32_t h) +{ + lv_glfw_texture_t * texture = lv_ll_ins_tail(&window->textures); + LV_ASSERT_MALLOC(texture); + if(texture == NULL) return NULL; + lv_memzero(texture, sizeof(*texture)); + texture->window = window; + texture->texture_id = texture_id; + lv_area_set(&texture->area, 0, 0, w - 1, h - 1); + texture->opa = LV_OPA_COVER; + + if(window->use_indev) { + lv_display_t * texture_disp = lv_opengles_texture_get_from_texture_id(texture_id); + if(texture_disp != NULL) { + lv_indev_t * indev = lv_indev_create(); + if(indev == NULL) { + lv_ll_remove(&window->textures, texture); + lv_free(texture); + return NULL; + } + texture->indev = indev; + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, indev_read_cb); + lv_indev_set_driver_data(indev, texture); + lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); + lv_indev_set_display(indev, texture_disp); + } + } + + return texture; +} + +void lv_glfw_texture_remove(lv_glfw_texture_t * texture) +{ + if(texture->indev != NULL) { + lv_indev_delete(texture->indev); + } + lv_ll_remove(&texture->window->textures, texture); + lv_free(texture); +} + +void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x) +{ + lv_area_set_pos(&texture->area, x, texture->area.y1); +} + +void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y) +{ + lv_area_set_pos(&texture->area, texture->area.x1, y); +} + +void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa) +{ + texture->opa = opa; +} + +lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture) +{ + return texture->indev; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int lv_glfw_init(void) +{ + if(glfw_inited) { + return 0; + } + + glfwSetErrorCallback(glfw_error_cb); + + int ret = glfwInit(); + if(ret == 0) { + LV_LOG_ERROR("glfwInit fail."); + return 1; + } + + lv_ll_init(&glfw_window_ll, sizeof(lv_glfw_window_t)); + + glfw_inited = true; + return 0; +} + +static int lv_glew_init(void) +{ + if(glew_inited) { + return 0; + } + + GLenum ret = glewInit(); + if(ret != GLEW_OK) { + LV_LOG_ERROR("glewInit fail: %d.", ret); + return ret; + } + + LV_LOG_INFO("GL version: %s", glGetString(GL_VERSION)); + LV_LOG_INFO("GLSL version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); + + glew_inited = true; + + return 0; +} + +static void lv_glfw_timer_init(void) +{ + if(update_handler_timer == NULL) { + update_handler_timer = lv_timer_create(window_update_handler, LV_DEF_REFR_PERIOD, NULL); + lv_tick_set_cb(lv_glfw_tick_count_callback); + } +} + +static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev) +{ + glfwMakeContextCurrent(window); + + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + if(use_mouse_indev) { + glfwSetMouseButtonCallback(window, mouse_button_callback); + glfwSetCursorPosCallback(window, mouse_move_callback); + } + + glfwSetKeyCallback(window, key_callback); + + glfwSetWindowCloseCallback(window, window_close_callback); +} + +static void lv_glfw_window_quit(void) +{ + lv_timer_delete(update_handler_timer); + update_handler_timer = NULL; + + glfwTerminate(); + glfw_inited = false; + + lv_deinit(); + + exit(0); +} + +static void window_update_handler(lv_timer_t * t) +{ + LV_UNUSED(t); + + lv_glfw_window_t * window; + + glfwPollEvents(); + + /* delete windows that are ready to close */ + window = lv_ll_get_head(&glfw_window_ll); + while(window) { + lv_glfw_window_t * window_to_delete = window->closing ? window : NULL; + window = lv_ll_get_next(&glfw_window_ll, window); + if(window_to_delete) { + glfwSetWindowShouldClose(window_to_delete->window, GLFW_TRUE); + lv_glfw_window_delete(window_to_delete); + } + } + + /* render each window */ + LV_LL_READ(&glfw_window_ll, window) { + glfwMakeContextCurrent(window->window); + lv_opengles_viewport(0, 0, window->hor_res, window->ver_res); + lv_opengles_render_clear(); + + /* render each texture in the window */ + lv_glfw_texture_t * texture; + LV_LL_READ(&window->textures, texture) { + /* if the added texture is an LVGL opengles texture display, refresh it before rendering it */ + lv_display_t * texture_disp = lv_opengles_texture_get_from_texture_id(texture->texture_id); + if(texture_disp != NULL) { + lv_refr_now(texture_disp); + } + + lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res); + } + + /* Swap front and back buffers */ + glfwSwapBuffers(window->window); + } +} + +static void glfw_error_cb(int error, const char * description) +{ + LV_LOG_ERROR("GLFW Error %d: %s", error, description); +} + +static lv_glfw_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window) +{ + return glfwGetWindowUserPointer(window); +} + +static void window_close_callback(GLFWwindow * window) +{ + lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->closing = 1; +} + +static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods) +{ + LV_UNUSED(scancode); + LV_UNUSED(mods); + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->closing = 1; + } +} + +static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods) +{ + LV_UNUSED(mods); + if(button == GLFW_MOUSE_BUTTON_LEFT) { + lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->mouse_last_state = action == GLFW_PRESS ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + proc_mouse(lv_window); + } +} + +static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos) +{ + lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->mouse_last_point.x = (int32_t)xpos; + lv_window->mouse_last_point.y = (int32_t)ypos; + proc_mouse(lv_window); +} + +static void proc_mouse(lv_glfw_window_t * window) +{ + /* mouse activity will affect the topmost LVGL display texture */ + lv_glfw_texture_t * texture; + LV_LL_READ_BACK(&window->textures, texture) { + if(lv_area_is_point_on(&texture->area, &window->mouse_last_point, 0)) { + /* adjust the mouse pointer coordinates so that they are relative to the texture */ + texture->indev_last_point.x = window->mouse_last_point.x - texture->area.x1; + texture->indev_last_point.y = window->mouse_last_point.y - texture->area.y1; + texture->indev_last_state = window->mouse_last_state; + lv_indev_read(texture->indev); + break; + } + } +} + +static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_glfw_texture_t * texture = lv_indev_get_driver_data(indev); + data->point = texture->indev_last_point; + data->state = texture->indev_last_state; +} + +static void framebuffer_size_callback(GLFWwindow * window, int width, int height) +{ + lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->hor_res = width; + lv_window->ver_res = height; +} + +static uint32_t lv_glfw_tick_count_callback(void) +{ + double tick = glfwGetTime() * 1000.0; + return (uint32_t)tick; +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.h b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.h new file mode 100644 index 000000000..e8e516101 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.h @@ -0,0 +1,108 @@ +/** + * @file lv_glfw_window.h + * + */ + +#ifndef LV_GLFW_WINDOW_H +#define LV_GLFW_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_types.h" +#include "../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a GLFW window with no textures and initialize OpenGL + * @param hor_res width in pixels of the window + * @param ver_res height in pixels of the window + * @param use_mouse_indev send pointer indev input to LVGL display textures + * @return the new GLFW window handle + */ +lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev); + +/** + * Delete a GLFW window. If it is the last one, the process will exit + * @param window GLFW window to delete + */ +void lv_glfw_window_delete(lv_glfw_window_t * window); + +/** + * Add a texture to the GLFW window. It can be an LVGL display texture, or any OpenGL texture + * @param window GLFW window + * @param texture_id OpenGL texture ID + * @param w width in pixels of the texture + * @param h height in pixels of the texture + * @return the new texture handle + */ +lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w, + int32_t h); + +/** + * Remove a texture from its GLFW window and delete it + * @param texture handle of a GLFW window texture + */ +void lv_glfw_texture_remove(lv_glfw_texture_t * texture); + +/** + * Set the x position of a texture within its GLFW window + * @param texture handle of a GLFW window texture + * @param x new x position of the texture + */ +void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x); + +/** + * Set the y position of a texture within its GLFW window + * @param texture handle of a GLFW window texture + * @param y new y position of the texture + */ +void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y); + +/** + * Set the opacity of a texture in a GLFW window + * @param texture handle of a GLFW window texture + * @param opa new opacity of the texture + */ +void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa); + +/** + * Get the mouse indev associated with a texture in a GLFW window, if it exists + * @param texture handle of a GLFW window texture + * @return the indev or `NULL` + * @note there will only be an indev if the texture is based on an + * LVGL display texture and the window was created with + * `use_mouse_indev` as `true` + */ +lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_GLFW_WINDOW_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window_private.h new file mode 100644 index 000000000..a8149c292 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window_private.h @@ -0,0 +1,70 @@ +/** + * @file lv_glfw_window_private.h + * + */ + +#ifndef LV_GLFW_WINDOW_PRIVATE_H +#define LV_GLFW_WINDOW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_glfw_window.h" +#if LV_USE_OPENGLES + +#include +#include + +#include "../../misc/lv_area.h" +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_glfw_window_t { + GLFWwindow * window; + int32_t hor_res; + int32_t ver_res; + lv_ll_t textures; + lv_point_t mouse_last_point; + lv_indev_state_t mouse_last_state; + uint8_t use_indev : 1; + uint8_t closing : 1; +}; + +struct lv_glfw_texture_t { + lv_glfw_window_t * window; + unsigned int texture_id; + lv_area_t area; + lv_opa_t opa; + lv_indev_t * indev; + lv_point_t indev_last_point; + lv_indev_state_t indev_last_state; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GLFW_WINDOW_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.c b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.c new file mode 100644 index 000000000..5bf6d0227 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.c @@ -0,0 +1,58 @@ +/** + * @file lv_opengles_debug.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_opengles_debug.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_log.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void GLClearError() +{ + while(glGetError() != GL_NO_ERROR); +} + +bool GLLogCall(const char * function, const char * file, int line) +{ + GLenum error; + while((error = glGetError()) != GL_NO_ERROR) { + LV_LOG_ERROR("[OpenGL Error] (%d) %s %s:%d", error, function, file, line); + return false; + } + return true; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_OPENGLES */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.h b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.h new file mode 100644 index 000000000..ddde0eb53 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.h @@ -0,0 +1,38 @@ +/** + * @file lv_opengles_debug.h + * + */ + +#ifndef LV_OPENGLES_DEBUG_H +#define LV_OPENGLES_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include +#include +#include + +void GLClearError(void); + +bool GLLogCall(const char * function, const char * file, int line); + +#if LV_USE_OPENGLES_DEBUG +#define GL_CALL(x) GLClearError();\ + x;\ + GLLogCall(#x, __FILE__, __LINE__) +#else +#define GL_CALL(x) x +#endif + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_DEBUG_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.c b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.c new file mode 100644 index 000000000..110e7140f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.c @@ -0,0 +1,409 @@ +/** + * @file lv_opengles_driver.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../display/lv_display.h" + +#if LV_USE_OPENGLES + +#include "lv_opengles_debug.h" +#include "lv_opengles_driver.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_opengles_enable_blending(void); +static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size); +static void lv_opengles_vertex_buffer_deinit(void); +static void lv_opengles_vertex_buffer_bind(void); +static void lv_opengles_vertex_buffer_unbind(void); +static void lv_opengles_vertex_array_init(void); +static void lv_opengles_vertex_array_deinit(void); +static void lv_opengles_vertex_array_bind(void); +static void lv_opengles_vertex_array_unbind(void); +static void lv_opengles_vertex_array_add_buffer(void); +static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count); +static void lv_opengles_index_buffer_deinit(void); +static unsigned int lv_opengles_index_buffer_get_count(void); +static void lv_opengles_index_buffer_bind(void); +static void lv_opengles_index_buffer_unbind(void); +static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source); +static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader); +static void lv_opengles_shader_init(void); +static void lv_opengles_shader_deinit(void); +static void lv_opengles_shader_bind(void); +static void lv_opengles_shader_unbind(void); +static int lv_opengles_shader_get_uniform_location(const char * name); +static void lv_opengles_shader_set_uniform1i(const char * name, int value); +static void lv_opengles_shader_set_uniformmatrix3fv(const char * name, int count, bool transpose, const float * values); +static void lv_opengles_shader_set_uniform1f(const char * name, float value); +static void lv_opengles_render_draw(void); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static bool is_init; + +static unsigned int vertex_buffer_id = 0; + +static unsigned int vertex_array_id = 0; + +static unsigned int index_buffer_id = 0; +static unsigned int index_buffer_count = 0; + +static unsigned int shader_id; + +static const char * shader_names[] = { "u_Texture", "u_ColorDepth", "u_VertexTransform", "u_Opa" }; +static int shader_location[] = { 0, 0, 0, 0 }; + +static const char * vertex_shader = + "#version 300 es\n" + "\n" + "in vec4 position;\n" + "in vec2 texCoord;\n" + "\n" + "out vec2 v_TexCoord;\n" + "\n" + "uniform mat3 u_VertexTransform;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4((u_VertexTransform * vec3(position.xy, 1)).xy, position.zw);\n" + " v_TexCoord = texCoord;\n" + "};\n"; + +static const char * fragment_shader = + "#version 300 es\n" + "\n" + "precision mediump float;\n" + "\n" + "layout(location = 0) out vec4 color;\n" + "\n" + "in vec2 v_TexCoord;\n" + "\n" + "uniform sampler2D u_Texture;\n" + "uniform int u_ColorDepth;\n" + "uniform float u_Opa;\n" + "\n" + "void main()\n" + "{\n" + " vec4 texColor = texture(u_Texture, v_TexCoord);\n" + " if (u_ColorDepth == 8) {\n" + " float gray = texColor.r;\n" + " color = vec4(gray, gray, gray, u_Opa);\n" + " } else {\n" + " color = vec4(texColor.rgb, texColor.a * u_Opa);\n" + " }\n" + "};\n"; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_opengles_init(void) +{ + if(is_init) return; + + lv_opengles_enable_blending(); + + float positions[] = { + -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f + }; + + unsigned int indices[] = { + 0, 1, 2, + 2, 3, 0 + }; + + lv_opengles_vertex_buffer_init(positions, sizeof(positions)); + + lv_opengles_vertex_array_init(); + lv_opengles_vertex_array_add_buffer(); + + lv_opengles_index_buffer_init(indices, 6); + + lv_opengles_shader_init(); + lv_opengles_shader_bind(); + + /* unbind everything */ + lv_opengles_vertex_array_unbind(); + lv_opengles_vertex_buffer_unbind(); + lv_opengles_index_buffer_unbind(); + lv_opengles_shader_unbind(); + + is_init = true; +} + +void lv_opengles_deinit(void) +{ + if(!is_init) return; + + lv_opengles_shader_deinit(); + lv_opengles_index_buffer_deinit(); + lv_opengles_vertex_buffer_deinit(); + lv_opengles_vertex_array_deinit(); + + is_init = false; +} + +void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, int32_t disp_w, + int32_t disp_h) +{ + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + + float hor_scale = (float)lv_area_get_width(texture_area) / (float)disp_w; + float ver_scale = (float)lv_area_get_height(texture_area) / (float)disp_h; + float hor_translate = (float)texture_area->x1 / (float)disp_w * 2.0f - (1.0f - hor_scale); + float ver_translate = -((float)texture_area->y1 / (float)disp_h * 2.0f - (1.0f - ver_scale)); + float matrix[9] = { + hor_scale, 0.0f, hor_translate, + 0.0f, ver_scale, ver_translate, + 0.0f, 0.0f, 1.0f + }; + + lv_opengles_shader_bind(); + lv_opengles_shader_set_uniform1i("u_ColorDepth", LV_COLOR_DEPTH); + lv_opengles_shader_set_uniform1i("u_Texture", 0); + lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, true, matrix); + lv_opengles_shader_set_uniform1f("u_Opa", (float)opa / (float)LV_OPA_100); + lv_opengles_render_draw(); +} + +void lv_opengles_render_clear(void) +{ + GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); +} + +void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h) +{ + glViewport(x, y, w, h); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_opengles_enable_blending(void) +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size) +{ + GL_CALL(glGenBuffers(1, &vertex_buffer_id)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); +} + +static void lv_opengles_vertex_buffer_deinit(void) +{ + GL_CALL(glDeleteBuffers(1, &vertex_buffer_id)); +} + +static void lv_opengles_vertex_buffer_bind(void) +{ + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); +} + +static void lv_opengles_vertex_buffer_unbind(void) +{ + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); +} + +static void lv_opengles_vertex_array_init(void) +{ + GL_CALL(glGenVertexArrays(1, &vertex_array_id)); +} + +static void lv_opengles_vertex_array_deinit(void) +{ + GL_CALL(glDeleteVertexArrays(1, &vertex_array_id)); +} + +static void lv_opengles_vertex_array_bind(void) +{ + GL_CALL(glBindVertexArray(vertex_array_id)); +} + +static void lv_opengles_vertex_array_unbind(void) +{ + GL_CALL(glBindVertexArray(0)); +} + +static void lv_opengles_vertex_array_add_buffer(void) +{ + lv_opengles_vertex_buffer_bind(); + intptr_t offset = 0; + + for(unsigned int i = 0; i < 2; i++) { + lv_opengles_vertex_array_bind(); + GL_CALL(glEnableVertexAttribArray(i)); + GL_CALL(glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 16, (const void *)offset)); + offset += 2 * 4; + } +} + +static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count) +{ + index_buffer_count = count; + GL_CALL(glGenBuffers(1, &index_buffer_id)); + + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); + + GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLuint), data, GL_STATIC_DRAW)); +} + +static void lv_opengles_index_buffer_deinit(void) +{ + GL_CALL(glDeleteBuffers(1, &index_buffer_id)); +} + +static unsigned int lv_opengles_index_buffer_get_count(void) +{ + return index_buffer_count; +} + +static void lv_opengles_index_buffer_bind(void) +{ + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); +} + +static void lv_opengles_index_buffer_unbind(void) +{ + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +} + +static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source) +{ + GL_CALL(unsigned int id = glCreateShader(type)); + const char * src = source; + GL_CALL(glShaderSource(id, 1, &src, NULL)); + GL_CALL(glCompileShader(id)); + + int result; + GL_CALL(glGetShaderiv(id, GL_COMPILE_STATUS, &result)); + if(result == GL_FALSE) { + int length; + GL_CALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length)); + char * message = lv_malloc_zeroed(length * sizeof(char)); + GL_CALL(glGetShaderInfoLog(id, length, &length, message)); + LV_LOG_ERROR("Failed to compile %s shader!", type == GL_VERTEX_SHADER ? "vertex" : "fragment"); + LV_LOG_ERROR("%s", message); + GL_CALL(glDeleteShader(id)); + return 0; + } + + return id; +} + +static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader) +{ + GL_CALL(unsigned int program = glCreateProgram()); + unsigned int vs = lv_opengles_shader_compile(GL_VERTEX_SHADER, vertexShader); + unsigned int fs = lv_opengles_shader_compile(GL_FRAGMENT_SHADER, fragmentShader); + + GL_CALL(glAttachShader(program, vs)); + GL_CALL(glAttachShader(program, fs)); + GL_CALL(glLinkProgram(program)); + GL_CALL(glValidateProgram(program)); + + GL_CALL(glDeleteShader(vs)); + GL_CALL(glDeleteShader(fs)); + + return program; +} + +static void lv_opengles_shader_init(void) +{ + shader_id = lv_opengles_shader_create(vertex_shader, fragment_shader); +} + +static void lv_opengles_shader_deinit(void) +{ + GL_CALL(glDeleteProgram(shader_id)); +} + +static void lv_opengles_shader_bind(void) +{ + GL_CALL(glUseProgram(shader_id)); +} + +static void lv_opengles_shader_unbind(void) +{ + GL_CALL(glUseProgram(0)); +} + +static int lv_opengles_shader_get_uniform_location(const char * name) +{ + int id = -1; + for(size_t i = 0; i < sizeof(shader_location) / sizeof(int); i++) { + if(lv_strcmp(shader_names[i], name) == 0) { + id = i; + } + } + if(id == -1) { + return -1; + } + + if(shader_location[id] != 0) { + return shader_location[id]; + } + + GL_CALL(int location = glGetUniformLocation(shader_id, name)); + if(location == -1) + LV_LOG_WARN("Warning: uniform '%s' doesn't exist!", name); + + shader_location[id] = location; + return location; +} + +static void lv_opengles_shader_set_uniform1i(const char * name, int value) +{ + GL_CALL(glUniform1i(lv_opengles_shader_get_uniform_location(name), value)); +} + +static void lv_opengles_shader_set_uniformmatrix3fv(const char * name, int count, bool transpose, const float * values) +{ + GL_CALL(glUniformMatrix3fv(lv_opengles_shader_get_uniform_location(name), count, transpose, values)); +} + +static void lv_opengles_shader_set_uniform1f(const char * name, float value) +{ + GL_CALL(glUniform1f(lv_opengles_shader_get_uniform_location(name), value)); +} + +static void lv_opengles_render_draw(void) +{ + lv_opengles_shader_bind(); + lv_opengles_vertex_array_bind(); + lv_opengles_index_buffer_bind(); + unsigned int count = lv_opengles_index_buffer_get_count(); + GL_CALL(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL)); +} + +#endif /* LV_USE_OPENGLES */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.h b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.h new file mode 100644 index 000000000..e539febb9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.h @@ -0,0 +1,82 @@ +/** + * @file lv_opengles_driver.h + * + */ + +#ifndef LV_OPENGLES_DRIVER_H +#define LV_OPENGLES_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize OpenGL + * @note it is not necessary to call this if you use `lv_glfw_window_create` + */ +void lv_opengles_init(void); + +/** + * Deinitialize OpenGL + * @note it is not necessary to call this if you use `lv_glfw_window_create` + */ +void lv_opengles_deinit(void); + +/** + * Render a texture + * @param texture OpenGL texture ID + * @param texture_area the area in the window to render the texture in + * @param opa opacity to blend the texture with existing contents + * @param disp_w width of the window being rendered to + * @param disp_h height of the window being rendered to + */ +void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, int32_t disp_w, + int32_t disp_h); + +/** + * Clear the window/display + */ +void lv_opengles_render_clear(void); + +/** + * Set the OpenGL viewport + * @param x x position of the viewport + * @param y y position of the viewport + * @param w width of the viewport + * @param h height of the viewport + */ +void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_DRIVER_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c new file mode 100644 index 000000000..42e6a9f70 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c @@ -0,0 +1,151 @@ +/** + * @file lv_opengles_texture.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_opengles_texture.h" +#if LV_USE_OPENGLES + +#include "lv_opengles_debug.h" +#include "../../display/lv_display_private.h" +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + unsigned int texture_id; + uint8_t * fb1; +} lv_opengles_texture_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void release_disp_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h) +{ + lv_display_t * disp = lv_display_create(w, h); + if(disp == NULL) { + return NULL; + } + lv_opengles_texture_t * dsc = lv_malloc_zeroed(sizeof(lv_opengles_texture_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) { + lv_display_delete(disp); + return NULL; + } + uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp)); + uint32_t buf_size = stride * w; + dsc->fb1 = malloc(buf_size); + if(dsc->fb1 == NULL) { + lv_free(dsc); + lv_display_delete(disp); + return NULL; + } + + GL_CALL(glGenTextures(1, &dsc->texture_id)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + lv_display_set_buffers(disp, dsc->fb1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_set_driver_data(disp, dsc); + lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp); + + return disp; +} + +unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp) +{ + if(disp->flush_cb != flush_cb) { + return 0; + } + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + return dsc->texture_id; +} + +lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id) +{ + lv_display_t * disp = NULL; + while(NULL != (disp = lv_display_get_next(disp))) { + unsigned int disp_texture_id = lv_opengles_texture_get_texture_id(disp); + if(disp_texture_id == texture_id) { + return disp; + } + } + return NULL; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + LV_UNUSED(area); + LV_UNUSED(px_map); + + if(lv_display_flush_is_last(disp)) { + + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id)); + + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + /*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +#if LV_COLOR_DEPTH == 8 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, disp->hor_res, disp->ver_res, 0, GL_RED, GL_UNSIGNED_BYTE, dsc->fb1)); +#elif LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + dsc->fb1)); +#elif LV_COLOR_DEPTH == 24 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, disp->hor_res, disp->ver_res, 0, GL_BGR, GL_UNSIGNED_BYTE, dsc->fb1)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE, dsc->fb1)); +#else +#error("Unsupported color format") +#endif + } + + lv_display_flush_ready(disp); +} + +static void release_disp_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_user_data(e); + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + free(dsc->fb1); + lv_free(dsc); +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.h b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.h new file mode 100644 index 000000000..0d53b2b16 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.h @@ -0,0 +1,66 @@ +/** + * @file lv_opengles_texture.h + * + */ + +#ifndef LV_OPENGLES_TEXTURE_H +#define LV_OPENGLES_TEXTURE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a display that flushes to an OpenGL texture + * @param w width in pixels of the texture + * @param h height in pixels of the texture + * @return the new display + */ +lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h); + +/** + * Get the OpenGL texture ID of the display + * @param disp display + * @return texture ID + */ +unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp); + +/** + * Get the display of an OpenGL texture if it is associated with one + * @param texture_id OpenGL texture ID + * @return display or `NULL` if there no display with that texture ID + */ +lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_TEXTURE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.c b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.c index f207fa477..7410f40fd 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.c @@ -7,7 +7,8 @@ * INCLUDES *********************/ -#include "lv_libinput.h" +#include "../../indev/lv_indev_private.h" +#include "lv_libinput_private.h" #if LV_USE_LIBINPUT @@ -22,6 +23,7 @@ #include #include #include +#include #if LV_LIBINPUT_BSD #include @@ -602,7 +604,7 @@ static void _read_keypad(lv_libinput_t * dsc, struct libinput_event * event) /* Only record button state when actual output is produced to prevent widgets from refreshing */ evt->pressed = (key_state == LIBINPUT_KEY_STATE_RELEASED) ? LV_INDEV_STATE_RELEASED : LV_INDEV_STATE_PRESSED; - // just release the key immediatly after it got pressed. + // just release the key immediately after it got pressed. // but don't handle special keys where holding a key makes sense if(evt->key_val != LV_KEY_BACKSPACE && evt->key_val != LV_KEY_UP && diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.h b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.h index 4ec1160a0..ce19a33b5 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.h @@ -39,43 +39,10 @@ typedef enum { LV_LIBINPUT_CAPABILITY_TOUCH = 1U << 2 } lv_libinput_capability; -typedef struct { - lv_indev_state_t pressed; - int key_val; - lv_point_t point; -} lv_libinput_event_t; +struct libinput_device; #define LV_LIBINPUT_MAX_EVENTS 32 -typedef struct { - int fd; - struct pollfd fds[1]; - - /* The points array is implemented as a circular LIFO queue */ - lv_libinput_event_t points[LV_LIBINPUT_MAX_EVENTS]; /* Event buffer */ - lv_libinput_event_t slots[2]; /* Realtime state of up to 2 fingers to handle multitouch */ - - /* Pointer devices work a bit differently in libinput which requires us to store their last known state */ - lv_point_t pointer_position; - bool pointer_button_down; - - int start; /* Index of start of event queue */ - int end; /* Index of end of queue*/ - lv_libinput_event_t last_event; /* Report when no new events - * to keep indev state consistent - */ - bool deinit; /* Tell worker thread to quit */ - pthread_mutex_t event_lock; - pthread_t worker_thread; - - struct libinput * libinput_context; - struct libinput_device * libinput_device; - -#if LV_LIBINPUT_XKB - lv_xkb_t xkb; -#endif /* LV_LIBINPUT_XKB */ -} lv_libinput_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -116,7 +83,7 @@ size_t lv_libinput_find_devs(lv_libinput_capability capabilities, char ** found, lv_indev_t * lv_libinput_create(lv_indev_type_t indev_type, const char * dev_path); /** - * Delete a libinput input devic + * Delete a libinput input device * @param indev pointer to input device */ void lv_libinput_delete(lv_indev_t * indev); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h new file mode 100644 index 000000000..6d1844c6b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h @@ -0,0 +1,79 @@ +/** + * @file lv_libinput_private.h + * + */ + +#ifndef LV_LIBINPUT_PRIVATE_H +#define LV_LIBINPUT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_libinput.h" + +#if LV_USE_LIBINPUT + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_libinput_event_t { + lv_indev_state_t pressed; + int key_val; + lv_point_t point; +}; + +struct lv_libinput_t { + int fd; + struct pollfd fds[1]; + + /* The points array is implemented as a circular LIFO queue */ + lv_libinput_event_t points[LV_LIBINPUT_MAX_EVENTS]; /* Event buffer */ + lv_libinput_event_t slots[2]; /* Realtime state of up to 2 fingers to handle multitouch */ + + /* Pointer devices work a bit differently in libinput which requires us to store their last known state */ + lv_point_t pointer_position; + bool pointer_button_down; + + int start; /* Index of start of event queue */ + int end; /* Index of end of queue*/ + lv_libinput_event_t last_event; /* Report when no new events + * to keep indev state consistent + */ + bool deinit; /* Tell worker thread to quit */ + pthread_mutex_t event_lock; + pthread_t worker_thread; + + struct libinput * libinput_context; + struct libinput_device * libinput_device; + +#if LV_LIBINPUT_XKB + lv_xkb_t xkb; +#endif /* LV_LIBINPUT_XKB */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LIBINPUT */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LIBINPUT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.c b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.c index 96aeb4c0b..1e8ddb10c 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ -#include "lv_xkb.h" +#include "lv_xkb_private.h" #if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h index d048f33cb..daaa4dc1d 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb.h @@ -25,15 +25,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - struct xkb_keymap * keymap; - struct xkb_state * state; -} lv_xkb_t; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb_private.h new file mode 100644 index 000000000..315762541 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_xkb_private.h + * + */ + +#ifndef LV_XKB_PRIVATE_H +#define LV_XKB_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_xkb.h" + +#if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_xkb_t { + struct xkb_keymap * keymap; + struct xkb_state * state; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XKB_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h b/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h index f07e000d5..08c76e777 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h @@ -37,6 +37,14 @@ extern "C" { #include "windows/lv_windows_input.h" #include "windows/lv_windows_display.h" +#include "glfw/lv_glfw_window.h" +#include "glfw/lv_opengles_texture.h" +#include "glfw/lv_opengles_driver.h" + +#include "qnx/lv_qnx.h" + +#include "wayland/lv_wayland.h" + /********************* * DEFINES *********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.c index 0655d2f56..273f49ef8 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.c @@ -12,6 +12,7 @@ #if LV_USE_NUTTX +#include "../../draw/lv_draw_buf_private.h" #include /********************* @@ -27,6 +28,7 @@ **********************/ static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +static void flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); /********************** * STATIC VARIABLES @@ -44,28 +46,51 @@ void lv_nuttx_cache_init(void) { lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); handlers->invalidate_cache_cb = invalidate_cache; + handlers->flush_cache_cb = flush_cache; +} + +void lv_nuttx_cache_deinit(void) +{ + lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); + handlers->invalidate_cache_cb = NULL; + handlers->flush_cache_cb = NULL; } /********************** * STATIC FUNCTIONS **********************/ -static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +static void draw_buf_to_region( + const lv_draw_buf_t * draw_buf, const lv_area_t * area, + lv_uintptr_t * start, lv_uintptr_t * end) { LV_ASSERT_NULL(draw_buf); + LV_ASSERT_NULL(area); + LV_ASSERT_NULL(start); + LV_ASSERT_NULL(end); + void * buf = draw_buf->data; uint32_t stride = draw_buf->header.stride; + int32_t h = lv_area_get_height(area); + *start = (lv_uintptr_t)buf + area->y1 * stride; + *end = *start + h * stride; +} + +static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ lv_uintptr_t start; lv_uintptr_t end; - - int32_t h = lv_area_get_height(area); - start = (lv_uintptr_t)buf + area->y1 * stride; - end = start + h * stride; - - LV_UNUSED(start); - LV_UNUSED(end); + draw_buf_to_region(draw_buf, area, &start, &end); up_invalidate_dcache(start, end); } +static void flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + lv_uintptr_t start; + lv_uintptr_t end; + draw_buf_to_region(draw_buf, area, &start, &end); + up_flush_dcache(start, end); +} + #endif /* LV_USE_NUTTX */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.h b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.h index 693744ea4..74be6d3af 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_cache.h @@ -28,6 +28,8 @@ extern "C" { void lv_nuttx_cache_init(void); +void lv_nuttx_cache_deinit(void); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.c index 559f9bbac..57a4d289d 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.c @@ -14,8 +14,10 @@ #include #include #include +#include #include "lv_nuttx_cache.h" #include "lv_nuttx_image_cache.h" +#include "../../core/lv_global.h" #include "lv_nuttx_profiler.h" #include "../../../lvgl.h" @@ -23,7 +25,15 @@ /********************* * DEFINES *********************/ + #define nuttx_ctx_p (LV_GLOBAL_DEFAULT()->nuttx_ctx) + +#if (LV_USE_FREETYPE || LV_USE_THORVG) + #define LV_NUTTX_MIN_STACK_SIZE (32 * 1024) +#else + #define LV_NUTTX_MIN_STACK_SIZE (8 * 1024) +#endif + /********************** * TYPEDEFS **********************/ @@ -36,6 +46,11 @@ static uint32_t millis(void); #if LV_USE_LOG static void syslog_print(lv_log_level_t level, const char * buf); #endif +static void check_stack_size(void); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + static void lv_nuttx_uv_loop(lv_nuttx_result_t * result); +#endif /********************** * STATIC VARIABLES @@ -102,11 +117,11 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) #endif lv_tick_set_cb(millis); + check_stack_size(); + lv_nuttx_cache_init(); -#if LV_CACHE_DEF_SIZE > 0 lv_nuttx_image_cache_init(); -#endif #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN lv_nuttx_profiler_init(); @@ -159,6 +174,22 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) #endif } +void lv_nuttx_run(lv_nuttx_result_t * result) +{ +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + lv_nuttx_uv_loop(&ui_loop, result); +#else + while(1) { + uint32_t idle; + idle = lv_timer_handler(); + + /* Minimum sleep of 1ms */ + idle = idle ? idle : 1; + usleep(idle * 1000); + } +#endif +} + #ifdef CONFIG_SCHED_CPULOAD uint32_t lv_nuttx_get_idle(void) @@ -179,6 +210,38 @@ uint32_t lv_nuttx_get_idle(void) #endif +void lv_nuttx_deinit(lv_nuttx_result_t * result) +{ +#if !LV_USE_NUTTX_CUSTOM_INIT + if(result) { + if(result->disp) { + lv_display_delete(result->disp); + result->disp = NULL; + } + + if(result->indev) { + lv_indev_delete(result->indev); + result->indev = NULL; + } + + if(result->utouch_indev) { + lv_indev_delete(result->utouch_indev); + result->utouch_indev = NULL; + } + } +#else + lv_nuttx_deinit_custom(result); +#endif + + if(nuttx_ctx_p) { + lv_nuttx_cache_deinit(); + lv_nuttx_image_cache_deinit(); + + lv_free(nuttx_ctx_p); + nuttx_ctx_p = NULL; + } +} + /********************** * STATIC FUNCTIONS **********************/ @@ -196,7 +259,7 @@ static uint32_t millis(void) #if LV_USE_LOG static void syslog_print(lv_log_level_t level, const char * buf) { - static const int priority[_LV_LOG_LEVEL_NUM] = { + static const int priority[LV_LOG_LEVEL_NUM] = { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT }; @@ -204,4 +267,40 @@ static void syslog_print(lv_log_level_t level, const char * buf) } #endif +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +static void lv_nuttx_uv_loop(lv_nuttx_result_t * result) +{ + uv_loop_t loop; + lv_nuttx_uv_t uv_info; + void * data; + + uv_loop_init(&loop); + + lv_memzero(&uv_info, sizeof(uv_info)); + uv_info.loop = &loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} +#endif + +static void check_stack_size(void) +{ + pthread_t tid = pthread_self(); + ssize_t stack_size = pthread_get_stacksize_np(tid); + LV_LOG_USER("tid: %d, Stack size : %zd", (int)tid, stack_size); + + if(stack_size < LV_NUTTX_MIN_STACK_SIZE) { + LV_LOG_ERROR("Stack size is too small. Please increase it to %d bytes or more.", + LV_NUTTX_MIN_STACK_SIZE); + } +} + #endif /*LV_USE_NUTTX*/ + diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.h b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.h index 2e0d8bd71..64ece994e 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_entry.h @@ -43,12 +43,8 @@ typedef struct { lv_indev_t * utouch_indev; } lv_nuttx_result_t; -typedef struct _lv_nuttx_ctx_t { - -#if LV_CACHE_DEF_SIZE > 0 +typedef struct lv_nuttx_ctx_t { void * image_cache; -#endif - } lv_nuttx_ctx_t; /********************** @@ -68,6 +64,12 @@ void lv_nuttx_dsc_init(lv_nuttx_dsc_t * dsc); */ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result); +/** + * Deinitialize the LVGL display driver for NuttX. + * @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler. + */ +void lv_nuttx_deinit(lv_nuttx_result_t * result); + #if LV_USE_NUTTX_CUSTOM_INIT /** * Initialize the LVGL display driver for NuttX using the provided custom configuration information. @@ -76,8 +78,21 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result); */ void lv_nuttx_init_custom(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result); +/** + * Deinitialize the LVGL display driver for NuttX using the provided custom configuration information. + * @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler. + */ +void lv_nuttx_deinit_custom(lv_nuttx_result_t * result); #endif /* LV_USE_NUTTX_CUSTOM_INIT */ +/** + * Call `lv_timer_handler()` (LVGL's super loop) in an endless loop. + * If LV_USE_NUTTX_LIBUV is enabled an UV timer will be created, + * else `lv_timer_handler()` will be called in a loop with some sleep. + * @param result pointer to a variable initialized by `lv_nuttx_init()` or `lv_nuttx_init_custom()` + */ +void lv_nuttx_run(lv_nuttx_result_t * result); + /** * Get the idle percentage of the system. * @return The idle percentage of the system. diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.c index d4cd7f737..5ff500e28 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.c @@ -39,6 +39,7 @@ typedef struct { void * mem; void * mem2; + void * mem_off_screen; uint32_t mem2_yoffset; lv_draw_buf_t buf1; @@ -50,10 +51,14 @@ typedef struct { **********************/ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); +static lv_color_format_t fb_fmt_to_color_format(int fmt); static int fbdev_get_pinfo(int fd, struct fb_planeinfo_s * pinfo); static int fbdev_init_mem2(lv_nuttx_fb_t * dsc); static void display_refr_timer_cb(lv_timer_t * tmr); static void display_release_cb(lv_event_t * e); +#if defined(CONFIG_FB_UPDATE) + static void fbdev_join_inv_areas(lv_display_t * disp, lv_area_t * final_inv_area); +#endif /********************** * STATIC VARIABLES @@ -118,6 +123,11 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file) goto errout; } + lv_color_format_t color_format = fb_fmt_to_color_format(dsc->vinfo.fmt); + if(color_format == LV_COLOR_FORMAT_UNKNOWN) { + goto errout; + } + dsc->mem = mmap(NULL, dsc->pinfo.fblen, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, dsc->fd, 0); if(dsc->mem == MAP_FAILED) { @@ -130,21 +140,34 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file) uint32_t h = dsc->vinfo.yres; uint32_t stride = dsc->pinfo.stride; uint32_t data_size = h * stride; - lv_draw_buf_init(&dsc->buf1, w, h, LV_COLOR_FORMAT_NATIVE, stride, dsc->mem, data_size); - - /* double buffer mode */ + lv_draw_buf_init(&dsc->buf1, w, h, color_format, stride, dsc->mem, data_size); + /* Check buffer mode */ bool double_buffer = dsc->pinfo.yres_virtual == (dsc->vinfo.yres * 2); if(double_buffer) { if((ret = fbdev_init_mem2(dsc)) < 0) { goto errout; } - lv_draw_buf_init(&dsc->buf2, w, h, LV_COLOR_FORMAT_NATIVE, stride, dsc->mem2, data_size); + lv_draw_buf_init(&dsc->buf2, w, h, color_format, stride, dsc->mem2, data_size); + lv_display_set_draw_buffers(disp, &dsc->buf1, &dsc->buf2); + } + else { + dsc->mem_off_screen = malloc(data_size); + LV_ASSERT_MALLOC(dsc->mem_off_screen); + if(!dsc->mem_off_screen) { + ret = -ENOMEM; + LV_LOG_ERROR("Failed to allocate memory for off-screen buffer"); + goto errout; + } + + LV_LOG_USER("Use off-screen mode, memory: %p, size: %" LV_PRIu32, dsc->mem_off_screen, data_size); + lv_draw_buf_init(&dsc->buf2, w, h, color_format, stride, dsc->mem_off_screen, data_size); + lv_display_set_draw_buffers(disp, &dsc->buf2, NULL); } - lv_display_set_draw_buffers(disp, &dsc->buf1, double_buffer ? &dsc->buf2 : NULL); - lv_display_set_render_mode(disp, LV_DISP_RENDER_MODE_DIRECT); + lv_display_set_color_format(disp, color_format); + lv_display_set_render_mode(disp, LV_DISPLAY_RENDER_MODE_DIRECT); lv_display_set_resolution(disp, dsc->vinfo.xres, dsc->vinfo.yres); lv_timer_set_cb(disp->refr_timer, display_refr_timer_cb); @@ -162,6 +185,34 @@ errout: * STATIC FUNCTIONS **********************/ +#if defined(CONFIG_FB_UPDATE) +static void fbdev_join_inv_areas(lv_display_t * disp, lv_area_t * final_inv_area) +{ + uint16_t inv_index; + + bool area_joined = false; + + for(inv_index = 0; inv_index < disp->inv_p; inv_index++) { + if(disp->inv_area_joined[inv_index] == 0) { + const lv_area_t * area_p = &disp->inv_areas[inv_index]; + + /* Join to final_area */ + + if(!area_joined) { + /* copy first area */ + lv_area_copy(final_inv_area, area_p); + area_joined = true; + } + else { + lv_area_join(final_inv_area, + final_inv_area, + area_p); + } + } + } +} +#endif + static void display_refr_timer_cb(lv_timer_t * tmr) { lv_display_t * disp = lv_timer_get_user_data(tmr); @@ -179,14 +230,21 @@ static void display_refr_timer_cb(lv_timer_t * tmr) } if(pfds[0].revents & POLLOUT) { - _lv_display_refr_timer(tmr); + lv_display_refr_timer(tmr); } } static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p) { + LV_UNUSED(color_p); lv_nuttx_fb_t * dsc = lv_display_get_driver_data(disp); + if(dsc->mem_off_screen) { + /* When rendering in off-screen mode, copy the drawing buffer to fb */ + /* buf2(off-screen buffer) -> buf1(fbmem)*/ + lv_draw_buf_copy(&dsc->buf1, area, &dsc->buf2, area); + } + /* Skip the non-last flush */ if(!lv_display_flush_is_last(disp)) { @@ -194,23 +252,21 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo return; } - if(dsc->mem == NULL || - area->x2 < 0 || area->y2 < 0 || - area->x1 > (int32_t)dsc->vinfo.xres - 1 || area->y1 > (int32_t)dsc->vinfo.yres - 1) { - lv_display_flush_ready(disp); - return; - } - #if defined(CONFIG_FB_UPDATE) /*May be some direct update command is required*/ int yoffset = disp->buf_act == disp->buf_1 ? 0 : dsc->mem2_yoffset; + /* Join the areas to update */ + lv_area_t final_inv_area; + lv_memzero(&final_inv_area, sizeof(final_inv_area)); + fbdev_join_inv_areas(disp, &final_inv_area); + struct fb_area_s fb_area; - fb_area.x = area->x1; - fb_area.y = area->y1 + yoffset; - fb_area.w = lv_area_get_width(area); - fb_area.h = lv_area_get_height(area); + fb_area.x = final_inv_area.x1; + fb_area.y = final_inv_area.y1 + yoffset; + fb_area.w = lv_area_get_width(&final_inv_area); + fb_area.h = lv_area_get_height(&final_inv_area); if(ioctl(dsc->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)&fb_area)) < 0) { LV_LOG_ERROR("ioctl(FBIO_UPDATE) failed: %d", errno); } @@ -233,6 +289,26 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo lv_display_flush_ready(disp); } +static lv_color_format_t fb_fmt_to_color_format(int fmt) +{ + switch(fmt) { + case FB_FMT_RGB16_565: + return LV_COLOR_FORMAT_RGB565; + case FB_FMT_RGB24: + return LV_COLOR_FORMAT_RGB888; + case FB_FMT_RGB32: + return LV_COLOR_FORMAT_XRGB8888; + case FB_FMT_RGBA32: + return LV_COLOR_FORMAT_ARGB8888; + default: + break; + } + + LV_LOG_ERROR("Unsupported color format: %d", fmt); + + return LV_COLOR_FORMAT_UNKNOWN; +} + static int fbdev_get_pinfo(int fd, FAR struct fb_planeinfo_s * pinfo) { if(ioctl(fd, FBIOGET_PLANEINFO, (unsigned long)((uintptr_t)pinfo)) < 0) { @@ -247,16 +323,6 @@ static int fbdev_get_pinfo(int fd, FAR struct fb_planeinfo_s * pinfo) LV_LOG_USER(" display: %u", pinfo->display); LV_LOG_USER(" bpp: %u", pinfo->bpp); - /* Only these pixel depths are supported. vinfo.fmt is ignored, only - * certain color formats are supported. - */ - - if(pinfo->bpp != 32 && pinfo->bpp != 16 && - pinfo->bpp != 8 && pinfo->bpp != 1) { - LV_LOG_ERROR("bpp = %u not supported", pinfo->bpp); - return -EINVAL; - } - return 0; } @@ -326,6 +392,13 @@ static void display_release_cb(lv_event_t * e) close(dsc->fd); dsc->fd = -1; } + + if(dsc->mem_off_screen) { + /* Free the off-screen buffer */ + free(dsc->mem_off_screen); + dsc->mem_off_screen = NULL; + } + lv_free(dsc); } LV_LOG_USER("Done"); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.h b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.h index 994c4973b..4310aa9c1 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_fbdev.h @@ -1,5 +1,5 @@ /** - * @file lv_nuttx_fbdev_h + * @file lv_nuttx_fbdev.h * */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.c index 839704c12..93f59ed9a 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.c @@ -7,13 +7,13 @@ * INCLUDES *********************/ -#include "lv_nuttx_cache.h" +#include "lv_nuttx_image_cache.h" +#include "../../core/lv_global.h" #include "../../../lvgl.h" -#if LV_CACHE_DEF_SIZE > 0 - #if LV_USE_NUTTX +#include "../../draw/lv_draw_buf_private.h" #include /********************* @@ -25,6 +25,8 @@ #define img_cache_p (LV_GLOBAL_DEFAULT()->img_cache) #define img_header_cache_p (LV_GLOBAL_DEFAULT()->img_header_cache) #define ctx (*(lv_nuttx_ctx_image_cache_t **)&LV_GLOBAL_DEFAULT()->nuttx_ctx->image_cache) +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -32,8 +34,12 @@ typedef struct { uint8_t * mem; uint32_t mem_size; + char name[sizeof(HEAP_NAME) + 10]; /**< +10 characters to store task pid. */ + struct mm_heap_s * heap; uint32_t heap_size; + + bool initialized; } lv_nuttx_ctx_image_cache_t; /********************** * STATIC PROTOTYPES @@ -56,19 +62,58 @@ static void free_cb(void * draw_buf); void lv_nuttx_image_cache_init(void) { - lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); + lv_draw_buf_handlers_t * handlers = image_cache_draw_buf_handlers; handlers->buf_malloc_cb = malloc_cb; handlers->buf_free_cb = free_cb; ctx = lv_malloc_zeroed(sizeof(lv_nuttx_ctx_image_cache_t)); LV_ASSERT_MALLOC(ctx); - ctx->mem_size = LV_CACHE_DEF_SIZE; + ctx->initialized = false; +} + +void lv_nuttx_image_cache_deinit(void) +{ + if(ctx->initialized == false) goto FREE_CONTEXT; + + mm_uninitialize(ctx->heap); + free(ctx->mem); + +FREE_CONTEXT: + lv_free(ctx); + + ctx = NULL; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool defer_init(void) +{ + if(ctx->mem != NULL && ctx->heap != NULL) { + return true; + } + + if(lv_image_cache_is_enabled() == false) { + LV_LOG_INFO("Image cache is not initialized yet. Skipping deferred initialization. Because max_size is 0."); + return false; + } + + ctx->mem_size = img_cache_p->max_size; ctx->mem = malloc(ctx->mem_size); LV_ASSERT_MALLOC(ctx->mem); + if(ctx->mem == NULL) { + LV_LOG_ERROR("Failed to allocate memory for image cache"); + ctx->initialized = false; + return false; + } + + lv_snprintf(ctx->name, sizeof(ctx->name), HEAP_NAME "[%-4" LV_PRIu32 "]", (uint32_t)gettid()); + ctx->heap = mm_initialize( - HEAP_NAME, + ctx->name, ctx->mem, ctx->mem_size ); @@ -86,16 +131,19 @@ void lv_nuttx_image_cache_init(void) LV_LOG_USER(" mxordblk: %d", info.mxordblk); LV_LOG_USER(" uordblks: %d", info.uordblks); LV_LOG_USER(" fordblks: %d", info.fordblks); -} -/********************** - * STATIC FUNCTIONS - **********************/ + ctx->initialized = true; + return true; +} static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) { LV_UNUSED(color_format); + if(ctx->initialized == false) { + if(defer_init() == false) return NULL; + } + /*Allocate larger memory to be sure it can be aligned as needed*/ size_bytes += LV_DRAW_BUF_ALIGN - 1; uint32_t cache_max_size = lv_cache_get_max_size(img_cache_p, NULL); @@ -126,4 +174,3 @@ static void free_cb(void * draw_buf) } #endif /* LV_USE_NUTTX */ -#endif /* LV_CACHE_DEF_SIZE > 0 */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.h b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.h index e2af31f41..105779fa6 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_image_cache.h @@ -16,8 +16,6 @@ extern "C" { #include "../../lv_conf_internal.h" -#if LV_CACHE_DEF_SIZE > 0 - /********************* * DEFINES *********************/ @@ -32,12 +30,12 @@ extern "C" { void lv_nuttx_image_cache_init(void); +void lv_nuttx_image_cache_deinit(void); + /********************** * MACROS **********************/ -#endif /*LV_CACHE_DEF_SIZE > 0*/ - #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c index c785d222f..228c44593 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_lcd.c @@ -150,8 +150,8 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area_p, static lv_display_t * lcd_init(int fd, int hor_res, int ver_res) { - lv_color_t * draw_buf = NULL; - lv_color_t * draw_buf_2 = NULL; + uint8_t * draw_buf = NULL; + uint8_t * draw_buf_2 = NULL; lv_nuttx_lcd_t * lcd = lv_malloc_zeroed(sizeof(lv_nuttx_lcd_t)); LV_ASSERT_MALLOC(lcd); if(lcd == NULL) { diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_libuv.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_libuv.c index f623ae062..12b8c439c 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_libuv.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_libuv.c @@ -6,12 +6,12 @@ * INCLUDES *********************/ #include "lv_nuttx_libuv.h" -#include #include "../../../lvgl.h" #include "../../lvgl_private.h" #if LV_USE_NUTTX +#include #if LV_USE_NUTTX_LIBUV #include @@ -202,7 +202,7 @@ static void lv_nuttx_uv_disp_poll_cb(uv_poll_t * handle, int status, int events) LV_UNUSED(status); LV_UNUSED(events); uv_poll_stop(handle); - _lv_display_refr_timer(NULL); + lv_display_refr_timer(NULL); fb_ctx->polling = false; } @@ -241,7 +241,7 @@ static int lv_nuttx_uv_fb_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_ctx_t * uv_c /* Remove default refr timer. */ - lv_timer_del(disp->refr_timer); + lv_timer_delete(disp->refr_timer); disp->refr_timer = NULL; fb_ctx->fb_poll.data = uv_ctx; diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_touchscreen.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_touchscreen.c index 5dc119677..d49f765a3 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_touchscreen.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_touchscreen.c @@ -34,6 +34,8 @@ typedef struct { /* fd should be defined at the beginning */ int fd; + struct touch_sample_s last_sample; + bool has_last_sample; lv_indev_state_t last_state; lv_indev_t * indev_drv; } lv_nuttx_touchscreen_t; @@ -85,38 +87,71 @@ lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path) * STATIC FUNCTIONS **********************/ +static void conv_touch_sample(lv_indev_t * drv, + lv_indev_data_t * data, + struct touch_sample_s * sample) +{ + lv_nuttx_touchscreen_t * touchscreen = drv->driver_data; + uint8_t touch_flags = sample->point[0].flags; + + if(touch_flags & (TOUCH_DOWN | TOUCH_MOVE)) { + lv_display_t * disp = lv_indev_get_display(drv); + int32_t hor_max = lv_display_get_horizontal_resolution(disp) - 1; + int32_t ver_max = lv_display_get_vertical_resolution(disp) - 1; + + data->point.x = LV_CLAMP(0, sample->point[0].x, hor_max); + data->point.y = LV_CLAMP(0, sample->point[0].y, ver_max); + touchscreen->last_state = LV_INDEV_STATE_PRESSED; + } + else if(touch_flags & TOUCH_UP) { + touchscreen->last_state = LV_INDEV_STATE_RELEASED; + } +} + +static bool touchscreen_read_sample(int fd, struct touch_sample_s * sample) +{ + int nbytes = read(fd, sample, sizeof(struct touch_sample_s)); + return nbytes == sizeof(struct touch_sample_s); +} + static void touchscreen_read(lv_indev_t * drv, lv_indev_data_t * data) { lv_nuttx_touchscreen_t * touchscreen = drv->driver_data; struct touch_sample_s sample; - /* Read one sample */ + /* + * Note: Since it is necessary to avoid multi-processing click events + * caused by redundant continue_reading, a two-unit sample sliding window + * algorithm is used here. continue_reading is only activated when there + * are two points in the window. + */ - int nbytes = read(touchscreen->fd, &sample, - sizeof(struct touch_sample_s)); - - /* Handle unexpected return values */ - - if(nbytes == sizeof(struct touch_sample_s)) { - uint8_t touch_flags = sample.point[0].flags; - - if(touch_flags & TOUCH_DOWN || touch_flags & TOUCH_MOVE) { - const lv_display_t * disp_drv = drv->disp; - int32_t ver_max = disp_drv->ver_res - 1; - int32_t hor_max = disp_drv->hor_res - 1; - - data->point.x = LV_CLAMP(0, sample.point[0].x, hor_max); - data->point.y = LV_CLAMP(0, sample.point[0].y, ver_max); - touchscreen->last_state = LV_INDEV_STATE_PRESSED; - } - else if(touch_flags & TOUCH_UP) { - touchscreen->last_state = LV_INDEV_STATE_RELEASED; + /* If has last sample, use it first */ + if(touchscreen->has_last_sample) { + conv_touch_sample(drv, data, &touchscreen->last_sample); + } + else { + /* Read first sample */ + if(!touchscreen_read_sample(touchscreen->fd, &sample)) { + /* No sample available, return last state */ + data->state = touchscreen->last_state; + return; } - /* Read until the last point */ + conv_touch_sample(drv, data, &sample); + } + /* Try to read next sample */ + if(touchscreen_read_sample(touchscreen->fd, &sample)) { + /* Save last sample and let lvgl continue reading */ + touchscreen->last_sample = sample; + touchscreen->has_last_sample = true; data->continue_reading = true; } + else { + /* No more sample available, clear last sample flag */ + touchscreen->has_last_sample = false; + } data->state = touchscreen->last_state; } diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.c b/lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.c new file mode 100644 index 000000000..f31e72710 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.c @@ -0,0 +1,542 @@ +/** + * @file lv_qnx.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_qnx.h" +#if LV_USE_QNX +#include +#include "../../core/lv_refr.h" +#include "../../stdlib/lv_string.h" +#include "../../core/lv_global.h" +#include "../../display/lv_display_private.h" +#include "../../lv_init.h" +#include +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + screen_window_t window; + screen_buffer_t buffers[LV_QNX_BUF_COUNT]; + int bufidx; + bool managed; + lv_indev_t * pointer; + lv_indev_t * keyboard; +} lv_qnx_window_t; + +typedef struct { + int pos[2]; + int buttons; +} lv_qnx_pointer_t; + +typedef struct { + int key; + int flags; +} lv_qnx_keyboard_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static uint32_t get_ticks(void); +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); +static bool window_create(lv_display_t * disp); +static bool init_display_from_window(lv_display_t * disp); +static void get_pointer(lv_indev_t * indev, lv_indev_data_t * data); +static void get_key(lv_indev_t * indev, lv_indev_data_t * data); +static bool handle_pointer_event(lv_display_t * disp, screen_event_t event); +static bool handle_keyboard_event(lv_display_t * disp, screen_event_t event); +static void release_disp_cb(lv_event_t * e); +static void refresh_cb(lv_timer_t * timer); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +static screen_context_t context; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_qnx_window_create(int32_t hor_res, int32_t ver_res) +{ + static bool inited = false; + + if(!inited) { + if(screen_create_context(&context, + SCREEN_APPLICATION_CONTEXT) != 0) { + LV_LOG_ERROR("screen_create_context: %s", strerror(errno)); + return NULL; + } + + lv_tick_set_cb(get_ticks); + inited = true; + } + + lv_qnx_window_t * dsc = lv_malloc_zeroed(sizeof(lv_qnx_window_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) return NULL; + + lv_display_t * disp = lv_display_create(hor_res, ver_res); + if(disp == NULL) { + lv_free(dsc); + return NULL; + } + lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp); + lv_display_set_driver_data(disp, dsc); + if(!window_create(disp)) { + lv_free(dsc); + return NULL; + } + + lv_display_set_flush_cb(disp, flush_cb); + + if(!init_display_from_window(disp)) { + screen_destroy_window(dsc->window); + lv_free(dsc); + return NULL; + } + + /*Replace the default refresh timer handler, so that we can run it on + *demand instead of constantly.*/ + lv_timer_t * refr_timer = lv_display_get_refr_timer(disp); + lv_timer_set_cb(refr_timer, refresh_cb); + + return disp; +} + +void lv_qnx_window_set_title(lv_display_t * disp, const char * title) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(!dsc->managed) { + /*Can't set title if there is no window manager*/ + return; + } + + screen_event_t event; + screen_create_event(&event); + + char title_buf[64]; + lv_snprintf(title_buf, sizeof(title_buf), "Title=%s", title); + + int type = SCREEN_EVENT_MANAGER; + screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type); + screen_set_event_property_cv(event, SCREEN_PROPERTY_USER_DATA, + sizeof(title_buf), title_buf); + screen_set_event_property_pv(event, SCREEN_PROPERTY_WINDOW, + (void **)&dsc->window); + screen_set_event_property_pv(event, SCREEN_PROPERTY_CONTEXT, + (void **)&context); + + screen_inject_event(NULL, event); +} + +bool lv_qnx_add_pointer_device(lv_display_t * disp) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->pointer != NULL) { + /*Only one pointer device per display*/ + return false; + } + + lv_qnx_pointer_t * ptr_dsc = lv_malloc_zeroed(sizeof(lv_qnx_pointer_t)); + LV_ASSERT_MALLOC(ptr_dsc); + if(ptr_dsc == NULL) { + return false; + } + + dsc->pointer = lv_indev_create(); + if(dsc->pointer == NULL) { + lv_free(ptr_dsc); + return false; + } + + lv_indev_set_type(dsc->pointer, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(dsc->pointer, get_pointer); + lv_indev_set_driver_data(dsc->pointer, ptr_dsc); + lv_indev_set_mode(dsc->pointer, LV_INDEV_MODE_EVENT); + return true; +} + +bool lv_qnx_add_keyboard_device(lv_display_t * disp) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->keyboard != NULL) { + /*Only one keyboard device per display*/ + return false; + } + + lv_qnx_keyboard_t * kbd_dsc = lv_malloc_zeroed(sizeof(lv_qnx_keyboard_t)); + LV_ASSERT_MALLOC(kbd_dsc); + if(dsc == NULL) { + return false; + } + + dsc->keyboard = lv_indev_create(); + if(dsc->keyboard == NULL) { + lv_free(kbd_dsc); + return false; + } + + lv_indev_set_type(dsc->keyboard, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(dsc->keyboard, get_key); + lv_indev_set_driver_data(dsc->keyboard, kbd_dsc); + lv_indev_set_mode(dsc->keyboard, LV_INDEV_MODE_EVENT); + return true; +} + +int lv_qnx_event_loop(lv_display_t * disp) +{ + lv_refr_now(disp); + + /*Run the event loop*/ + screen_event_t event; + if(screen_create_event(&event) != 0) { + LV_LOG_ERROR("screen_create_event: %s", strerror(errno)); + return EXIT_FAILURE; + } + + uint64_t timeout_ns = 0; + for(;;) { + /*Wait for an event, timing out after 16ms if animations are running*/ + if(screen_get_event(context, event, timeout_ns) != 0) { + LV_LOG_ERROR("screen_get_event: %s", strerror(errno)); + return EXIT_FAILURE; + } + + /*Get the event's type*/ + int type; + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(TYPE): %s", strerror(errno)); + return EXIT_FAILURE; + } + + if(type == SCREEN_EVENT_POINTER) { + if(!handle_pointer_event(disp, event)) { + return EXIT_FAILURE; + } + } + else if(type == SCREEN_EVENT_KEYBOARD) { + if(!handle_keyboard_event(disp, event)) { + return EXIT_FAILURE; + } + } + else if(type == SCREEN_EVENT_MANAGER) { + /*Only sub-type supported is closing the window*/ + break; + } + + /*Calculate the next timeout*/ + uint32_t timeout_ms = lv_timer_handler(); + if(timeout_ms == LV_NO_TIMER_READY) { + timeout_ns = -1ULL; + } + else { + timeout_ns = (uint64_t)timeout_ms * 1000000UL; + } + } + + return EXIT_SUCCESS; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static uint32_t get_ticks(void) +{ + uint64_t const ns = clock_gettime_mon_ns(); + return (uint32_t)(ns / 1000000UL); +} + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(screen_post_window(dsc->window, dsc->buffers[dsc->bufidx], 0, NULL, 0) + != 0) { + LV_LOG_ERROR("screen_post_window: %s", strerror(errno)); + } + +#if (LV_QNX_BUF_COUNT > 1) + dsc->bufidx = 1 - dsc->bufidx; +#endif + + lv_display_flush_ready(disp); +} + +static bool window_create(lv_display_t * disp) +{ + /*Create a window*/ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(screen_create_window(&dsc->window, context) != 0) { + LV_LOG_ERROR("screen_create_window: %s", strerror(errno)); + return false; + } + + /*Set window properties*/ + int rect[] = { 0, 0, disp->hor_res, disp->ver_res }; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_POSITION, + &rect[0]) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(POSITION): %s", strerror(errno)); + return false; + } + + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_SIZE, + &rect[2]) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(SIZE): %s", strerror(errno)); + return false; + } + + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_SOURCE_SIZE, + &rect[2]) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(SOURCE_SIZE): %s", strerror(errno)); + return NULL; + } + + int usage = SCREEN_USAGE_WRITE; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_USAGE, + &usage) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(USAGE): %s", strerror(errno)); + return NULL; + } + + int format = SCREEN_FORMAT_RGBA8888; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_FORMAT, + &format) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(USAGE): %s", strerror(errno)); + return NULL; + } + + /*Initialize window buffers*/ + if(screen_create_window_buffers(dsc->window, LV_QNX_BUF_COUNT) != 0) { + LV_LOG_ERROR("screen_create_window_buffers: %s", strerror(errno)); + return false; + } + + if(screen_get_window_property_pv(dsc->window, SCREEN_PROPERTY_BUFFERS, + (void **)&dsc->buffers) != 0) { + LV_LOG_ERROR("screen_get_window_property_pv(BUFFERS): %s", strerror(errno)); + return false; + } + + /*Connect to the window manager. Can legitimately fail if one is not running*/ + if(screen_manage_window(dsc->window, "Frame=Y") == 0) { + dsc->managed = true; + } + else { + dsc->managed = false; + } + + int visible = 1; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_VISIBLE, + &visible) != 0) { + LV_LOG_ERROR("screen_set_window_property_iv(VISIBLE): %s", strerror(errno)); + return false; + } + + return true; +} + +static bool init_display_from_window(lv_display_t * disp) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + + int bufsize; + if(screen_get_buffer_property_iv(dsc->buffers[0], SCREEN_PROPERTY_SIZE, + &bufsize) == -1) { + LV_LOG_ERROR("screen_get_buffer_property_iv(SIZE): %s", strerror(errno)); + return false; + } + + void * ptr1 = NULL; + if(screen_get_buffer_property_pv(dsc->buffers[0], SCREEN_PROPERTY_POINTER, + &ptr1) == -1) { + LV_LOG_ERROR("screen_get_buffer_property_pv(POINTER): %s", strerror(errno)); + return false; + } + + void * ptr2 = NULL; +#if (LV_QNX_BUF_COUNT > 1) + if(screen_get_buffer_property_pv(dsc->buffers[1], SCREEN_PROPERTY_POINTER, + &ptr2) == -1) { + LV_LOG_ERROR("screen_get_buffer_property_pv(POINTER): %s", strerror(errno)); + return false; + } +#endif + + lv_display_set_buffers(disp, ptr1, ptr2, bufsize, LV_DISPLAY_RENDER_MODE_FULL); + return true; +} + +static void release_disp_cb(lv_event_t * e) +{ + lv_display_t * disp = (lv_display_t *) lv_event_get_user_data(e); + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + + if(dsc->window != NULL) { + screen_destroy_window(dsc->window); + } + + if(dsc->pointer != NULL) { + lv_free(dsc->pointer); + } + + if(dsc->keyboard != NULL) { + lv_free(dsc->keyboard); + } + + lv_free(dsc); + lv_display_set_driver_data(disp, NULL); +} + +static void get_pointer(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_qnx_pointer_t * dsc = lv_indev_get_driver_data(indev); + + data->point.x = dsc->pos[0]; + data->point.y = dsc->pos[1]; + if((dsc->buttons & SCREEN_LEFT_MOUSE_BUTTON) != 0) { + data->state = LV_INDEV_STATE_PRESSED; + } + else { + data->state = LV_INDEV_STATE_RELEASED; + } +} + +static bool handle_pointer_event(lv_display_t * disp, screen_event_t event) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->pointer == NULL) return true; + + lv_qnx_pointer_t * ptr_dsc = lv_indev_get_driver_data(dsc->pointer); + + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, + ptr_dsc->pos) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(SOURCE_POSITION): %s", strerror(errno)); + return false; + } + + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, + &ptr_dsc->buttons) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(BUTTONS): %s", strerror(errno)); + return false; + } + + lv_indev_read(dsc->pointer); + return true; +} + +static void get_key(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_qnx_keyboard_t * dsc = lv_indev_get_driver_data(indev); + + if((dsc->flags & KEY_DOWN) != 0) { + data->state = LV_INDEV_STATE_PRESSED; + data->key = dsc->key; + } + else { + data->state = LV_INDEV_STATE_RELEASED; + } +} + +static bool handle_keyboard_event(lv_display_t * disp, screen_event_t event) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->keyboard == NULL) return true; + + lv_qnx_keyboard_t * kbd_dsc = lv_indev_get_driver_data(dsc->keyboard); + + /*Get event data*/ + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, + &kbd_dsc->flags) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(FLAGS): %s", strerror(errno)); + return false; + } + + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, + &kbd_dsc->key) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(SYM): %s", strerror(errno)); + return false; + } + + /*Translate special keys*/ + switch(kbd_dsc->key) { + case KEYCODE_UP: + kbd_dsc->key = LV_KEY_UP; + break; + + case KEYCODE_DOWN: + kbd_dsc->key = LV_KEY_DOWN; + break; + + case KEYCODE_LEFT: + kbd_dsc->key = LV_KEY_LEFT; + break; + + case KEYCODE_RIGHT: + kbd_dsc->key = LV_KEY_RIGHT; + break; + + case KEYCODE_RETURN: + kbd_dsc->key = LV_KEY_ENTER; + break; + + case KEYCODE_BACKSPACE: + kbd_dsc->key = LV_KEY_BACKSPACE; + break; + + case KEYCODE_HOME: + kbd_dsc->key = LV_KEY_HOME; + break; + + case KEYCODE_END: + kbd_dsc->key = LV_KEY_END; + break; + + case KEYCODE_DELETE: + kbd_dsc->key = LV_KEY_DEL; + break; + + default: + /*Ignore other non-ASCII keys, including modifiers*/ + if(kbd_dsc->key > 0xff) return true; + } + + lv_indev_read(dsc->keyboard); + return true; +} + +static void refresh_cb(lv_timer_t * timer) +{ + /*Refresh the window on timeout, but disable the timer. Any callback can + *re-enable it.*/ + lv_display_t * disp = timer->user_data; + lv_refr_now(disp); + lv_timer_pause(timer); +} + +#endif /*LV_USE_QNX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.h b/lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.h new file mode 100644 index 000000000..bb8f9409a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/qnx/lv_qnx.h @@ -0,0 +1,86 @@ +/** + * @file lv_qnx.h + * @brief LVGL driver for the QNX Screen compositing window manager + */ + +#ifndef LV_QNX_H +#define LV_QNX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_QNX + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a window to use as a display for LVGL. + * @param hor_res The horizontal resolution (size) of the window + * @param ver_res The vertical resolution (size) of the window + * @return A pointer to a new display object if successful, NULL otherwise + */ +lv_display_t * lv_qnx_window_create(int32_t hor_res, int32_t ver_res); + +/** + * Set the title of the window identified by the given display. + * @param disp The display object for the window + * @param title The new title to set + */ +void lv_qnx_window_set_title(lv_display_t * disp, const char * title); + +/** + * Create a pointer input device for the display. + * Only one pointer object is currently supported. + * @param disp The display object associated with the device + * @return true if successful, false otherwise + */ +bool lv_qnx_add_pointer_device(lv_display_t * disp); + +/** + * Create a keyboard input device for the display. + * Only one keyboard object is currently supported. + * @param disp The display object associated with the device + * @return true if successful, false otherwise + */ +bool lv_qnx_add_keyboard_device(lv_display_t * disp); + +/** + * Runs the event loop for the display. + * The function only returns in response to a close event. + * @param disp The display for the event loop + * @return Exit code + */ +int lv_qnx_event_loop(lv_display_t * disp); + +/********************** + * MACROS + **********************/ + +#endif /* LV_DRV_QNX */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_QNX_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_keyboard.c b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_keyboard.c index ebff6a130..0bb94d6e3 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_keyboard.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_keyboard.c @@ -9,10 +9,9 @@ #include "lv_sdl_keyboard.h" #if LV_USE_SDL -#include "../../indev/lv_indev.h" #include "../../core/lv_group.h" #include "../../stdlib/lv_string.h" -#include LV_SDL_INCLUDE_PATH +#include "lv_sdl_private.h" /********************* * DEFINES @@ -83,7 +82,7 @@ static void sdl_keyboard_read(lv_indev_t * indev, lv_indev_data_t * data) dev->dummy_read = true; data->state = LV_INDEV_STATE_PRESSED; data->key = dev->buf[0]; - memmove(dev->buf, dev->buf + 1, len); + lv_memmove(dev->buf, dev->buf + 1, len); } } @@ -99,7 +98,7 @@ static void release_indev_cb(lv_event_t * e) } } -void _lv_sdl_keyboard_handler(SDL_Event * event) +void lv_sdl_keyboard_handler(SDL_Event * event) { uint32_t win_id = UINT32_MAX; switch(event->type) { @@ -113,17 +112,18 @@ void _lv_sdl_keyboard_handler(SDL_Event * event) return; } - lv_display_t * disp = _lv_sdl_get_disp_from_win_id(win_id); + lv_display_t * disp = lv_sdl_get_disp_from_win_id(win_id); + /*Find a suitable indev*/ lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { - if(lv_indev_get_display(indev) == disp && lv_indev_get_type(indev) == LV_INDEV_TYPE_KEYPAD) { - break; + if(lv_indev_get_type(indev) == LV_INDEV_TYPE_KEYPAD) { + /*If disp is NULL for any reason use the first indev with the correct type*/ + if(disp == NULL || lv_indev_get_display(indev) == disp) break; } indev = lv_indev_get_next(indev); } - if(indev == NULL) return; lv_sdl_keyboard_t * dsc = lv_indev_get_driver_data(indev); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.c b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.c index a6c1c692a..98b4f695f 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.c @@ -11,8 +11,8 @@ #include "../../core/lv_group.h" #include "../../stdlib/lv_string.h" +#include "lv_sdl_private.h" -#include LV_SDL_INCLUDE_PATH /********************* * DEFINES *********************/ @@ -97,7 +97,7 @@ static void release_indev_cb(lv_event_t * e) } } -void _lv_sdl_mouse_handler(SDL_Event * event) +void lv_sdl_mouse_handler(SDL_Event * event) { uint32_t win_id = UINT32_MAX; switch(event->type) { @@ -127,13 +127,14 @@ void _lv_sdl_mouse_handler(SDL_Event * event) return; } - lv_display_t * disp = _lv_sdl_get_disp_from_win_id(win_id); + lv_display_t * disp = lv_sdl_get_disp_from_win_id(win_id); /*Find a suitable indev*/ lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { - if(lv_indev_get_display(indev) == disp && lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { - break; + if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { + /*If disp is NULL for any reason use the first indev with the correct type*/ + if(disp == NULL || lv_indev_get_display(indev) == disp) break; } indev = lv_indev_get_next(indev); } @@ -188,7 +189,7 @@ void _lv_sdl_mouse_handler(SDL_Event * event) case SDL_MOUSEWHEEL: #if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_CROWN #ifdef __EMSCRIPTEN__ - /*Escripten scales it wrong*/ + /*Emscripten scales it wrong*/ if(event->wheel.y < 0) dsc->diff++; if(event->wheel.y > 0) dsc->diff--; #else diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.h b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.h index 02e9b576d..ef60685f4 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mouse.h @@ -1,5 +1,5 @@ /** - * @file Lv_sdl_mouse.h + * @file lv_sdl_mouse.h * */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mousewheel.c b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mousewheel.c index f331e3788..b31a72309 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mousewheel.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_mousewheel.c @@ -10,9 +10,8 @@ #if LV_USE_SDL && LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER #include "../../core/lv_group.h" -#include "../../indev/lv_indev_private.h" #include "../../stdlib/lv_string.h" -#include LV_SDL_INCLUDE_PATH +#include "lv_sdl_private.h" /********************* * DEFINES @@ -84,7 +83,7 @@ static void release_indev_cb(lv_event_t * e) } } -void _lv_sdl_mousewheel_handler(SDL_Event * event) +void lv_sdl_mousewheel_handler(SDL_Event * event) { uint32_t win_id = UINT32_MAX; switch(event->type) { @@ -99,13 +98,14 @@ void _lv_sdl_mousewheel_handler(SDL_Event * event) return; } - lv_display_t * disp = _lv_sdl_get_disp_from_win_id(win_id); + lv_display_t * disp = lv_sdl_get_disp_from_win_id(win_id); /*Find a suitable indev*/ lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { - if(lv_indev_get_display(indev) == disp && lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) { - break; + if(lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) { + /*If disp is NULL for any reason use the first indev with the correct type*/ + if(disp == NULL || lv_indev_get_display(indev) == disp) break; } indev = lv_indev_get_next(indev); } @@ -116,7 +116,7 @@ void _lv_sdl_mousewheel_handler(SDL_Event * event) switch(event->type) { case SDL_MOUSEWHEEL: #ifdef __EMSCRIPTEN__ - /*Escripten scales it wrong*/ + /*Emscripten scales it wrong*/ if(event->wheel.y < 0) dsc->diff++; if(event->wheel.y > 0) dsc->diff--; #else diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_private.h new file mode 100644 index 000000000..1fd519bfa --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_private.h @@ -0,0 +1,49 @@ +/** + * @file lv_sdl_private.h + * + */ + +#ifndef LV_SDL_PRIVATE_H +#define LV_SDL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" + +#if LV_USE_SDL + +#include LV_SDL_INCLUDE_PATH + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_sdl_keyboard_handler(SDL_Event * event); +void lv_sdl_mouse_handler(SDL_Event * event); +void lv_sdl_mousewheel_handler(SDL_Event * event); +lv_display_t * lv_sdl_get_disp_from_win_id(uint32_t win_id); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SDL*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_SDL_PRIVATE_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c index b4300666f..8448e79d4 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.c @@ -12,18 +12,23 @@ #include "../../core/lv_refr.h" #include "../../stdlib/lv_string.h" #include "../../core/lv_global.h" +#include "../../display/lv_display_private.h" #include "../../lv_init.h" +#include "../../draw/lv_draw_buf.h" + +/* for aligned_alloc */ +#ifndef __USE_ISOC11 + #define __USE_ISOC11 +#endif +#include #define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ -#include LV_SDL_INCLUDE_PATH - -#if LV_USE_DRAW_SDL - #include -#endif +#include "lv_sdl_private.h" /********************* * DEFINES *********************/ +#define lv_deinit_in_progress LV_GLOBAL_DEFAULT()->deinit_in_progress /********************** * TYPEDEFS @@ -38,6 +43,8 @@ typedef struct { uint8_t * fb_act; uint8_t * buf1; uint8_t * buf2; + uint8_t * rotated_buf; + size_t rotated_buf_size; #endif uint8_t zoom; uint8_t ignore_size_chg; @@ -46,33 +53,25 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ +static inline int sdl_render_mode(void); static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); static void window_create(lv_display_t * disp); static void window_update(lv_display_t * disp); #if LV_USE_DRAW_SDL == 0 static void texture_resize(lv_display_t * disp); + static void * sdl_draw_buf_realloc_aligned(void * ptr, size_t new_size); + static void sdl_draw_buf_free(void * ptr); #endif static void sdl_event_handler(lv_timer_t * t); static void release_disp_cb(lv_event_t * e); - -/*********************** - * GLOBAL PROTOTYPES - ***********************/ -lv_display_t * _lv_sdl_get_disp_from_win_id(uint32_t win_id); -void _lv_sdl_mouse_handler(SDL_Event * event); -void _lv_sdl_mousewheel_handler(SDL_Event * event); -void _lv_sdl_keyboard_handler(SDL_Event * event); static void res_chg_event_cb(lv_event_t * e); -static bool inited = false; - /********************** * STATIC VARIABLES **********************/ +static bool inited = false; static lv_timer_t * event_handler_timer; -#define lv_deinit_in_progress LV_GLOBAL_DEFAULT()->deinit_in_progress - /********************** * MACROS **********************/ @@ -89,13 +88,6 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res) event_handler_timer = lv_timer_create(sdl_event_handler, 5, NULL); lv_tick_set_cb(SDL_GetTicks); -#if LV_USE_DRAW_SDL - if(!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { - fprintf(stderr, "could not initialize sdl2_image: %s\n", IMG_GetError()); - return NULL; - } -#endif - inited = true; } @@ -115,31 +107,35 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res) lv_display_set_flush_cb(disp, flush_cb); #if LV_USE_DRAW_SDL == 0 - if(LV_SDL_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) { - dsc->buf1 = malloc(32 * 1024); + if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { + dsc->buf1 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024); #if LV_SDL_BUF_COUNT == 2 - dsc->buf2 = malloc(32 * 1024); + dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024); #endif lv_display_set_buffers(disp, dsc->buf1, dsc->buf2, 32 * 1024, LV_DISPLAY_RENDER_MODE_PARTIAL); } /*LV_DISPLAY_RENDER_MODE_DIRECT or FULL */ else { - uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), + uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res, lv_display_get_color_format(disp)); - lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * lv_display_get_vertical_resolution(disp), + lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * disp->ver_res, LV_SDL_RENDER_MODE); } #else /*/*LV_USE_DRAW_SDL == 1*/ - uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), - lv_display_get_color_format(disp)); /*It will render directly to default Texture, so the buffer is not used, so just set something*/ - static uint8_t dummy_buf[1]; - lv_display_set_buffers(disp, dummy_buf, NULL, stride * lv_display_get_vertical_resolution(disp), - LV_SDL_RENDER_MODE); + static lv_draw_buf_t draw_buf; + static uint8_t dummy_buf; /*It won't be used as it will render to the SDL textures directly*/ + lv_draw_buf_init(&draw_buf, 4096, 4096, LV_COLOR_FORMAT_ARGB8888, 4096 * 4, &dummy_buf, 4096 * 4096 * 4); + + lv_display_set_draw_buffers(disp, &draw_buf, NULL); + lv_display_set_render_mode(disp, LV_DISPLAY_RENDER_MODE_DIRECT); #endif /*LV_USE_DRAW_SDL == 0*/ lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + /*Process the initial events*/ + sdl_event_handler(NULL); + return disp; } @@ -163,7 +159,7 @@ uint8_t lv_sdl_window_get_zoom(lv_display_t * disp) return dsc->zoom; } -lv_display_t * _lv_sdl_get_disp_from_win_id(uint32_t win_id) +lv_display_t * lv_sdl_get_disp_from_win_id(uint32_t win_id) { lv_display_t * disp = lv_display_get_next(NULL); if(win_id == UINT32_MAX) return disp; @@ -190,7 +186,7 @@ void * lv_sdl_window_get_renderer(lv_display_t * disp) return dsc->renderer; } -void lv_sdl_quit() +void lv_sdl_quit(void) { if(inited) { SDL_Quit(); @@ -204,34 +200,83 @@ void lv_sdl_quit() * STATIC FUNCTIONS **********************/ +static inline int sdl_render_mode(void) +{ + return LV_SDL_RENDER_MODE; +} + static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) { #if LV_USE_DRAW_SDL == 0 + lv_area_t rotated_area; lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); - if(LV_SDL_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) { - int32_t y; + lv_color_format_t cf = lv_display_get_color_format(disp); + + if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { + lv_display_rotation_t rotation = lv_display_get_rotation(disp); + uint32_t px_size = lv_color_format_get_size(cf); + + if(rotation != LV_DISPLAY_ROTATION_0) { + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + uint32_t w_stride = lv_draw_buf_width_to_stride(w, cf); + uint32_t h_stride = lv_draw_buf_width_to_stride(h, cf); + size_t buf_size = w * h * px_size; + + /* (Re)allocate temporary buffer if needed */ + if(!dsc->rotated_buf || dsc->rotated_buf_size != buf_size) { + dsc->rotated_buf = sdl_draw_buf_realloc_aligned(dsc->rotated_buf, buf_size); + dsc->rotated_buf_size = buf_size; + } + + switch(rotation) { + case LV_DISPLAY_ROTATION_0: + break; + case LV_DISPLAY_ROTATION_90: + lv_draw_sw_rotate(px_map, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf); + break; + case LV_DISPLAY_ROTATION_180: + lv_draw_sw_rotate(px_map, dsc->rotated_buf, w, h, w_stride, w_stride, rotation, cf); + break; + case LV_DISPLAY_ROTATION_270: + lv_draw_sw_rotate(px_map, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf); + break; + } + + px_map = dsc->rotated_buf; + + rotated_area = *area; + lv_display_rotate_area(disp, &rotated_area); + area = &rotated_area; + } + + uint32_t px_map_stride = lv_draw_buf_width_to_stride(lv_area_get_width(area), cf); + uint32_t px_map_line_bytes = lv_area_get_width(area) * px_size; + uint8_t * fb_tmp = dsc->fb_act; - uint32_t px_size = lv_color_format_get_size(lv_display_get_color_format(disp)); - uint32_t px_map_stride = lv_draw_buf_width_to_stride(lv_area_get_width(area), lv_display_get_color_format(disp)); - uint32_t data_size = lv_area_get_width(area) * px_size; - int32_t fb_stride = lv_display_get_horizontal_resolution(disp) * px_size; + uint32_t fb_stride = disp->hor_res * px_size; fb_tmp += area->y1 * fb_stride; fb_tmp += area->x1 * px_size; + + int32_t y; for(y = area->y1; y <= area->y2; y++) { - lv_memcpy(fb_tmp, px_map, data_size); + lv_memcpy(fb_tmp, px_map, px_map_line_bytes); px_map += px_map_stride; fb_tmp += fb_stride; } } + /* TYPICALLY YOU DO NOT NEED THIS * If it was the last part to refresh update the texture of the window.*/ if(lv_display_flush_is_last(disp)) { - if(LV_SDL_RENDER_MODE != LV_DISPLAY_RENDER_MODE_PARTIAL) { + if(sdl_render_mode() != LV_DISPLAY_RENDER_MODE_PARTIAL) { dsc->fb_act = px_map; } window_update(disp); } #else + LV_UNUSED(area); + LV_UNUSED(px_map); if(lv_display_flush_is_last(disp)) { window_update(disp); } @@ -252,17 +297,16 @@ static void sdl_event_handler(lv_timer_t * t) /*Refresh handling*/ SDL_Event event; while(SDL_PollEvent(&event)) { - _lv_sdl_mouse_handler(&event); + lv_sdl_mouse_handler(&event); #if LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER - _lv_sdl_mousewheel_handler(&event); + lv_sdl_mousewheel_handler(&event); #endif - _lv_sdl_keyboard_handler(&event); + lv_sdl_keyboard_handler(&event); if(event.type == SDL_WINDOWEVENT) { - lv_display_t * disp = _lv_sdl_get_disp_from_win_id(event.window.windowID); + lv_display_t * disp = lv_sdl_get_disp_from_win_id(event.window.windowID); if(disp == NULL) continue; lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); - switch(event.window.event) { #if SDL_VERSION_ATLEAST(2, 0, 5) case SDL_WINDOWEVENT_TAKE_FOCUS: @@ -304,13 +348,14 @@ static void window_create(lv_display_t * disp) flag |= SDL_WINDOW_FULLSCREEN; #endif - int32_t hor_res = lv_display_get_horizontal_resolution(disp); - int32_t ver_res = lv_display_get_vertical_resolution(disp); + int32_t hor_res = disp->hor_res; + int32_t ver_res = disp->ver_res; dsc->window = SDL_CreateWindow("LVGL Simulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, hor_res * dsc->zoom, ver_res * dsc->zoom, flag); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/ - dsc->renderer = SDL_CreateRenderer(dsc->window, -1, SDL_RENDERER_SOFTWARE); + dsc->renderer = SDL_CreateRenderer(dsc->window, -1, + LV_SDL_ACCELERATED ? SDL_RENDERER_ACCELERATED : SDL_RENDERER_SOFTWARE); #if LV_USE_DRAW_SDL == 0 texture_resize(disp); @@ -331,7 +376,7 @@ static void window_update(lv_display_t * disp) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); #if LV_USE_DRAW_SDL == 0 - int32_t hor_res = lv_display_get_horizontal_resolution(disp); + int32_t hor_res = disp->hor_res; uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_display_get_color_format(disp)); SDL_UpdateTexture(dsc->texture, NULL, dsc->fb_act, stride); @@ -346,23 +391,21 @@ static void window_update(lv_display_t * disp) #if LV_USE_DRAW_SDL == 0 static void texture_resize(lv_display_t * disp) { - int32_t hor_res = lv_display_get_horizontal_resolution(disp); - int32_t ver_res = lv_display_get_vertical_resolution(disp); - uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_display_get_color_format(disp)); + uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res, lv_display_get_color_format(disp)); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); - dsc->fb1 = realloc(dsc->fb1, stride * ver_res); - memset(dsc->fb1, 0x00, stride * ver_res); + dsc->fb1 = sdl_draw_buf_realloc_aligned(dsc->fb1, stride * disp->ver_res); + lv_memzero(dsc->fb1, stride * disp->ver_res); - if(LV_SDL_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) { + if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { dsc->fb_act = dsc->fb1; } else { #if LV_SDL_BUF_COUNT == 2 - dsc->fb2 = realloc(dsc->fb2, stride * ver_res); - memset(dsc->fb2, 0x00, stride * ver_res); + dsc->fb2 = sdl_draw_buf_realloc_aligned(dsc->fb2, stride * disp->ver_res); + memset(dsc->fb2, 0x00, stride * disp->ver_res); #endif - lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * ver_res, LV_SDL_RENDER_MODE); + lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * disp->ver_res, LV_SDL_RENDER_MODE); } if(dsc->texture) SDL_DestroyTexture(dsc->texture); @@ -379,20 +422,45 @@ static void texture_resize(lv_display_t * disp) // px_format = SDL_PIXELFORMAT_BGR24; dsc->texture = SDL_CreateTexture(dsc->renderer, px_format, - SDL_TEXTUREACCESS_STATIC, hor_res, ver_res); + SDL_TEXTUREACCESS_STATIC, disp->hor_res, disp->ver_res); SDL_SetTextureBlendMode(dsc->texture, SDL_BLENDMODE_BLEND); } + +static void * sdl_draw_buf_realloc_aligned(void * ptr, size_t new_size) +{ + if(ptr) { + sdl_draw_buf_free(ptr); + } + + /* No need copy for drawing buffer */ + +#ifndef _WIN32 + /* Size must be multiple of align, See: https://en.cppreference.com/w/c/memory/aligned_alloc */ + +#define BUF_ALIGN (LV_DRAW_BUF_ALIGN < sizeof(void *) ? sizeof(void *) : LV_DRAW_BUF_ALIGN) + return aligned_alloc(BUF_ALIGN, LV_ALIGN_UP(new_size, BUF_ALIGN)); +#else + return _aligned_malloc(LV_ALIGN_UP(new_size, LV_DRAW_BUF_ALIGN), LV_DRAW_BUF_ALIGN); +#endif /* _WIN32 */ +} + +static void sdl_draw_buf_free(void * ptr) +{ +#ifndef _WIN32 + free(ptr); +#else + _aligned_free(ptr); +#endif /* _WIN32 */ +} #endif static void res_chg_event_cb(lv_event_t * e) { lv_display_t * disp = lv_event_get_current_target(e); - int32_t hor_res = lv_display_get_horizontal_resolution(disp); - int32_t ver_res = lv_display_get_vertical_resolution(disp); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); if(dsc->ignore_size_chg == false) { - SDL_SetWindowSize(dsc->window, hor_res * dsc->zoom, ver_res * dsc->zoom); + SDL_SetWindowSize(dsc->window, disp->hor_res * dsc->zoom, disp->ver_res * dsc->zoom); } #if LV_USE_DRAW_SDL == 0 @@ -415,10 +483,10 @@ static void release_disp_cb(lv_event_t * e) SDL_DestroyRenderer(dsc->renderer); SDL_DestroyWindow(dsc->window); #if LV_USE_DRAW_SDL == 0 - if(dsc->fb1) free(dsc->fb1); - if(dsc->fb2) free(dsc->fb2); - if(dsc->buf1) free(dsc->buf1); - if(dsc->buf2) free(dsc->buf2); + if(dsc->fb1) sdl_draw_buf_free(dsc->fb1); + if(dsc->fb2) sdl_draw_buf_free(dsc->fb2); + if(dsc->buf1) sdl_draw_buf_free(dsc->buf1); + if(dsc->buf2) sdl_draw_buf_free(dsc->buf2); #endif lv_free(dsc); lv_display_set_driver_data(disp, NULL); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.h b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.h index 4a3901fdc..f2e243cdd 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/sdl/lv_sdl_window.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_SDL_DISP_H -#define LV_SDL_DISP_H +#ifndef LV_SDL_WINDOW_H +#define LV_SDL_WINDOW_H #ifdef __cplusplus extern "C" { @@ -43,13 +43,11 @@ void lv_sdl_window_set_zoom(lv_display_t * disp, uint8_t zoom); uint8_t lv_sdl_window_get_zoom(lv_display_t * disp); -lv_display_t * _lv_sdl_get_disp_from_win_id(uint32_t win_id); - void lv_sdl_window_set_title(lv_display_t * disp, const char * title); void * lv_sdl_window_get_renderer(lv_display_t * disp); -void lv_sdl_quit(); +void lv_sdl_quit(void); /********************** * MACROS @@ -61,4 +59,4 @@ void lv_sdl_quit(); } /* extern "C" */ #endif -#endif /* LV_SDL_DISP_H */ +#endif /* LV_SDL_WINDOW_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c new file mode 100644 index 000000000..dc71f6677 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c @@ -0,0 +1,2860 @@ +/******************************************************************* + * + * @file lv_wayland.c - The Wayland client for LVGL applications + * + * Based on the original file from the repository. + * + * Porting to LVGL 9.1 + * EDGEMTech Ltd. by Erik Tagirov (erik.tagirov@edgemtech.ch) + * + * See LICENCE.txt for details + * + ******************************************************************/ + +typedef int dummy_t; /* Make GCC on windows happy, avoid empty translation unit */ + +#ifndef _WIN32 + +/********************* + * INCLUDES + *********************/ +#include "lv_wayland.h" +#include "lv_wayland_smm.h" + +#if LV_USE_WAYLAND + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lvgl.h" + + +#if !LV_WAYLAND_WL_SHELL + #include "wayland_xdg_shell.h" + #define LV_WAYLAND_XDG_SHELL 1 +#else + #define LV_WAYLAND_XDG_SHELL 0 +#endif + + +/********************* + * DEFINES + *********************/ + +#define LVGL_DRAW_BUFFER_DIV (8) +#define DMG_CACHE_CAPACITY (32) +#define TAG_LOCAL (0) +#define TAG_BUFFER_DAMAGE (1) + +#if LV_WAYLAND_WINDOW_DECORATIONS + #define TITLE_BAR_HEIGHT 24 + #define BORDER_SIZE 2 + #define BUTTON_MARGIN LV_MAX((TITLE_BAR_HEIGHT / 6), BORDER_SIZE) + #define BUTTON_PADDING LV_MAX((TITLE_BAR_HEIGHT / 8), BORDER_SIZE) + #define BUTTON_SIZE (TITLE_BAR_HEIGHT - (2 * BUTTON_MARGIN)) +#endif + +#ifndef LV_WAYLAND_CYCLE_PERIOD + #define LV_WAYLAND_CYCLE_PERIOD LV_MIN(LV_DEF_REFR_PERIOD,1) +#endif + +#define SHM_FORMAT_UNKNOWN 0xFFFFFF + +#if (LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1) + #error [wayland] Unsupported LV_COLOR_DEPTH +#endif + +/********************** + * TYPEDEFS + **********************/ + +enum object_type { + OBJECT_TITLEBAR = 0, + OBJECT_BUTTON_CLOSE, +#if LV_WAYLAND_XDG_SHELL + OBJECT_BUTTON_MAXIMIZE, + OBJECT_BUTTON_MINIMIZE, +#endif + OBJECT_BORDER_TOP, + OBJECT_BORDER_BOTTOM, + OBJECT_BORDER_LEFT, + OBJECT_BORDER_RIGHT, + OBJECT_WINDOW, +}; + +#define FIRST_DECORATION (OBJECT_TITLEBAR) +#define LAST_DECORATION (OBJECT_BORDER_RIGHT) +#define NUM_DECORATIONS (LAST_DECORATION-FIRST_DECORATION+1) + +struct window; +struct input { + struct { + uint32_t x; + uint32_t y; + lv_indev_state_t left_button; + lv_indev_state_t right_button; + lv_indev_state_t wheel_button; + int16_t wheel_diff; + } pointer; + + struct { + lv_key_t key; + lv_indev_state_t state; + } keyboard; + + struct { + uint32_t x; + uint32_t y; + lv_indev_state_t state; + } touch; +}; + +struct seat { + struct wl_touch * wl_touch; + struct wl_pointer * wl_pointer; + struct wl_keyboard * wl_keyboard; + + struct { + struct xkb_keymap * keymap; + struct xkb_state * state; + } xkb; +}; + +struct graphic_object { + struct window * window; + + struct wl_surface * surface; + bool surface_configured; + smm_buffer_t * pending_buffer; + smm_group_t * buffer_group; + struct wl_subsurface * subsurface; + + enum object_type type; + int width; + int height; + + struct input input; +}; + +struct application { + struct wl_display * display; + struct wl_registry * registry; + struct wl_compositor * compositor; + struct wl_subcompositor * subcompositor; + struct wl_shm * shm; + struct wl_seat * wl_seat; + + struct wl_cursor_theme * cursor_theme; + struct wl_surface * cursor_surface; + +#if LV_WAYLAND_WL_SHELL + struct wl_shell * wl_shell; +#endif + +#if LV_WAYLAND_XDG_SHELL + struct xdg_wm_base * xdg_wm; +#endif + + const char * xdg_runtime_dir; + +#ifdef LV_WAYLAND_WINDOW_DECORATIONS + bool opt_disable_decorations; +#endif + + uint32_t shm_format; + + struct xkb_context * xkb_context; + + struct seat seat; + + struct graphic_object * touch_obj; + struct graphic_object * pointer_obj; + struct graphic_object * keyboard_obj; + + lv_ll_t window_ll; + lv_timer_t * cycle_timer; + + bool cursor_flush_pending; + struct pollfd wayland_pfd; +}; + +struct window { + lv_display_t * lv_disp; + lv_draw_buf_t * lv_disp_draw_buf; + + lv_indev_t * lv_indev_pointer; + lv_indev_t * lv_indev_pointeraxis; + lv_indev_t * lv_indev_touch; + lv_indev_t * lv_indev_keyboard; + + lv_wayland_display_close_f_t close_cb; + + struct application * application; + +#if LV_WAYLAND_WL_SHELL + struct wl_shell_surface * wl_shell_surface; +#endif + +#if LV_WAYLAND_XDG_SHELL + struct xdg_surface * xdg_surface; + struct xdg_toplevel * xdg_toplevel; + uint32_t wm_capabilities; +#endif + + struct graphic_object * body; + struct { + lv_area_t cache[DMG_CACHE_CAPACITY]; + unsigned char start; + unsigned char end; + unsigned size; + } dmg_cache; + +#if LV_WAYLAND_WINDOW_DECORATIONS + struct graphic_object * decoration[NUM_DECORATIONS]; +#endif + + int width; + int height; + + bool resize_pending; + int resize_width; + int resize_height; + + bool flush_pending; + bool shall_close; + bool closed; + bool maximized; + bool fullscreen; + uint32_t frame_counter; + bool frame_done; +}; + +/********************************* + * STATIC VARIABLES and FUNTIONS + *********************************/ + +static struct application application; + +static void color_fill(void * pixels, lv_color_t color, uint32_t width, uint32_t height); +static void color_fill_XRGB8888(void * pixels, lv_color_t color, uint32_t width, uint32_t height); +static void color_fill_RGB565(void * pixels, lv_color_t color, uint32_t width, uint32_t height); + +static const struct wl_callback_listener wl_surface_frame_listener; +static bool resize_window(struct window * window, int width, int height); +static struct graphic_object * create_graphic_obj(struct application * app, struct window * window, + enum object_type type, + struct graphic_object * parent); + +static uint32_t tick_get_cb(void); + +static void wayland_init(void); +static void wayland_deinit(void); + +/** + * The frame callback called when the compositor has finished rendering + * a frame.It increments the frame counter and sets up the callback + * for the next frame the frame counter is used to avoid needlessly + * committing frames too fast on a slow system + * + * NOTE: this function is invoked by the wayland-server library within the compositor + * the event is added to the queue, and then upon the next timer call it's + * called indirectly from _lv_wayland_handle_input (via wl_display_dispatch_queue) + * @param void data the user object defined that was tied to this event during + * the configuration of the callback + * @param struct wl_callback The callback that needs to be destroyed and re-created + * @param time Timestamp of the event (unused) + */ +static void graphic_obj_frame_done(void * data, struct wl_callback * cb, uint32_t time) +{ + struct graphic_object * obj; + struct window * window; + + LV_UNUSED(time); + + wl_callback_destroy(cb); + + obj = (struct graphic_object *)data; + window = obj->window; + window->frame_counter++; + + LV_LOG_TRACE("frame: %d done, new frame: %d", + window->frame_counter - 1, window->frame_counter); + + window->frame_done = true; + +} + +static const struct wl_callback_listener wl_surface_frame_listener = { + .done = graphic_obj_frame_done, +}; + +static inline bool _is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + +/* + * shm_format + * @description called by the compositor to advertise the supported + * color formats for SHM buffers, there is a call per supported format + */ +static void shm_format(void * data, struct wl_shm * wl_shm, uint32_t format) +{ + struct application * app = data; + + LV_UNUSED(wl_shm); + + LV_LOG_TRACE("Supported color space fourcc.h code: %08X", format); + + if(LV_COLOR_DEPTH == 32 && format == WL_SHM_FORMAT_ARGB8888) { + + /* Wayland compositors MUST support ARGB8888 */ + app->shm_format = format; + + } + else if(LV_COLOR_DEPTH == 32 && + format == WL_SHM_FORMAT_XRGB8888 && + app->shm_format != WL_SHM_FORMAT_ARGB8888) { + + /* Select XRGB only if the compositor doesn't support transprancy */ + app->shm_format = format; + + } + else if(LV_COLOR_DEPTH == 16 && format == WL_SHM_FORMAT_RGB565) { + + app->shm_format = format; + + } +} + +static const struct wl_shm_listener shm_listener = { + shm_format +}; + +static void pointer_handle_enter(void * data, struct wl_pointer * pointer, + uint32_t serial, struct wl_surface * surface, + wl_fixed_t sx, wl_fixed_t sy) +{ + struct application * app = data; + const char * cursor = "left_ptr"; + int pos_x = wl_fixed_to_int(sx); + int pos_y = wl_fixed_to_int(sy); + + if(!surface) { + app->pointer_obj = NULL; + return; + } + + app->pointer_obj = wl_surface_get_user_data(surface); + + app->pointer_obj->input.pointer.x = pos_x; + app->pointer_obj->input.pointer.y = pos_y; + +#if (LV_WAYLAND_WINDOW_DECORATIONS && LV_WAYLAND_XDG_SHELL) + if(!app->pointer_obj->window->xdg_toplevel || app->opt_disable_decorations) { + return; + } + + struct window * window = app->pointer_obj->window; + + switch(app->pointer_obj->type) { + case OBJECT_BORDER_TOP: + if(window->maximized) { + // do nothing + } + else if(pos_x < (BORDER_SIZE * 5)) { + cursor = "top_left_corner"; + } + else if(pos_x >= (window->width + BORDER_SIZE - (BORDER_SIZE * 5))) { + cursor = "top_right_corner"; + } + else { + cursor = "top_side"; + } + break; + case OBJECT_BORDER_BOTTOM: + if(window->maximized) { + // do nothing + } + else if(pos_x < (BORDER_SIZE * 5)) { + cursor = "bottom_left_corner"; + } + else if(pos_x >= (window->width + BORDER_SIZE - (BORDER_SIZE * 5))) { + cursor = "bottom_right_corner"; + } + else { + cursor = "bottom_side"; + } + break; + case OBJECT_BORDER_LEFT: + if(window->maximized) { + // do nothing + } + else if(pos_y < (BORDER_SIZE * 5)) { + cursor = "top_left_corner"; + } + else if(pos_y >= (window->height + BORDER_SIZE - (BORDER_SIZE * 5))) { + cursor = "bottom_left_corner"; + } + else { + cursor = "left_side"; + } + break; + case OBJECT_BORDER_RIGHT: + if(window->maximized) { + // do nothing + } + else if(pos_y < (BORDER_SIZE * 5)) { + cursor = "top_right_corner"; + } + else if(pos_y >= (window->height + BORDER_SIZE - (BORDER_SIZE * 5))) { + cursor = "bottom_right_corner"; + } + else { + cursor = "right_side"; + } + break; + default: + break; + } +#endif + + if(app->cursor_surface) { + struct wl_cursor_image * cursor_image = wl_cursor_theme_get_cursor(app->cursor_theme, cursor)->images[0]; + wl_pointer_set_cursor(pointer, serial, app->cursor_surface, cursor_image->hotspot_x, cursor_image->hotspot_y); + wl_surface_attach(app->cursor_surface, wl_cursor_image_get_buffer(cursor_image), 0, 0); + wl_surface_damage(app->cursor_surface, 0, 0, cursor_image->width, cursor_image->height); + wl_surface_commit(app->cursor_surface); + app->cursor_flush_pending = true; + } +} + +static void pointer_handle_leave(void * data, struct wl_pointer * pointer, + uint32_t serial, struct wl_surface * surface) +{ + struct application * app = data; + + LV_UNUSED(pointer); + LV_UNUSED(serial); + + if(!surface || (app->pointer_obj == wl_surface_get_user_data(surface))) { + app->pointer_obj = NULL; + } +} + +static void pointer_handle_motion(void * data, struct wl_pointer * pointer, + uint32_t time, wl_fixed_t sx, wl_fixed_t sy) +{ + struct application * app = data; + + LV_UNUSED(pointer); + LV_UNUSED(time); + + if(!app->pointer_obj) { + return; + } + + app->pointer_obj->input.pointer.x = LV_MAX(0, LV_MIN(wl_fixed_to_int(sx), app->pointer_obj->width - 1)); + app->pointer_obj->input.pointer.y = LV_MAX(0, LV_MIN(wl_fixed_to_int(sy), app->pointer_obj->height - 1)); +} + +static void pointer_handle_button(void * data, struct wl_pointer * wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, + uint32_t state) +{ + struct application * app = data; + + LV_UNUSED(serial); + LV_UNUSED(wl_pointer); + LV_UNUSED(time); + + const lv_indev_state_t lv_state = + (state == WL_POINTER_BUTTON_STATE_PRESSED) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + + if(!app->pointer_obj) { + return; + } + + +#if LV_WAYLAND_WINDOW_DECORATIONS + struct window * window; + window = app->pointer_obj->window; + int pos_x = app->pointer_obj->input.pointer.x; + int pos_y = app->pointer_obj->input.pointer.y; +#endif + + switch(app->pointer_obj->type) { + case OBJECT_WINDOW: + switch(button) { + case BTN_LEFT: + app->pointer_obj->input.pointer.left_button = lv_state; + break; + case BTN_RIGHT: + app->pointer_obj->input.pointer.right_button = lv_state; + break; + case BTN_MIDDLE: + app->pointer_obj->input.pointer.wheel_button = lv_state; + break; + default: + break; + } + + break; +#if LV_WAYLAND_WINDOW_DECORATIONS + case OBJECT_TITLEBAR: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { +#if LV_WAYLAND_XDG_SHELL + if(window->xdg_toplevel) { + xdg_toplevel_move(window->xdg_toplevel, app->wl_seat, serial); + window->flush_pending = true; + } +#endif +#if LV_WAYLAND_WL_SHELL + if(window->wl_shell_surface) { + wl_shell_surface_move(window->wl_shell_surface, app->wl_seat, serial); + window->flush_pending = true; + } +#endif + } + break; + case OBJECT_BUTTON_CLOSE: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_RELEASED)) { + window->shall_close = true; + } + break; +#if LV_WAYLAND_XDG_SHELL + case OBJECT_BUTTON_MAXIMIZE: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_RELEASED)) { + if(window->xdg_toplevel) { + if(window->maximized) { + xdg_toplevel_unset_maximized(window->xdg_toplevel); + } + else { + xdg_toplevel_set_maximized(window->xdg_toplevel); + } + window->maximized ^= true; + window->flush_pending = true; + } + } + break; + case OBJECT_BUTTON_MINIMIZE: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_RELEASED)) { + if(window->xdg_toplevel) { + xdg_toplevel_set_minimized(window->xdg_toplevel); + window->flush_pending = true; + } + } + break; + case OBJECT_BORDER_TOP: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { + if(window->xdg_toplevel && !window->maximized) { + uint32_t edge; + if(pos_x < (BORDER_SIZE * 5)) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; + } + else if(pos_x >= (window->width + BORDER_SIZE - (BORDER_SIZE * 5))) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; + } + else { + edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP; + } + xdg_toplevel_resize(window->xdg_toplevel, + window->application->wl_seat, serial, edge); + window->flush_pending = true; + } + } + break; + case OBJECT_BORDER_BOTTOM: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { + if(window->xdg_toplevel && !window->maximized) { + uint32_t edge; + if(pos_x < (BORDER_SIZE * 5)) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; + } + else if(pos_x >= (window->width + BORDER_SIZE - (BORDER_SIZE * 5))) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; + } + else { + edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; + } + xdg_toplevel_resize(window->xdg_toplevel, + window->application->wl_seat, serial, edge); + window->flush_pending = true; + } + } + break; + case OBJECT_BORDER_LEFT: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { + if(window->xdg_toplevel && !window->maximized) { + uint32_t edge; + if(pos_y < (BORDER_SIZE * 5)) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; + } + else if(pos_y >= (window->height + BORDER_SIZE - (BORDER_SIZE * 5))) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; + } + else { + edge = XDG_TOPLEVEL_RESIZE_EDGE_LEFT; + } + xdg_toplevel_resize(window->xdg_toplevel, + window->application->wl_seat, serial, edge); + window->flush_pending = true; + } + } + break; + case OBJECT_BORDER_RIGHT: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { + if(window->xdg_toplevel && !window->maximized) { + uint32_t edge; + if(pos_y < (BORDER_SIZE * 5)) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; + } + else if(pos_y >= (window->height + BORDER_SIZE - (BORDER_SIZE * 5))) { + edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; + } + else { + edge = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; + } + xdg_toplevel_resize(window->xdg_toplevel, + window->application->wl_seat, serial, edge); + window->flush_pending = true; + } + } + break; +#endif // LV_WAYLAND_XDG_SHELL +#endif // LV_WAYLAND_WINDOW_DECORATIONS + default: + break; + } +} + +static void pointer_handle_axis(void * data, struct wl_pointer * wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ + struct application * app = data; + const int diff = wl_fixed_to_int(value); + + LV_UNUSED(time); + LV_UNUSED(wl_pointer); + + if(!app->pointer_obj) { + return; + } + + if(axis == 0) { + if(diff > 0) { + app->pointer_obj->input.pointer.wheel_diff++; + } + else if(diff < 0) { + app->pointer_obj->input.pointer.wheel_diff--; + } + } +} + +static const struct wl_pointer_listener pointer_listener = { + .enter = pointer_handle_enter, + .leave = pointer_handle_leave, + .motion = pointer_handle_motion, + .button = pointer_handle_button, + .axis = pointer_handle_axis, +}; + +static lv_key_t keycode_xkb_to_lv(xkb_keysym_t xkb_key) +{ + lv_key_t key = 0; + + if(((xkb_key >= XKB_KEY_space) && (xkb_key <= XKB_KEY_asciitilde))) { + key = xkb_key; + } + else if(((xkb_key >= XKB_KEY_KP_0) && (xkb_key <= XKB_KEY_KP_9))) { + key = (xkb_key & 0x003f); + } + else { + switch(xkb_key) { + case XKB_KEY_BackSpace: + key = LV_KEY_BACKSPACE; + break; + case XKB_KEY_Return: + case XKB_KEY_KP_Enter: + key = LV_KEY_ENTER; + break; + case XKB_KEY_Escape: + key = LV_KEY_ESC; + break; + case XKB_KEY_Delete: + case XKB_KEY_KP_Delete: + key = LV_KEY_DEL; + break; + case XKB_KEY_Home: + case XKB_KEY_KP_Home: + key = LV_KEY_HOME; + break; + case XKB_KEY_Left: + case XKB_KEY_KP_Left: + key = LV_KEY_LEFT; + break; + case XKB_KEY_Up: + case XKB_KEY_KP_Up: + key = LV_KEY_UP; + break; + case XKB_KEY_Right: + case XKB_KEY_KP_Right: + key = LV_KEY_RIGHT; + break; + case XKB_KEY_Down: + case XKB_KEY_KP_Down: + key = LV_KEY_DOWN; + break; + case XKB_KEY_Prior: + case XKB_KEY_KP_Prior: + key = LV_KEY_PREV; + break; + case XKB_KEY_Next: + case XKB_KEY_KP_Next: + case XKB_KEY_Tab: + case XKB_KEY_KP_Tab: + key = LV_KEY_NEXT; + break; + case XKB_KEY_End: + case XKB_KEY_KP_End: + key = LV_KEY_END; + break; + default: + break; + } + } + + return key; +} + +static void keyboard_handle_keymap(void * data, struct wl_keyboard * keyboard, + uint32_t format, int fd, uint32_t size) +{ + struct application * app = data; + + struct xkb_keymap * keymap; + struct xkb_state * state; + char * map_str; + + LV_UNUSED(keyboard); + + if(format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + map_str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + if(map_str == MAP_FAILED) { + close(fd); + return; + } + + /* Set up XKB keymap */ + keymap = xkb_keymap_new_from_string(app->xkb_context, map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, 0); + munmap(map_str, size); + close(fd); + + if(!keymap) { + LV_LOG_ERROR("failed to compile keymap"); + return; + } + + /* Set up XKB state */ + state = xkb_state_new(keymap); + if(!state) { + LV_LOG_ERROR("failed to create XKB state"); + xkb_keymap_unref(keymap); + return; + } + + xkb_keymap_unref(app->seat.xkb.keymap); + xkb_state_unref(app->seat.xkb.state); + app->seat.xkb.keymap = keymap; + app->seat.xkb.state = state; +} + +static void keyboard_handle_enter(void * data, struct wl_keyboard * keyboard, + uint32_t serial, struct wl_surface * surface, + struct wl_array * keys) +{ + struct application * app = data; + + LV_UNUSED(keyboard); + LV_UNUSED(serial); + LV_UNUSED(keys); + + if(!surface) { + app->keyboard_obj = NULL; + } + else { + app->keyboard_obj = wl_surface_get_user_data(surface); + } +} + +static void keyboard_handle_leave(void * data, struct wl_keyboard * keyboard, + uint32_t serial, struct wl_surface * surface) +{ + struct application * app = data; + + LV_UNUSED(serial); + LV_UNUSED(keyboard); + + if(!surface || (app->keyboard_obj == wl_surface_get_user_data(surface))) { + app->keyboard_obj = NULL; + } +} + +static void keyboard_handle_key(void * data, struct wl_keyboard * keyboard, + uint32_t serial, uint32_t time, uint32_t key, + uint32_t state) +{ + struct application * app = data; + const uint32_t code = (key + 8); + const xkb_keysym_t * syms; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + + LV_UNUSED(serial); + LV_UNUSED(time); + LV_UNUSED(keyboard); + + if(!app->keyboard_obj || !app->seat.xkb.state) { + return; + } + + if(xkb_state_key_get_syms(app->seat.xkb.state, code, &syms) == 1) { + sym = syms[0]; + } + + const lv_key_t lv_key = keycode_xkb_to_lv(sym); + const lv_indev_state_t lv_state = + (state == WL_KEYBOARD_KEY_STATE_PRESSED) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + + if(lv_key != 0) { + app->keyboard_obj->input.keyboard.key = lv_key; + app->keyboard_obj->input.keyboard.state = lv_state; + } +} + +static void keyboard_handle_modifiers(void * data, struct wl_keyboard * keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + struct application * app = data; + + LV_UNUSED(serial); + LV_UNUSED(keyboard); + + /* If we're not using a keymap, then we don't handle PC-style modifiers */ + if(!app->seat.xkb.keymap) { + return; + } + + xkb_state_update_mask(app->seat.xkb.state, + mods_depressed, mods_latched, mods_locked, 0, 0, group); +} + +static const struct wl_keyboard_listener keyboard_listener = { + .keymap = keyboard_handle_keymap, + .enter = keyboard_handle_enter, + .leave = keyboard_handle_leave, + .key = keyboard_handle_key, + .modifiers = keyboard_handle_modifiers, +}; + +static void touch_handle_down(void * data, struct wl_touch * wl_touch, + uint32_t serial, uint32_t time, struct wl_surface * surface, + int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) +{ + struct application * app = data; + + LV_UNUSED(id); + LV_UNUSED(time); + LV_UNUSED(serial); + LV_UNUSED(wl_touch); + + if(!surface) { + app->touch_obj = NULL; + return; + } + + app->touch_obj = wl_surface_get_user_data(surface); + + app->touch_obj->input.touch.x = wl_fixed_to_int(x_w); + app->touch_obj->input.touch.y = wl_fixed_to_int(y_w); + app->touch_obj->input.touch.state = LV_INDEV_STATE_PRESSED; + +#if LV_WAYLAND_WINDOW_DECORATIONS + struct window * window = app->touch_obj->window; + switch(app->touch_obj->type) { + case OBJECT_TITLEBAR: +#if LV_WAYLAND_XDG_SHELL + if(window->xdg_toplevel) { + xdg_toplevel_move(window->xdg_toplevel, app->wl_seat, serial); + window->flush_pending = true; + } +#endif +#if LV_WAYLAND_WL_SHELL + if(window->wl_shell_surface) { + wl_shell_surface_move(window->wl_shell_surface, app->wl_seat, serial); + window->flush_pending = true; + } +#endif + break; + default: + break; + } +#endif +} + +static void touch_handle_up(void * data, struct wl_touch * wl_touch, + uint32_t serial, uint32_t time, int32_t id) +{ + struct application * app = data; + + LV_UNUSED(serial); + LV_UNUSED(time); + LV_UNUSED(id); + LV_UNUSED(wl_touch); + + if(!app->touch_obj) { + return; + } + + app->touch_obj->input.touch.state = LV_INDEV_STATE_RELEASED; + +#if LV_WAYLAND_WINDOW_DECORATIONS + struct window * window = app->touch_obj->window; + switch(app->touch_obj->type) { + case OBJECT_BUTTON_CLOSE: + window->shall_close = true; + break; +#if LV_WAYLAND_XDG_SHELL + case OBJECT_BUTTON_MAXIMIZE: + if(window->xdg_toplevel) { + if(window->maximized) { + xdg_toplevel_unset_maximized(window->xdg_toplevel); + } + else { + xdg_toplevel_set_maximized(window->xdg_toplevel); + } + window->maximized ^= true; + } + break; + case OBJECT_BUTTON_MINIMIZE: + if(window->xdg_toplevel) { + xdg_toplevel_set_minimized(window->xdg_toplevel); + window->flush_pending = true; + } +#endif // LV_WAYLAND_XDG_SHELL + default: + break; + } +#endif // LV_WAYLAND_WINDOW_DECORATIONS + + app->touch_obj = NULL; +} + +static void touch_handle_motion(void * data, struct wl_touch * wl_touch, + uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) +{ + struct application * app = data; + + LV_UNUSED(time); + LV_UNUSED(id); + LV_UNUSED(wl_touch); + + if(!app->touch_obj) { + return; + } + + app->touch_obj->input.touch.x = wl_fixed_to_int(x_w); + app->touch_obj->input.touch.y = wl_fixed_to_int(y_w); +} + +static void touch_handle_frame(void * data, struct wl_touch * wl_touch) +{ + LV_UNUSED(wl_touch); + LV_UNUSED(data); + +} + +static void touch_handle_cancel(void * data, struct wl_touch * wl_touch) +{ + LV_UNUSED(wl_touch); + LV_UNUSED(data); +} + +static const struct wl_touch_listener touch_listener = { + .down = touch_handle_down, + .up = touch_handle_up, + .motion = touch_handle_motion, + .frame = touch_handle_frame, + .cancel = touch_handle_cancel, +}; + +static void seat_handle_capabilities(void * data, struct wl_seat * wl_seat, enum wl_seat_capability caps) +{ + struct application * app = data; + struct seat * seat = &app->seat; + + if((caps & WL_SEAT_CAPABILITY_POINTER) && !seat->wl_pointer) { + seat->wl_pointer = wl_seat_get_pointer(wl_seat); + wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, app); + app->cursor_surface = wl_compositor_create_surface(app->compositor); + if(!app->cursor_surface) { + LV_LOG_WARN("failed to create cursor surface"); + } + } + else if(!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer) { + wl_pointer_destroy(seat->wl_pointer); + if(app->cursor_surface) { + wl_surface_destroy(app->cursor_surface); + } + seat->wl_pointer = NULL; + } + + if((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !seat->wl_keyboard) { + seat->wl_keyboard = wl_seat_get_keyboard(wl_seat); + wl_keyboard_add_listener(seat->wl_keyboard, &keyboard_listener, app); + } + else if(!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->wl_keyboard) { + wl_keyboard_destroy(seat->wl_keyboard); + seat->wl_keyboard = NULL; + } + + if((caps & WL_SEAT_CAPABILITY_TOUCH) && !seat->wl_touch) { + seat->wl_touch = wl_seat_get_touch(wl_seat); + wl_touch_add_listener(seat->wl_touch, &touch_listener, app); + } + else if(!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch) { + wl_touch_destroy(seat->wl_touch); + seat->wl_touch = NULL; + } +} + +static const struct wl_seat_listener seat_listener = { + .capabilities = seat_handle_capabilities, +}; + +static void draw_window(struct window * window, uint32_t width, uint32_t height) +{ + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(application.opt_disable_decorations == false) { + int d; + for(d = 0; d < NUM_DECORATIONS; d++) { + window->decoration[d] = create_graphic_obj(&application, window, (FIRST_DECORATION + d), window->body); + if(!window->decoration[d]) { + LV_LOG_ERROR("Failed to create decoration %d", d); + } + } + } +#endif + + /* First resize */ + if(!resize_window(window, width, height)) { + LV_LOG_ERROR("Failed to resize window"); +#if LV_WAYLAND_XDG_SHELL + if(window->xdg_toplevel) { + xdg_toplevel_destroy(window->xdg_toplevel); + } +#endif + } + + lv_refr_now(window->lv_disp); + +} + +#if LV_WAYLAND_WL_SHELL +static void wl_shell_handle_ping(void * data, struct wl_shell_surface * shell_surface, uint32_t serial) +{ + return wl_shell_surface_pong(shell_surface, serial); +} + +static void wl_shell_handle_configure(void * data, struct wl_shell_surface * shell_surface, + uint32_t edges, int32_t width, int32_t height) +{ + struct window * window = (struct window *)data; + + LV_UNUSED(edges); + + if((width <= 0) || (height <= 0)) { + return; + } + else if((width != window->width) || (height != window->height)) { + window->resize_width = width; + window->resize_height = height; + window->resize_pending = true; + } +} + +static const struct wl_shell_surface_listener shell_surface_listener = { + .ping = wl_shell_handle_ping, + .configure = wl_shell_handle_configure, +}; +#endif + +#if LV_WAYLAND_XDG_SHELL +static void xdg_surface_handle_configure(void * data, struct xdg_surface * xdg_surface, uint32_t serial) +{ + struct window * window = (struct window *)data; + + xdg_surface_ack_configure(xdg_surface, serial); + + if(window->body->surface_configured == false) { + /* This branch is executed at launch */ + if(window->resize_pending == false) { + /* Use the size passed to the create_window function */ + draw_window(window, window->width, window->height); + } + else { + + /* Handle early maximization or fullscreen, */ + /* by using the size communicated by the compositor */ + /* when the initial xdg configure event arrives */ + draw_window(window, window->resize_width, window->resize_height); + window->width = window->resize_width; + window->height = window->resize_height; + window->resize_pending = false; + } + } + window->body->surface_configured = true; +} + +static const struct xdg_surface_listener xdg_surface_listener = { + .configure = xdg_surface_handle_configure, +}; + +static void xdg_toplevel_handle_configure(void * data, struct xdg_toplevel * xdg_toplevel, + int32_t width, int32_t height, struct wl_array * states) +{ + struct window * window = (struct window *)data; + + LV_UNUSED(xdg_toplevel); + LV_UNUSED(states); + LV_UNUSED(width); + LV_UNUSED(height); + + LV_LOG_TRACE("w:%d h:%d", width, height); + LV_LOG_TRACE("current body w:%d h:%d", window->body->width, window->body->height); + LV_LOG_TRACE("window w:%d h:%d", window->width, window->height); + + + if((width <= 0) || (height <= 0)) { + LV_LOG_TRACE("will not resize to w:%d h:%d", width, height); + return; + } + + if((width != window->width) || (height != window->height)) { + window->resize_width = width; + window->resize_height = height; + window->resize_pending = true; + LV_LOG_TRACE("resize_pending is set, will resize to w:%d h:%d", width, height); + } + else { + LV_LOG_TRACE("resize_pending not set w:%d h:%d", width, height); + } +} + +static void xdg_toplevel_handle_close(void * data, struct xdg_toplevel * xdg_toplevel) +{ + struct window * window = (struct window *)data; + window->shall_close = true; + + LV_UNUSED(xdg_toplevel); +} + +static void xdg_toplevel_handle_configure_bounds(void * data, struct xdg_toplevel * xdg_toplevel, + int32_t width, int32_t height) +{ + + LV_UNUSED(width); + LV_UNUSED(height); + LV_UNUSED(data); + LV_UNUSED(xdg_toplevel); + + /* Optional: Could set window width/height upper bounds, however, currently + * we'll honor the set width/height. + */ +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + .configure = xdg_toplevel_handle_configure, + .close = xdg_toplevel_handle_close, + .configure_bounds = xdg_toplevel_handle_configure_bounds +}; + +static void xdg_wm_base_ping(void * data, struct xdg_wm_base * xdg_wm_base, uint32_t serial) +{ + LV_UNUSED(data); + + xdg_wm_base_pong(xdg_wm_base, serial); + + return; +} + +static const struct xdg_wm_base_listener xdg_wm_base_listener = { + .ping = xdg_wm_base_ping +}; +#endif + + +static void handle_global(void * data, struct wl_registry * registry, + uint32_t name, const char * interface, uint32_t version) +{ + struct application * app = data; + + LV_UNUSED(version); + LV_UNUSED(data); + + if(strcmp(interface, wl_compositor_interface.name) == 0) { + app->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); + } + else if(strcmp(interface, wl_subcompositor_interface.name) == 0) { + app->subcompositor = wl_registry_bind(registry, name, &wl_subcompositor_interface, 1); + } + else if(strcmp(interface, wl_shm_interface.name) == 0) { + app->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); + wl_shm_add_listener(app->shm, &shm_listener, app); + app->cursor_theme = wl_cursor_theme_load(NULL, 32, app->shm); + } + else if(strcmp(interface, wl_seat_interface.name) == 0) { + app->wl_seat = wl_registry_bind(app->registry, name, &wl_seat_interface, 1); + wl_seat_add_listener(app->wl_seat, &seat_listener, app); + } +#if LV_WAYLAND_WL_SHELL + else if(strcmp(interface, wl_shell_interface.name) == 0) { + app->wl_shell = wl_registry_bind(registry, name, &wl_shell_interface, 1); + } +#endif +#if LV_WAYLAND_XDG_SHELL + else if(strcmp(interface, xdg_wm_base_interface.name) == 0) { + /* Explicitly support version 4 of the xdg protocol */ + app->xdg_wm = wl_registry_bind(app->registry, name, &xdg_wm_base_interface, 4); + xdg_wm_base_add_listener(app->xdg_wm, &xdg_wm_base_listener, app); + } +#endif +} + +static void handle_global_remove(void * data, struct wl_registry * registry, uint32_t name) +{ + + LV_UNUSED(data); + LV_UNUSED(registry); + LV_UNUSED(name); + +} + +static const struct wl_registry_listener registry_listener = { + .global = handle_global, + .global_remove = handle_global_remove +}; + +static void handle_wl_buffer_release(void * data, struct wl_buffer * wl_buffer) +{ + const struct smm_buffer_properties * props; + struct graphic_object * obj; + struct window * window; + smm_buffer_t * buf; + + buf = (smm_buffer_t *)data; + props = SMM_BUFFER_PROPERTIES(buf); + obj = SMM_GROUP_PROPERTIES(props->group)->tag[TAG_LOCAL]; + window = obj->window; + + LV_LOG_TRACE("releasing buffer %p wl_buffer %p w:%d h:%d frame: %d", (smm_buffer_t *)data, (void *)wl_buffer, + obj->width, + obj->height, window->frame_counter); + smm_release((smm_buffer_t *)data); +} + +static const struct wl_buffer_listener wl_buffer_listener = { + .release = handle_wl_buffer_release, +}; + +static void cache_clear(struct window * window) +{ + window->dmg_cache.start = window->dmg_cache.end; + window->dmg_cache.size = 0; +} + +static void cache_purge(struct window * window, smm_buffer_t * buf) +{ + lv_area_t * next_dmg; + smm_buffer_t * next_buf = smm_next(buf); + + /* Remove all damage areas up until start of next buffers damage */ + if(next_buf == NULL) { + cache_clear(window); + } + else { + next_dmg = SMM_BUFFER_PROPERTIES(next_buf)->tag[TAG_BUFFER_DAMAGE]; + while((window->dmg_cache.cache + window->dmg_cache.start) != next_dmg) { + window->dmg_cache.start++; + window->dmg_cache.start %= DMG_CACHE_CAPACITY; + window->dmg_cache.size--; + } + } +} + +static void cache_add_area(struct window * window, smm_buffer_t * buf, const lv_area_t * area) +{ + if(SMM_BUFFER_PROPERTIES(buf)->tag[TAG_BUFFER_DAMAGE] == NULL) { + /* Buffer damage beyond cache capacity */ + goto done; + } + + if((window->dmg_cache.start == window->dmg_cache.end) && + (window->dmg_cache.size)) { + /* This buffer has more damage then the cache's capacity, so + * clear cache and leave buffer damage unrecorded + */ + cache_clear(window); + SMM_TAG(buf, TAG_BUFFER_DAMAGE, NULL); + goto done; + } + + /* Add damage area to cache */ + memcpy(window->dmg_cache.cache + window->dmg_cache.end, + area, + sizeof(lv_area_t)); + window->dmg_cache.end++; + window->dmg_cache.end %= DMG_CACHE_CAPACITY; + window->dmg_cache.size++; + +done: + return; +} + +static void cache_apply_areas(struct window * window, void * dest, void * src, smm_buffer_t * src_buf) +{ + unsigned long offset; + unsigned char start; + int32_t y; + lv_area_t * dmg; + lv_area_t * next_dmg; + smm_buffer_t * next_buf = smm_next(src_buf); + const struct smm_buffer_properties * props = SMM_BUFFER_PROPERTIES(src_buf); + struct graphic_object * obj = SMM_GROUP_PROPERTIES(props->group)->tag[TAG_LOCAL]; + uint8_t bpp; + + if(next_buf == NULL) { + next_dmg = (window->dmg_cache.cache + window->dmg_cache.end); + } + else { + next_dmg = SMM_BUFFER_PROPERTIES(next_buf)->tag[TAG_BUFFER_DAMAGE]; + } + + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + + /* Apply all buffer damage areas */ + start = ((lv_area_t *)SMM_BUFFER_PROPERTIES(src_buf)->tag[TAG_BUFFER_DAMAGE] - window->dmg_cache.cache); + while((window->dmg_cache.cache + start) != next_dmg) { + /* Copy an area from source to destination (line-by-line) */ + dmg = (window->dmg_cache.cache + start); + for(y = dmg->y1; y <= dmg->y2; y++) { + offset = (dmg->x1 + (y * obj->width)) * bpp; + + memcpy(((char *)dest) + offset, + ((char *)src) + offset, + ((dmg->x2 - dmg->x1 + 1) * bpp)); + } + + + start++; + start %= DMG_CACHE_CAPACITY; + } + +} + +static bool sme_new_pool(void * ctx, smm_pool_t * pool) +{ + struct wl_shm_pool * wl_pool; + struct application * app = ctx; + const struct smm_pool_properties * props = SMM_POOL_PROPERTIES(pool); + + LV_UNUSED(ctx); + + wl_pool = wl_shm_create_pool(app->shm, + props->fd, + props->size); + + SMM_TAG(pool, TAG_LOCAL, wl_pool); + return (wl_pool == NULL); +} + +static void sme_expand_pool(void * ctx, smm_pool_t * pool) +{ + const struct smm_pool_properties * props = SMM_POOL_PROPERTIES(pool); + + LV_UNUSED(ctx); + + wl_shm_pool_resize(props->tag[TAG_LOCAL], props->size); +} + +static void sme_free_pool(void * ctx, smm_pool_t * pool) +{ + struct wl_shm_pool * wl_pool = SMM_POOL_PROPERTIES(pool)->tag[TAG_LOCAL]; + + LV_UNUSED(ctx); + + wl_shm_pool_destroy(wl_pool); +} + +static bool sme_new_buffer(void * ctx, smm_buffer_t * buf) +{ + struct wl_buffer * wl_buf; + bool fail_alloc = true; + const struct smm_buffer_properties * props = SMM_BUFFER_PROPERTIES(buf); + struct wl_shm_pool * wl_pool = SMM_POOL_PROPERTIES(props->pool)->tag[TAG_LOCAL]; + struct application * app = ctx; + struct graphic_object * obj = SMM_GROUP_PROPERTIES(props->group)->tag[TAG_LOCAL]; + uint8_t bpp; + + LV_LOG_TRACE("create new buffer of width %d height %d", obj->width, obj->height); + + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + wl_buf = wl_shm_pool_create_buffer(wl_pool, + props->offset, + obj->width, + obj->height, + obj->width * bpp, + app->shm_format); + + if(wl_buf != NULL) { + wl_buffer_add_listener(wl_buf, &wl_buffer_listener, buf); + SMM_TAG(buf, TAG_LOCAL, wl_buf); + SMM_TAG(buf, TAG_BUFFER_DAMAGE, NULL); + fail_alloc = false; + } + + return fail_alloc; +} + +static bool sme_init_buffer(void * ctx, smm_buffer_t * buf) +{ + smm_buffer_t * src; + void * src_base; + bool fail_init = true; + bool dmg_missing = false; + void * buf_base = smm_map(buf); + const struct smm_buffer_properties * props = SMM_BUFFER_PROPERTIES(buf); + struct graphic_object * obj = SMM_GROUP_PROPERTIES(props->group)->tag[TAG_LOCAL]; + uint8_t bpp; + + LV_UNUSED(ctx); + + if(buf_base == NULL) { + LV_LOG_ERROR("cannot map in buffer to initialize"); + goto done; + } + + /* Determine if all subsequent buffers damage is recorded */ + for(src = smm_next(buf); src != NULL; src = smm_next(src)) { + if(SMM_BUFFER_PROPERTIES(src)->tag[TAG_BUFFER_DAMAGE] == NULL) { + dmg_missing = true; + break; + } + } + + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + + if((smm_next(buf) == NULL) || dmg_missing) { + /* Missing subsequent buffer damage, initialize by copying the most + * recently acquired buffers data + */ + src = smm_latest(props->group); + if((src != NULL) && + (src != buf)) { + /* Map and copy latest buffer data */ + src_base = smm_map(src); + if(src_base == NULL) { + LV_LOG_ERROR("cannot map most recent buffer to copy"); + goto done; + } + + memcpy(buf_base, + src_base, + (obj->width * bpp) * obj->height); + } + } + else { + /* All subsequent buffers damage is recorded, initialize by applying + * their damage to this buffer + */ + for(src = smm_next(buf); src != NULL; src = smm_next(src)) { + src_base = smm_map(src); + if(src_base == NULL) { + LV_LOG_ERROR("cannot map source buffer to copy from"); + goto done; + } + + cache_apply_areas(obj->window, buf_base, src_base, src); + } + + /* Purge out-of-date cached damage (up to and including next buffer) */ + src = smm_next(buf); + if(src == NULL) { + cache_purge(obj->window, src); + } + } + + fail_init = false; +done: + return fail_init; +} + +static void sme_free_buffer(void * ctx, smm_buffer_t * buf) +{ + struct wl_buffer * wl_buf = SMM_BUFFER_PROPERTIES(buf)->tag[TAG_LOCAL]; + + LV_UNUSED(ctx); + + wl_buffer_destroy(wl_buf); +} + +static struct graphic_object * create_graphic_obj(struct application * app, struct window * window, + enum object_type type, + struct graphic_object * parent) +{ + struct graphic_object * obj; + + LV_UNUSED(parent); + + obj = lv_malloc(sizeof(*obj)); + LV_ASSERT_MALLOC(obj); + if(!obj) { + goto err_out; + } + + lv_memset(obj, 0x00, sizeof(struct graphic_object)); + + obj->surface = wl_compositor_create_surface(app->compositor); + if(!obj->surface) { + LV_LOG_ERROR("cannot create surface for graphic object"); + goto err_free; + } + + obj->buffer_group = smm_create(); + if(obj->buffer_group == NULL) { + LV_LOG_ERROR("cannot create buffer group for graphic object"); + goto err_destroy_surface; + } + + obj->window = window; + obj->type = type; + obj->surface_configured = true; + obj->pending_buffer = NULL; + wl_surface_set_user_data(obj->surface, obj); + SMM_TAG(obj->buffer_group, TAG_LOCAL, obj); + + return obj; + +err_destroy_surface: + wl_surface_destroy(obj->surface); + +err_free: + lv_free(obj); + +err_out: + return NULL; +} + +static void destroy_graphic_obj(struct graphic_object * obj) +{ + if(obj->subsurface) { + wl_subsurface_destroy(obj->subsurface); + } + + wl_surface_destroy(obj->surface); + smm_destroy(obj->buffer_group); + lv_free(obj); +} + +#if LV_WAYLAND_WINDOW_DECORATIONS +static bool attach_decoration(struct window * window, struct graphic_object * decoration, + smm_buffer_t * decoration_buffer, struct graphic_object * parent) +{ + struct wl_buffer * wl_buf = SMM_BUFFER_PROPERTIES(decoration_buffer)->tag[TAG_LOCAL]; + + int pos_x, pos_y; + + switch(decoration->type) { + case OBJECT_TITLEBAR: + pos_x = 0; + pos_y = -TITLE_BAR_HEIGHT; + break; + case OBJECT_BUTTON_CLOSE: + pos_x = parent->width - 1 * (BUTTON_MARGIN + BUTTON_SIZE); + pos_y = -1 * (BUTTON_MARGIN + BUTTON_SIZE + (BORDER_SIZE / 2)); + break; +#if LV_WAYLAND_XDG_SHELL + case OBJECT_BUTTON_MAXIMIZE: + pos_x = parent->width - 2 * (BUTTON_MARGIN + BUTTON_SIZE); + pos_y = -1 * (BUTTON_MARGIN + BUTTON_SIZE + (BORDER_SIZE / 2)); + break; + case OBJECT_BUTTON_MINIMIZE: + pos_x = parent->width - 3 * (BUTTON_MARGIN + BUTTON_SIZE); + pos_y = -1 * (BUTTON_MARGIN + BUTTON_SIZE + (BORDER_SIZE / 2)); + break; +#endif + case OBJECT_BORDER_TOP: + pos_x = -BORDER_SIZE; + pos_y = -(BORDER_SIZE + TITLE_BAR_HEIGHT); + break; + case OBJECT_BORDER_BOTTOM: + pos_x = -BORDER_SIZE; + pos_y = parent->height; + break; + case OBJECT_BORDER_LEFT: + pos_x = -BORDER_SIZE; + pos_y = -TITLE_BAR_HEIGHT; + break; + case OBJECT_BORDER_RIGHT: + pos_x = parent->width; + pos_y = -TITLE_BAR_HEIGHT; + break; + default: + LV_ASSERT_MSG(0, "Invalid object type"); + return false; + } + + /* Enable this, to make it function on weston 10.0.2 */ + /* It's not elegant but it forces weston to size the surfaces before */ + /* the conversion to a subsurface takes place */ + + /* Likely related to this issue, some patches were merged into 10.0.0 */ + /* https://gitlab.freedesktop.org/wayland/weston/-/issues/446 */ + /* Moreover, it crashes on GNOME */ + +#if 0 + wl_surface_attach(decoration->surface, wl_buf, 0, 0); + wl_surface_commit(decoration->surface); +#endif + + if(decoration->subsurface == NULL) { + /* Create the subsurface only once */ + + decoration->subsurface = wl_subcompositor_get_subsurface(window->application->subcompositor, + decoration->surface, + parent->surface); + if(!decoration->subsurface) { + LV_LOG_ERROR("cannot get subsurface for decoration"); + goto err_destroy_surface; + } + } + + wl_subsurface_set_position(decoration->subsurface, pos_x, pos_y); + wl_surface_attach(decoration->surface, wl_buf, 0, 0); + wl_surface_commit(decoration->surface); + + return true; + +err_destroy_surface: + wl_surface_destroy(decoration->surface); + decoration->surface = NULL; + + return false; +} + +/* + * Fills a buffer with a color + * @description Used to draw the decorations, by writing directly to the SHM buffer, + * most wayland compositors support the ARGB8888, XRGB8888, RGB565 formats + * + * For color depths usually not natively supported by wayland i.e RGB332, Grayscale + * A conversion is performed to match the format of the SHM buffer read by the compositor. + * + * This function can also be used as a visual debugging aid to see how damage is applied + * + * @param pixels pointer to the buffer to fill + * @param lv_color_t color the color that will be used for the fill + * @param width width of the filled area + * @param height height of the filled area + * + */ +static void color_fill(void * pixels, lv_color_t color, uint32_t width, uint32_t height) +{ + + switch(application.shm_format) { + case WL_SHM_FORMAT_ARGB8888: + color_fill_XRGB8888(pixels, color, width, height); + break; + case WL_SHM_FORMAT_RGB565: + color_fill_RGB565(pixels, color, width, height); + break; + default: + LV_ASSERT_MSG(0, "Unsupported WL_SHM_FORMAT"); + break; + } +} + +static void color_fill_XRGB8888(void * pixels, lv_color_t color, uint32_t width, uint32_t height) +{ + unsigned char * buf = pixels; + unsigned char * buf_end; + + buf_end = (unsigned char *)((uint32_t *)buf + width * height); + + while(buf < buf_end) { + *(buf++) = color.blue; + *(buf++) = color.green; + *(buf++) = color.red; + *(buf++) = 0xFF; + } + +} + +static void color_fill_RGB565(void * pixels, lv_color_t color, uint32_t width, uint32_t height) +{ + uint16_t * buf = pixels; + uint16_t * buf_end; + + buf_end = (uint16_t *)buf + width * height; + + while(buf < buf_end) { + *(buf++) = lv_color_to_u16(color); + } +} + +static bool create_decoration(struct window * window, + struct graphic_object * decoration, + int window_width, int window_height) +{ + smm_buffer_t * buf; + void * buf_base; + int x, y; + lv_color_t * pixel; + uint8_t bpp; + + switch(decoration->type) { + case OBJECT_TITLEBAR: + decoration->width = window_width; + decoration->height = TITLE_BAR_HEIGHT; + break; + case OBJECT_BUTTON_CLOSE: + decoration->width = BUTTON_SIZE; + decoration->height = BUTTON_SIZE; + break; +#if LV_WAYLAND_XDG_SHELL + case OBJECT_BUTTON_MAXIMIZE: + decoration->width = BUTTON_SIZE; + decoration->height = BUTTON_SIZE; + break; + case OBJECT_BUTTON_MINIMIZE: + decoration->width = BUTTON_SIZE; + decoration->height = BUTTON_SIZE; + break; +#endif + case OBJECT_BORDER_TOP: + decoration->width = window_width + 2 * (BORDER_SIZE); + decoration->height = BORDER_SIZE; + break; + case OBJECT_BORDER_BOTTOM: + decoration->width = window_width + 2 * (BORDER_SIZE); + decoration->height = BORDER_SIZE; + break; + case OBJECT_BORDER_LEFT: + decoration->width = BORDER_SIZE; + decoration->height = window_height + TITLE_BAR_HEIGHT; + break; + case OBJECT_BORDER_RIGHT: + decoration->width = BORDER_SIZE; + decoration->height = window_height + TITLE_BAR_HEIGHT; + break; + default: + LV_ASSERT_MSG(0, "Invalid object type"); + return false; + } + + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + + LV_LOG_TRACE("decoration window %dx%d", decoration->width, decoration->height); + + smm_resize(decoration->buffer_group, + (decoration->width * bpp) * decoration->height); + + buf = smm_acquire(decoration->buffer_group); + + if(buf == NULL) { + LV_LOG_ERROR("cannot allocate buffer for decoration"); + return false; + } + + buf_base = smm_map(buf); + if(buf_base == NULL) { + LV_LOG_ERROR("cannot map in allocated decoration buffer"); + smm_release(buf); + return false; + } + + switch(decoration->type) { + case OBJECT_TITLEBAR: + color_fill(buf_base, lv_color_make(0x66, 0x66, 0x66), decoration->width, decoration->height); + break; + case OBJECT_BUTTON_CLOSE: + color_fill(buf_base, lv_color_make(0xCC, 0xCC, 0xCC), decoration->width, decoration->height); + for(y = 0; y < decoration->height; y++) { + for(x = 0; x < decoration->width; x++) { + pixel = (lv_color_t *)((unsigned char *)buf_base + (y * (decoration->width * bpp)) + x * bpp); + if((x >= BUTTON_PADDING) && (x < decoration->width - BUTTON_PADDING)) { + if((x == y) || (x == decoration->width - 1 - y)) { + color_fill(pixel, lv_color_make(0x33, 0x33, 0x33), 1, 1); + } + else if((x == y - 1) || (x == decoration->width - y)) { + color_fill(pixel, lv_color_make(0x66, 0x66, 0x66), 1, 1); + } + } + } + } + break; +#if LV_WAYLAND_XDG_SHELL + case OBJECT_BUTTON_MAXIMIZE: + color_fill(buf_base, lv_color_make(0xCC, 0xCC, 0xCC), decoration->width, decoration->height); + for(y = 0; y < decoration->height; y++) { + for(x = 0; x < decoration->width; x++) { + pixel = (lv_color_t *)((unsigned char *)buf_base + (y * (decoration->width * bpp)) + x * bpp); + if(((x == BUTTON_PADDING) && (y >= BUTTON_PADDING) && (y < decoration->height - BUTTON_PADDING)) || + ((x == (decoration->width - BUTTON_PADDING)) && (y >= BUTTON_PADDING) && (y <= decoration->height - BUTTON_PADDING)) || + ((y == BUTTON_PADDING) && (x >= BUTTON_PADDING) && (x < decoration->width - BUTTON_PADDING)) || + ((y == (BUTTON_PADDING + 1)) && (x >= BUTTON_PADDING) && (x < decoration->width - BUTTON_PADDING)) || + ((y == (decoration->height - BUTTON_PADDING)) && (x >= BUTTON_PADDING) && (x < decoration->width - BUTTON_PADDING))) { + color_fill(pixel, lv_color_make(0x33, 0x33, 0x33), 1, 1); + } + } + } + break; + case OBJECT_BUTTON_MINIMIZE: + color_fill(buf_base, lv_color_make(0xCC, 0xCC, 0xCC), decoration->width, decoration->height); + for(y = 0; y < decoration->height; y++) { + for(x = 0; x < decoration->width; x++) { + pixel = (lv_color_t *)((unsigned char *)buf_base + (y * (decoration->width * bpp)) + x * bpp); + if((x >= BUTTON_PADDING) && (x < decoration->width - BUTTON_PADDING) && + (y > decoration->height - (2 * BUTTON_PADDING)) && (y < decoration->height - BUTTON_PADDING)) { + color_fill(pixel, lv_color_make(0x33, 0x33, 0x33), 1, 1); + } + } + } + break; +#endif + case OBJECT_BORDER_TOP: + /* fallthrough */ + case OBJECT_BORDER_BOTTOM: + /* fallthrough */ + case OBJECT_BORDER_LEFT: + /* fallthrough */ + case OBJECT_BORDER_RIGHT: + color_fill(buf_base, lv_color_make(0x66, 0x66, 0x66), decoration->width, decoration->height); + break; + default: + LV_ASSERT_MSG(0, "Invalid object type"); + return false; + } + + return attach_decoration(window, decoration, buf, window->body); +} + +static void detach_decoration(struct window * window, + struct graphic_object * decoration) +{ + + LV_UNUSED(window); + + if(decoration->subsurface) { + wl_subsurface_destroy(decoration->subsurface); + decoration->subsurface = NULL; + } +} +#endif + +static bool resize_window(struct window * window, int width, int height) +{ + struct smm_buffer_t * body_buf1; + struct smm_buffer_t * body_buf2; + uint32_t stride; + uint8_t bpp; +#if LV_WAYLAND_WINDOW_DECORATIONS + int b; +#endif + + + window->width = width; + window->height = height; + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(!window->application->opt_disable_decorations && !window->fullscreen) { + width -= (2 * BORDER_SIZE); + height -= (TITLE_BAR_HEIGHT + (2 * BORDER_SIZE)); + } +#endif + + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + + /* Update size for newly allocated buffers */ + smm_resize(window->body->buffer_group, ((width * bpp) * height) * 2); + + window->body->width = width; + window->body->height = height; + + /* Pre-allocate two buffers for the window body here */ + body_buf1 = smm_acquire(window->body->buffer_group); + body_buf2 = smm_acquire(window->body->buffer_group); + + if(smm_map(body_buf2) == NULL) { + LV_LOG_ERROR("Cannot pre-allocate backing buffers for window body"); + wl_surface_destroy(window->body->surface); + return false; + } + + /* Moves the buffers to the the unused list of the group */ + smm_release(body_buf1); + smm_release(body_buf2); + + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(!window->application->opt_disable_decorations && !window->fullscreen) { + for(b = 0; b < NUM_DECORATIONS; b++) { + if(!create_decoration(window, window->decoration[b], + window->body->width, window->body->height)) { + LV_LOG_ERROR("failed to create decoration %d", b); + } + } + + } + else if(!window->application->opt_disable_decorations) { + /* Entering fullscreen, detach decorations to prevent xdg_wm_base error 4 */ + /* requested geometry larger than the configured fullscreen state */ + for(b = 0; b < NUM_DECORATIONS; b++) { + detach_decoration(window, window->decoration[b]); + } + + } +#endif + + LV_LOG_TRACE("resize window:%dx%d body:%dx%d frame: %d rendered: %d", + window->width, window->height, + window->body->width, window->body->height, + window->frame_counter, window->frame_done); + + width = window->body->width; + height = window->body->height; + + if(window->lv_disp != NULL) { + /* Resize draw buffer */ + stride = lv_draw_buf_width_to_stride(width, + lv_display_get_color_format(window->lv_disp)); + + window->lv_disp_draw_buf = lv_draw_buf_reshape( + window->lv_disp_draw_buf, + lv_display_get_color_format(window->lv_disp), + width, height / LVGL_DRAW_BUFFER_DIV, stride); + + lv_display_set_resolution(window->lv_disp, width, height); + + window->body->input.pointer.x = LV_MIN((int32_t)window->body->input.pointer.x, (width - 1)); + window->body->input.pointer.y = LV_MIN((int32_t)window->body->input.pointer.y, (height - 1)); + } + + return true; +} + +/* Create a window + * @description Creates the graphical context for the window body, and then create a toplevel + * wayland surface and commit it to obtain an XDG configuration event + * @param width the height of the window w/decorations + * @param height the width of the window w/decorations +*/ +static struct window * create_window(struct application * app, int width, int height, const char * title) +{ + struct window * window; + + window = lv_ll_ins_tail(&app->window_ll); + LV_ASSERT_MALLOC(window); + if(!window) { + return NULL; + } + + lv_memset(window, 0x00, sizeof(struct window)); + + window->application = app; + + // Create wayland buffer and surface + window->body = create_graphic_obj(app, window, OBJECT_WINDOW, NULL); + window->width = width; + window->height = height; + + if(!window->body) { + LV_LOG_ERROR("cannot create window body"); + goto err_free_window; + } + + // Create shell surface + if(0) { + // Needed for #if madness below + } +#if LV_WAYLAND_XDG_SHELL + else if(app->xdg_wm) { + window->xdg_surface = xdg_wm_base_get_xdg_surface(app->xdg_wm, window->body->surface); + if(!window->xdg_surface) { + LV_LOG_ERROR("cannot create XDG surface"); + goto err_destroy_surface; + } + + xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, window); + + window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface); + if(!window->xdg_toplevel) { + LV_LOG_ERROR("cannot get XDG toplevel surface"); + goto err_destroy_shell_surface; + } + + xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener, window); + xdg_toplevel_set_title(window->xdg_toplevel, title); + xdg_toplevel_set_app_id(window->xdg_toplevel, title); + + // XDG surfaces need to be configured before a buffer can be attached. + // An (XDG) surface commit (without an attached buffer) triggers this + // configure event + window->body->surface_configured = false; + } +#endif +#if LV_WAYLAND_WL_SHELL + else if(app->wl_shell) { + window->wl_shell_surface = wl_shell_get_shell_surface(app->wl_shell, window->body->surface); + if(!window->wl_shell_surface) { + LV_LOG_ERROR("cannot create WL shell surface"); + goto err_destroy_surface; + } + + wl_shell_surface_add_listener(window->wl_shell_surface, &shell_surface_listener, window); + wl_shell_surface_set_toplevel(window->wl_shell_surface); + wl_shell_surface_set_title(window->wl_shell_surface, title); + + /* For wl_shell, just draw the window, weston doesn't send it */ + draw_window(window, window->width, window->height); + } +#endif + else { + LV_LOG_ERROR("No shell available"); + goto err_destroy_surface; + } + + + return window; + +err_destroy_shell_surface: +#if LV_WAYLAND_WL_SHELL + if(window->wl_shell_surface) { + wl_shell_surface_destroy(window->wl_shell_surface); + } +#endif +#if LV_WAYLAND_XDG_SHELL + if(window->xdg_surface) { + xdg_surface_destroy(window->xdg_surface); + } +#endif + +err_destroy_surface: + wl_surface_destroy(window->body->surface); + +err_free_window: + lv_ll_remove(&app->window_ll, window); + lv_free(window); + return NULL; +} + +static void destroy_window(struct window * window) +{ + if(!window) { + return; + } + +#if LV_WAYLAND_WL_SHELL + if(window->wl_shell_surface) { + wl_shell_surface_destroy(window->wl_shell_surface); + } +#endif +#if LV_WAYLAND_XDG_SHELL + if(window->xdg_toplevel) { + xdg_toplevel_destroy(window->xdg_toplevel); + xdg_surface_destroy(window->xdg_surface); + } +#endif + +#if LV_WAYLAND_WINDOW_DECORATIONS + int b; + for(b = 0; b < NUM_DECORATIONS; b++) { + if(window->decoration[b]) { + destroy_graphic_obj(window->decoration[b]); + window->decoration[b] = NULL; + } + } +#endif + + destroy_graphic_obj(window->body); +} + +static void _lv_wayland_flush(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p) +{ + unsigned long offset; + void * buf_base; + struct wl_buffer * wl_buf; + uint32_t src_width; + uint32_t src_height; + struct window * window; + smm_buffer_t * buf; + struct wl_callback * cb; + lv_display_rotation_t rot; + uint8_t bpp; + int32_t y; + int32_t w; + int32_t h; + int32_t hres; + int32_t vres; + + window = lv_display_get_user_data(disp); + buf = window->body->pending_buffer; + src_width = (area->x2 - area->x1 + 1); + src_height = (area->y2 - area->y1 + 1); + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + + rot = lv_display_get_rotation(disp); + w = lv_display_get_horizontal_resolution(disp); + h = lv_display_get_vertical_resolution(disp); + + /* TODO actually test what happens if the rotation is 90 or 270 or 180 ? */ + hres = (rot == LV_DISPLAY_ROTATION_0) ? w : h; + vres = (rot == LV_DISPLAY_ROTATION_0) ? h : w; + + /* If window has been / is being closed, or is not visible, skip flush */ + if(window->closed || window->shall_close) { + goto skip; + } + /* Skip if the area is out the screen */ + else if((area->x2 < 0) || (area->y2 < 0) || (area->x1 > hres - 1) || (area->y1 > vres - 1)) { + goto skip; + } + + /* Acquire and map a buffer to attach/commit to surface */ + if(buf == NULL) { + buf = smm_acquire(window->body->buffer_group); + if(buf == NULL) { + LV_LOG_ERROR("cannot acquire a window body buffer"); + goto skip; + } + + window->body->pending_buffer = buf; + SMM_TAG(buf, + TAG_BUFFER_DAMAGE, + window->dmg_cache.cache + window->dmg_cache.end); + } + + buf_base = smm_map(buf); + if(buf_base == NULL) { + LV_LOG_ERROR("cannot map in window body buffer"); + goto skip; + } + + /* Modify specified area in buffer */ + for(y = area->y1; y <= area->y2; y++) { + offset = ((area->x1 + (y * hres)) * bpp); + memcpy(((char *)buf_base) + offset, + color_p, + src_width * bpp); + color_p += src_width * bpp; + } + + /* Mark surface damage */ + wl_surface_damage(window->body->surface, + area->x1, + area->y1, + src_width, + src_height); + + cache_add_area(window, buf, area); + + + if(lv_display_flush_is_last(disp)) { + /* Finally, attach buffer and commit to surface */ + wl_buf = SMM_BUFFER_PROPERTIES(buf)->tag[TAG_LOCAL]; + wl_surface_attach(window->body->surface, wl_buf, 0, 0); + wl_surface_commit(window->body->surface); + window->body->pending_buffer = NULL; + window->frame_done = false; + + cb = wl_surface_frame(window->body->surface); + wl_callback_add_listener(cb, &wl_surface_frame_listener, window->body); + LV_LOG_TRACE("last flush frame: %d", window->frame_counter); + + window->flush_pending = true; + } + + lv_display_flush_ready(disp); + return; +skip: + if(buf != NULL) { + /* Cleanup any intermediate state (in the event that this flush being + * skipped is in the middle of a flush sequence) + */ + cache_clear(window); + SMM_TAG(buf, TAG_BUFFER_DAMAGE, NULL); + smm_release(buf); + window->body->pending_buffer = NULL; + } +} + +static void _lv_wayland_handle_input(void) +{ + int prepare_read = wl_display_prepare_read(application.display); + while(prepare_read != 0) { + wl_display_dispatch_pending(application.display); + } + + wl_display_read_events(application.display); + wl_display_dispatch_pending(application.display); +} + +static void _lv_wayland_handle_output(void) +{ + struct window * window; + bool shall_flush = application.cursor_flush_pending; + + LV_LL_READ(&application.window_ll, window) { + if((window->shall_close) && (window->close_cb != NULL)) { + window->shall_close = window->close_cb(window->lv_disp); + } + + if(window->closed) { + continue; + } + else if(window->shall_close) { + window->closed = true; + window->shall_close = false; + shall_flush = true; + + window->body->input.touch.x = 0; + window->body->input.touch.y = 0; + window->body->input.touch.state = LV_INDEV_STATE_RELEASED; + if(window->application->touch_obj == window->body) { + window->application->touch_obj = NULL; + } + + window->body->input.pointer.x = 0; + window->body->input.pointer.y = 0; + window->body->input.pointer.left_button = LV_INDEV_STATE_RELEASED; + window->body->input.pointer.right_button = LV_INDEV_STATE_RELEASED; + window->body->input.pointer.wheel_button = LV_INDEV_STATE_RELEASED; + window->body->input.pointer.wheel_diff = 0; + if(window->application->pointer_obj == window->body) { + window->application->pointer_obj = NULL; + } + + window->body->input.keyboard.key = 0; + window->body->input.keyboard.state = LV_INDEV_STATE_RELEASED; + if(window->application->keyboard_obj == window->body) { + window->application->keyboard_obj = NULL; + } + destroy_window(window); + } + + shall_flush |= window->flush_pending; + } + + if(shall_flush) { + if(wl_display_flush(application.display) == -1) { + if(errno != EAGAIN) { + LV_LOG_ERROR("failed to flush wayland display"); + } + } + else { + /* All data flushed */ + application.cursor_flush_pending = false; + LV_LL_READ(&application.window_ll, window) { + window->flush_pending = false; + } + } + } +} + +static void _lv_wayland_pointer_read(lv_indev_t * drv, lv_indev_data_t * data) +{ + struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + + if(!window || window->closed) { + return; + } + + data->point.x = window->body->input.pointer.x; + data->point.y = window->body->input.pointer.y; + data->state = window->body->input.pointer.left_button; +} + +static void _lv_wayland_pointeraxis_read(lv_indev_t * drv, lv_indev_data_t * data) +{ + struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + + if(!window || window->closed) { + return; + } + + data->state = window->body->input.pointer.wheel_button; + data->enc_diff = window->body->input.pointer.wheel_diff; + + window->body->input.pointer.wheel_diff = 0; +} + +static void _lv_wayland_keyboard_read(lv_indev_t * drv, lv_indev_data_t * data) +{ + struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + if(!window || window->closed) { + return; + } + + data->key = window->body->input.keyboard.key; + data->state = window->body->input.keyboard.state; +} + +static void _lv_wayland_touch_read(lv_indev_t * drv, lv_indev_data_t * data) +{ + struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + if(!window || window->closed) { + return; + } + + data->point.x = window->body->input.touch.x; + data->point.y = window->body->input.touch.y; + data->state = window->body->input.touch.state; +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Initialize Wayland driver + */ +static void wayland_init(void) +{ + struct smm_events evs = { + NULL, + sme_new_pool, + sme_expand_pool, + sme_free_pool, + sme_new_buffer, + sme_init_buffer, + sme_free_buffer + }; + + application.xdg_runtime_dir = getenv("XDG_RUNTIME_DIR"); + LV_ASSERT_MSG(application.xdg_runtime_dir, "cannot get XDG_RUNTIME_DIR"); + + // Create XKB context + application.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + LV_ASSERT_MSG(application.xkb_context, "failed to create XKB context"); + if(application.xkb_context == NULL) { + return; + } + + // Connect to Wayland display + application.display = wl_display_connect(NULL); + LV_ASSERT_MSG(application.display, "failed to connect to Wayland server"); + if(application.display == NULL) { + return; + } + + /* Add registry listener and wait for registry reception */ + application.shm_format = SHM_FORMAT_UNKNOWN; + application.registry = wl_display_get_registry(application.display); + wl_registry_add_listener(application.registry, ®istry_listener, &application); + wl_display_dispatch(application.display); + wl_display_roundtrip(application.display); + + LV_ASSERT_MSG(application.compositor, "Wayland compositor not available"); + if(application.compositor == NULL) { + return; + } + + LV_ASSERT_MSG(application.shm, "Wayland SHM not available"); + if(application.shm == NULL) { + return; + } + + LV_ASSERT_MSG((application.shm_format != SHM_FORMAT_UNKNOWN), "WL_SHM_FORMAT not available"); + if(application.shm_format == SHM_FORMAT_UNKNOWN) { + LV_LOG_TRACE("Unable to match a suitable SHM format for selected LVGL color depth"); + return; + } + + smm_init(&evs); + smm_setctx(&application); + +#ifdef LV_WAYLAND_WINDOW_DECORATIONS + const char * env_disable_decorations = getenv("LV_WAYLAND_DISABLE_WINDOWDECORATION"); + application.opt_disable_decorations = ((env_disable_decorations != NULL) && + (env_disable_decorations[0] != '0')); +#endif + + lv_ll_init(&application.window_ll, sizeof(struct window)); + + lv_tick_set_cb(tick_get_cb); + + /* Used to wait for events when the window is minimized or hidden */ + application.wayland_pfd.fd = wl_display_get_fd(application.display); + application.wayland_pfd.events = POLLIN; + +} + +/** + * De-initialize Wayland driver + */ +static void wayland_deinit(void) +{ + struct window * window = NULL; + + LV_LL_READ(&application.window_ll, window) { + if(!window->closed) { + destroy_window(window); + } + } + + smm_deinit(); + + if(application.shm) { + wl_shm_destroy(application.shm); + } + +#if LV_WAYLAND_XDG_SHELL + if(application.xdg_wm) { + xdg_wm_base_destroy(application.xdg_wm); + } +#endif + +#if LV_WAYLAND_WL_SHELL + if(application.wl_shell) { + wl_shell_destroy(application.wl_shell); + } +#endif + + if(application.wl_seat) { + wl_seat_destroy(application.wl_seat); + } + + if(application.subcompositor) { + wl_subcompositor_destroy(application.subcompositor); + } + + if(application.compositor) { + wl_compositor_destroy(application.compositor); + } + + wl_registry_destroy(application.registry); + wl_display_flush(application.display); + wl_display_disconnect(application.display); + + lv_ll_clear(&application.window_ll); + +} + +static uint32_t tick_get_cb(void) +{ + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + uint64_t time_ms = t.tv_sec * 1000 + (t.tv_nsec / 1000000); + return time_ms; +} + +/** + * Get Wayland display file descriptor + * @return Wayland display file descriptor + */ +int lv_wayland_get_fd(void) +{ + return wl_display_get_fd(application.display); +} + +/** + * Create wayland window + * @param hor_res initial horizontal window body size in pixels + * @param ver_res initial vertical window body size in pixels + * @param title window title + * @param close_cb function to be called when the window gets closed by the user (optional) + * @return new display backed by a Wayland window, or NULL on error + */ +lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char * title, + lv_wayland_display_close_f_t close_cb) +{ + struct window * window; + int32_t window_width; + int32_t window_height; + int32_t stride; + + wayland_init(); + + window_width = hor_res; + window_height = ver_res; + +#if LV_WAYLAND_WINDOW_DECORATIONS + + /* Decorations are enabled, caculate the body size */ + if(!application.opt_disable_decorations) { + window_width = hor_res + (2 * BORDER_SIZE); + window_height = ver_res + (TITLE_BAR_HEIGHT + (2 * BORDER_SIZE)); + } + +#endif + + window = create_window(&application, window_width, window_height, title); + if(!window) { + LV_LOG_ERROR("failed to create wayland window"); + return NULL; + } + + window->close_cb = close_cb; + + /* Initialize display driver */ + window->lv_disp = lv_display_create(hor_res, ver_res); + if(window->lv_disp == NULL) { + LV_LOG_ERROR("failed to create lvgl display"); + return NULL; + } + + stride = lv_draw_buf_width_to_stride(hor_res, + lv_display_get_color_format(window->lv_disp)); + + window->lv_disp_draw_buf = lv_draw_buf_create( + hor_res, + ver_res / LVGL_DRAW_BUFFER_DIV, + lv_display_get_color_format(window->lv_disp), + stride); + + + lv_display_set_draw_buffers(window->lv_disp, window->lv_disp_draw_buf, NULL); + lv_display_set_render_mode(window->lv_disp, LV_DISPLAY_RENDER_MODE_PARTIAL); + lv_display_set_flush_cb(window->lv_disp, _lv_wayland_flush); + lv_display_set_user_data(window->lv_disp, window); + + /* Register input */ + window->lv_indev_pointer = lv_indev_create(); + lv_indev_set_type(window->lv_indev_pointer, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(window->lv_indev_pointer, _lv_wayland_pointer_read); + lv_indev_set_display(window->lv_indev_pointer, window->lv_disp); + + if(!window->lv_indev_pointer) { + LV_LOG_ERROR("failed to register pointer indev"); + } + + window->lv_indev_pointeraxis = lv_indev_create(); + lv_indev_set_type(window->lv_indev_pointeraxis, LV_INDEV_TYPE_ENCODER); + lv_indev_set_read_cb(window->lv_indev_pointeraxis, _lv_wayland_pointeraxis_read); + lv_indev_set_display(window->lv_indev_pointeraxis, window->lv_disp); + + if(!window->lv_indev_pointeraxis) { + LV_LOG_ERROR("failed to register pointeraxis indev"); + } + + window->lv_indev_touch = lv_indev_create(); + lv_indev_set_type(window->lv_indev_touch, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(window->lv_indev_touch, _lv_wayland_touch_read); + lv_indev_set_display(window->lv_indev_touch, window->lv_disp); + + if(!window->lv_indev_touch) { + LV_LOG_ERROR("failed to register touch indev"); + } + + window->lv_indev_keyboard = lv_indev_create(); + lv_indev_set_type(window->lv_indev_keyboard, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(window->lv_indev_keyboard, _lv_wayland_keyboard_read); + lv_indev_set_display(window->lv_indev_keyboard, window->lv_disp); + + if(!window->lv_indev_keyboard) { + LV_LOG_ERROR("failed to register keyboard indev"); + } + + return window->lv_disp; +} + +/** + * Close wayland window + * @param disp LVGL display using window to be closed + */ +void lv_wayland_window_close(lv_display_t * disp) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window || window->closed) { + return; + } + window->shall_close = true; + window->close_cb = NULL; + wayland_deinit(); +} + +/** + * Check if a Wayland window is open on the specified display. Otherwise (if + * argument is NULL), check if any Wayland window is open. + * @return true if window open, false otherwise + */ +bool lv_wayland_window_is_open(lv_display_t * disp) +{ + struct window * window; + bool open = false; + + if(disp == NULL) { + LV_LL_READ(&application.window_ll, window) { + if(!window->closed) { + open = true; + break; + } + } + } + else { + window = lv_display_get_user_data(disp); + open = (!window->closed); + } + + return open; +} +/** + * Set/unset window maximization mode + * @description Maximization is nearly the same as fullscreen, except + * window decorations and the compositor's panels must remain visible + * @param disp LVGL display using window to be set/unset maximization + * @param Maximization requested status (true = maximized) + */ +void lv_wayland_window_set_maximized(lv_display_t * disp, bool maximized) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window || window->closed) { + return; + } + + if(window->maximized != maximized) { + +#if LV_WAYLAND_WL_SHELL + if(window->wl_shell_surface) { + if(maximized) { + /* Maximizing the wl_shell is possible, but requires binding to wl_output */ + /* The wl_shell has been deperacted */ + //wl_shell_surface_set_maximized(window->wl_shell_surface); + } + else { + wl_shell_surface_set_toplevel(window->wl_shell_surface); + } + window->maximized = maximized; + window->flush_pending = true; + } +#endif + +#if LV_WAYLAND_XDG_SHELL + if(window->xdg_toplevel) { + if(maximized) { + xdg_toplevel_set_maximized(window->xdg_toplevel); + } + else { + xdg_toplevel_unset_maximized(window->xdg_toplevel); + } + + window->maximized = maximized; + window->flush_pending = true; + } +#endif + } +} + +/** + * Set/unset window fullscreen mode + * @param disp LVGL display using window to be set/unset fullscreen + * @param fullscreen requested status (true = fullscreen) + */ +void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window || window->closed) { + return; + } + + if(window->fullscreen != fullscreen) { + if(0) { + // Needed for #if madness below + } +#if LV_WAYLAND_XDG_SHELL + else if(window->xdg_toplevel) { + if(fullscreen) { + xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL); + } + else { + xdg_toplevel_unset_fullscreen(window->xdg_toplevel); + } + window->fullscreen = fullscreen; + window->flush_pending = true; + } +#endif +#if LV_WAYLAND_WL_SHELL + else if(window->wl_shell_surface) { + if(fullscreen) { + wl_shell_surface_set_fullscreen(window->wl_shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, + 0, NULL); + } + else { + wl_shell_surface_set_toplevel(window->wl_shell_surface); + } + window->fullscreen = fullscreen; + window->flush_pending = true; + } +#endif + else { + LV_LOG_WARN("Wayland fullscreen mode not supported"); + } + } +} + +/** + * Get pointer input device for given LVGL display + * @param disp LVGL display + * @return input device connected to pointer events, or NULL on error + */ +lv_indev_t * lv_wayland_get_pointer(lv_display_t * disp) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window) { + return NULL; + } + return window->lv_indev_pointer; +} + +/** + * Get pointer axis input device for given LVGL display + * @param disp LVGL display + * @return input device connected to pointer axis events, or NULL on error + */ +lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * disp) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window) { + return NULL; + } + return window->lv_indev_pointeraxis; +} + +/** + * Get keyboard input device for given LVGL display + * @param disp LVGL display + * @return input device connected to keyboard, or NULL on error + */ +lv_indev_t * lv_wayland_get_keyboard(lv_display_t * disp) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window) { + return NULL; + } + return window->lv_indev_keyboard; +} + +/** + * Get touchscreen input device for given LVGL display + * @param disp LVGL display + * @return input device connected to touchscreen, or NULL on error + */ +lv_indev_t * lv_wayland_get_touchscreen(lv_display_t * disp) +{ + struct window * window = lv_display_get_user_data(disp); + if(!window) { + return NULL; + } + return window->lv_indev_touch; +} + +/** + * Wayland specific timer handler (use in place of LVGL lv_timer_handler) + */ +bool lv_wayland_timer_handler(void) +{ + struct window * window; + + /* Wayland input handling - it will also trigger the frame done handler */ + _lv_wayland_handle_input(); + + /* Ready input timers (to probe for any input received) */ + LV_LL_READ(&application.window_ll, window) { + LV_LOG_TRACE("handle timer frame: %d", window->frame_counter); + + if(window != NULL && window->frame_done == false + && window->frame_counter > 0) { + /* The last frame was not rendered */ + LV_LOG_TRACE("The window is hidden or minimized"); + + /* Simply blocks until a frame done message arrives */ + poll(&application.wayland_pfd, 1, -1); + + /* Resume lvgl on the next cycle */ + return false; + + } + else if(window != NULL && window->body->surface_configured == false) { + /* Initial commit to trigger the configure event */ + /* Manually dispatching the queue is necessary, */ + /* to emit the configure event straight away */ + wl_surface_commit(window->body->surface); + wl_display_dispatch(application.display); + } + else if(window != NULL && window->resize_pending) { + if(resize_window(window, window->resize_width, window->resize_height)) { + window->resize_width = window->width; + window->resize_height = window->height; + window->resize_pending = false; + + } + else { + + LV_LOG_TRACE("Failed to resize window frame: %d", + window->frame_counter); + } + } + else if(window->shall_close == true) { + + /* Destroy graphical context and execute close_cb */ + _lv_wayland_handle_output(); + wayland_deinit(); + return false; + } + } + + /* LVGL handling */ + lv_timer_handler(); + + /* Wayland output handling */ + _lv_wayland_handle_output(); + + /* Set 'errno' if a Wayland flush is outstanding (i.e. data still needs to + * be sent to the compositor, but the compositor pipe/connection is unable + * to take more data at this time). + */ + LV_LL_READ(&application.window_ll, window) { + if(window->flush_pending) { + errno = EAGAIN; + break; + } + } + + return true; +} + +#endif /* LV_USE_WAYLAND */ +#endif /* _WIN32 */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.h new file mode 100644 index 000000000..f3d340b0d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.h @@ -0,0 +1,142 @@ +/******************************************************************* + * + * @file lv_wayland.h - Public functions of the LVGL Wayland client + * + * Based on the original file from the repository. + * + * Porting to LVGL 9.1 + * 2024 EDGEMTech Ltd. + * + * See LICENCE.txt for details + * + * Author(s): EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch) + * + ******************************************************************/ +#ifndef LV_WAYLAND_H +#define LV_WAYLAND_H + +#ifndef _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef bool (*lv_wayland_display_close_f_t)(lv_display_t * disp); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Retrieves the file descriptor of the wayland socket + */ +int lv_wayland_get_fd(void); + +/** + * Creates a window + * @param hor_res The width of the window in pixels + * @param ver_res The height of the window in pixels + * @param title The title of the window + * @param close_cb The callback that will be execute when the user closes the window + * @return The LVGL display associated to the window + */ +lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char * title, + lv_wayland_display_close_f_t close_cb); + +/** + * Closes the window programmatically + * @param disp Reference to the LVGL display associated to the window + */ +void lv_wayland_window_close(lv_display_t * disp); + +/** + * Check if the window is open + * @param disp Reference to the LVGL display associated to the window + * @return true: The window is open + */ +bool lv_wayland_window_is_open(lv_display_t * disp); + +/** + * Sets the fullscreen state of the window + * @param disp Reference to the LVGL display associated to the window + * @param fullscreen If true the window enters fullscreen + */ +void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen); + +/** + * Sets the maximized state of the window + * @param disp Reference to the LVGL display associated to the window + * @param fullscreen If true the window is maximized + */ +void lv_wayland_window_set_maximized(lv_display_t * disp, bool maximize); + +/** + * Obtains the input device of the mouse pointer + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_pointer(lv_display_t * disp); + +/** + * Obtains the input device of the encoder + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * disp); + +/** + * Obtains the input device of the keyboard + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_keyboard(lv_display_t * disp); + +/** + * Obtains the input device of the touch screen + * @note It is used to create an input group on application start + * @param disp Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_touchscreen(lv_display_t * disp); + +/** + * Wrapper around lv_timer_handler + * @note Must be called in the application run loop instead of the + * regular lv_timer_handler provided by LVGL + * @return true: if the cycle was completed, false if the application + * went to sleep because the last frame wasn't completed + */ +bool lv_wayland_timer_handler(void); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _WIN32 */ +#endif /* WAYLAND_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.c new file mode 100644 index 000000000..7cb982a0f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.c @@ -0,0 +1,675 @@ +/** + * @file lv_wayland_smm.c + * + */ + +typedef int dummy_t; /* Make GCC on windows happy, avoid empty translation unit */ + +#ifndef _WIN32 + +#include "lv_wayland_smm.h" +#include "../../display/lv_display.h" + +#if LV_USE_WAYLAND + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NAME_ATTEMPTS (5) +#define PREFER_NUM_BUFFERS (3) + +#define ROUND_UP(n, b) (((((n) ? (n) : 1) + (b) - 1) / (b)) * (b)) +#define LLHEAD(type) \ + struct { \ + struct type *first; \ + struct type *last; \ + } + +#define LLLINK(type) \ + struct { \ + struct type *next; \ + struct type *prev; \ + } + +#define LL_FIRST(head) ((head)->first) +#define LL_LAST(head) ((head)->last) +#define LL_IS_EMPTY(head) (LL_FIRST(head) == NULL) +#define LL_NEXT(src, member) ((src)->member.next) +#define LL_PREV(src, member) ((src)->member.prev) + +#define LL_INIT(head) do { \ + (head)->first = NULL; \ + (head)->last = NULL; \ + } while (0) + +#define LL_ENQUEUE(head, src, member) do { \ + (src)->member.next = NULL; \ + (src)->member.prev = (head)->last; \ + if ((head)->last == NULL) { \ + (head)->first = (src); \ + } else { \ + (head)->last->member.next = (src); \ + } \ + (head)->last = (src); \ + } while (0) + +#define LL_DEQUEUE(entry, head, member) do { \ + (entry) = LL_FIRST(head); \ + LL_REMOVE(head, entry, member); \ + } while (0) + +#define LL_INSERT_AFTER(head, dest, src, member) do { \ + (src)->member.prev = (dest); \ + (src)->member.next = (dest)->member.next; \ + if ((dest)->member.next != NULL) { \ + (dest)->member.next->member.prev = (src); \ + } else { \ + (head)->last = (src); \ + } \ + (dest)->member.next = (src); \ + } while (0) + +#define LL_REMOVE(head, src, member) do { \ + if ((src)->member.prev != NULL) { \ + (src)->member.prev->member.next = (src)->member.next; \ + } else { \ + (head)->first = (src)->member.next; \ + } \ + if ((src)->member.next != NULL) { \ + (src)->member.next->member.prev = (src)->member.prev; \ + } else { \ + (head)->last = (src)->member.prev; \ + } \ + } while (0) + +#define LL_FOREACH(entry, head, member) \ + for ((entry) = LL_FIRST(head); \ + (entry) != NULL; \ + (entry) = LL_NEXT(entry, member)) + +#define WAYLAND_FD_NAME "/" SMM_FD_NAME "-XXXXX" + +struct smm_pool { + struct smm_pool_properties props; + LLHEAD(smm_buffer) allocd; + void * map; + size_t map_size; + bool map_outdated; +}; + +struct smm_buffer { + struct smm_buffer_properties props; + bool group_resized; + LLLINK(smm_buffer) pool; + LLLINK(smm_buffer) use; + LLLINK(smm_buffer) age; +}; + +struct smm_group { + struct smm_group_properties props; + size_t size; + unsigned char num_buffers; + LLHEAD(smm_buffer) unused; + LLHEAD(smm_buffer) inuse; + LLHEAD(smm_buffer) history; + LLLINK(smm_group) link; +}; + +static size_t calc_buffer_size(struct smm_buffer * buf); +static void purge_history(struct smm_buffer * buf); +static struct smm_buffer * get_from_pool(struct smm_group * grp); +static void return_to_pool(struct smm_buffer * buf); +static struct smm_pool * alloc_pool(void); +static void free_pool(struct smm_pool * pool); +static struct smm_buffer * alloc_buffer(struct smm_buffer * last, size_t offset); +static void free_buffer(struct smm_buffer * buf); + +static struct { + unsigned long page_sz; + struct smm_events cbs; + struct smm_pool * active; + LLHEAD(smm_group) groups; + struct { + size_t active_used; + } statistics; +} smm_instance; + + +void smm_init(struct smm_events * evs) +{ + memcpy(&smm_instance.cbs, evs, sizeof(struct smm_events)); + srand((unsigned int)clock()); + smm_instance.page_sz = (unsigned long)sysconf(_SC_PAGESIZE); + LL_INIT(&smm_instance.groups); +} + + +void smm_deinit(void) +{ + struct smm_group * grp; + + /* Destroy all buffer groups */ + while(!LL_IS_EMPTY(&smm_instance.groups)) { + LL_DEQUEUE(grp, &smm_instance.groups, link); + smm_destroy(grp); + } +} + + +void smm_setctx(void * ctx) +{ + smm_instance.cbs.ctx = ctx; +} + + +smm_group_t * smm_create(void) +{ + struct smm_group * grp; + + /* Allocate and intialize a new buffer group */ + grp = malloc(sizeof(struct smm_group)); + if(grp != NULL) { + grp->size = smm_instance.page_sz; + grp->num_buffers = 0; + LL_INIT(&grp->unused); + LL_INIT(&grp->inuse); + LL_INIT(&grp->history); + + /* Add to instance groups queue */ + LL_ENQUEUE(&smm_instance.groups, grp, link); + } + + return grp; +} + + +void smm_resize(smm_group_t * grp, size_t sz) +{ + struct smm_buffer * buf; + struct smm_group * rgrp = grp; + + /* Round allocation size up to a sysconf(_SC_PAGE_SIZE) boundary */ + rgrp->size = ROUND_UP(sz, smm_instance.page_sz); + + /* Return all unused buffers to pool (to be re-allocated at the new size) */ + while(!LL_IS_EMPTY(&rgrp->unused)) { + LL_DEQUEUE(buf, &rgrp->unused, use); + return_to_pool(buf); + } + + /* Mark all buffers in use to be freed to pool when possible */ + LL_FOREACH(buf, &rgrp->inuse, use) { + buf->group_resized = true; + purge_history(buf); + } +} + + +void smm_destroy(smm_group_t * grp) +{ + struct smm_buffer * buf; + struct smm_group * dgrp = grp; + + /* Return unused buffers */ + while(!LL_IS_EMPTY(&dgrp->unused)) { + LL_DEQUEUE(buf, &dgrp->unused, use); + return_to_pool(buf); + } + + /* Return buffers that are still in use (ideally this queue should be empty + * at this time) + */ + while(!LL_IS_EMPTY(&dgrp->inuse)) { + LL_DEQUEUE(buf, &dgrp->inuse, use); + return_to_pool(buf); + } + + /* Remove from instance groups queue */ + LL_REMOVE(&smm_instance.groups, dgrp, link); + free(dgrp); +} + + +smm_buffer_t * smm_acquire(smm_group_t * grp) +{ + struct smm_buffer * buf; + struct smm_group * agrp = grp; + + if(LL_IS_EMPTY(&agrp->unused)) { + /* No unused buffer available, so get a new one from pool */ + buf = get_from_pool(agrp); + } + else { + /* Otherwise, reuse an unused buffer */ + LL_DEQUEUE(buf, &agrp->unused, use); + } + + if(buf != NULL) { + /* Add buffer to in-use queue */ + LL_ENQUEUE(&agrp->inuse, buf, use); + + /* Emit 'init buffer' event */ + if(smm_instance.cbs.init_buffer != NULL) { + if(smm_instance.cbs.init_buffer(smm_instance.cbs.ctx, &buf->props)) { + smm_release(buf); + buf = NULL; + } + } + + if(buf != NULL) { + /* Remove from history */ + purge_history(buf); + + /* Add to history a-new */ + LL_ENQUEUE(&agrp->history, buf, age); + } + } + + return buf; +} + + +void * smm_map(smm_buffer_t * buf) +{ + struct smm_buffer * mbuf = buf; + struct smm_pool * pool = mbuf->props.pool; + void * map = pool->map; + + if(pool->map_outdated) { + /* Update mapping to current pool size */ + if(pool->map != NULL) { + munmap(pool->map, pool->map_size); + } + + map = mmap(NULL, + pool->props.size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + pool->props.fd, + 0); + + if(map == MAP_FAILED) { + map = NULL; + pool->map = NULL; + } + else { + pool->map = map; + pool->map_size = pool->props.size; + pool->map_outdated = false; + } + } + + /* Calculate buffer mapping (from offset in pool) */ + if(map != NULL) { + map = (((char *)map) + mbuf->props.offset); + } + + return map; +} + + +void smm_release(smm_buffer_t * buf) +{ + struct smm_buffer * rbuf = buf; + struct smm_group * grp = rbuf->props.group; + + /* Remove from in-use queue */ + LL_REMOVE(&grp->inuse, rbuf, use); + + if(rbuf->group_resized) { + /* Buffer group was resized while this buffer was in-use, thus it must be + * returned to it's pool + */ + rbuf->group_resized = false; + return_to_pool(rbuf); + } + else { + /* Move to unused queue */ + LL_ENQUEUE(&grp->unused, rbuf, use); + + /* Try to limit total number of buffers to preferred number */ + while((grp->num_buffers > PREFER_NUM_BUFFERS) && + (!LL_IS_EMPTY(&grp->unused))) { + LL_DEQUEUE(rbuf, &grp->unused, use); + return_to_pool(rbuf); + } + } +} + + +smm_buffer_t * smm_latest(smm_group_t * grp) +{ + struct smm_group * lgrp = grp; + + return LL_LAST(&lgrp->history); +} + + +smm_buffer_t * smm_next(smm_buffer_t * buf) +{ + struct smm_buffer * ibuf; + struct smm_buffer * nbuf = buf; + struct smm_group * grp = nbuf->props.group; + + LL_FOREACH(ibuf, &grp->history, age) { + if(ibuf == nbuf) { + ibuf = LL_NEXT(ibuf, age); + break; + } + } + + return ibuf; +} + +void purge_history(struct smm_buffer * buf) +{ + struct smm_buffer * ibuf; + struct smm_group * grp = buf->props.group; + + /* Remove from history (and any older) */ + LL_FOREACH(ibuf, &grp->history, age) { + if(ibuf == buf) { + do { + LL_DEQUEUE(ibuf, &grp->history, age); + } while(ibuf != buf); + break; + } + } +} + + +size_t calc_buffer_size(struct smm_buffer * buf) +{ + size_t buf_sz; + struct smm_pool * buf_pool = buf->props.pool; + + if(buf == LL_LAST(&buf_pool->allocd)) { + buf_sz = (buf_pool->props.size - buf->props.offset); + } + else { + buf_sz = (LL_NEXT(buf, pool)->props.offset - buf->props.offset); + } + + return buf_sz; +} + + +struct smm_buffer * get_from_pool(struct smm_group * grp) +{ + int ret; + size_t buf_sz; + struct smm_buffer * buf; + struct smm_buffer * last = NULL; + + /* TODO: Determine when to allocate a new active pool (i.e. memory shrink) */ + + if(smm_instance.active == NULL) { + /* Allocate a new active pool */ + smm_instance.active = alloc_pool(); + smm_instance.statistics.active_used = 0; + } + + if(smm_instance.active == NULL) { + buf = NULL; + } + else { + /* Search for a free buffer large enough for allocation */ + LL_FOREACH(buf, &smm_instance.active->allocd, pool) { + last = buf; + if(buf->props.group == NULL) { + buf_sz = calc_buffer_size(buf); + if(buf_sz == grp->size) { + break; + } + else if(buf_sz > grp->size) { + if((buf != LL_LAST(&smm_instance.active->allocd)) && + (LL_NEXT(buf, pool)->props.group == NULL)) { + /* Pull back next buffer to use unallocated size */ + LL_NEXT(buf, pool)->props.offset -= (buf_sz - grp->size); + } + else { + /* Allocate another buffer to hold unallocated size */ + alloc_buffer(buf, buf->props.offset + grp->size); + } + + break; + } + } + } + + if(buf == NULL) { + /* No buffer found to meet allocation size, expand pool */ + if((last != NULL) && + (last->props.group == NULL)) { + /* Use last free buffer */ + buf_sz = (grp->size - buf_sz); + } + else { + /* Allocate new buffer */ + buf_sz = grp->size; + if(last == NULL) { + buf = alloc_buffer(NULL, 0); + } + else { + buf = alloc_buffer(last, smm_instance.active->props.size); + } + last = buf; + } + + if(last != NULL) { + /* Expand pool backing memory */ + ret = ftruncate(smm_instance.active->props.fd, + smm_instance.active->props.size + buf_sz); + if(ret) { + if(buf != NULL) { + free_buffer(buf); + buf = NULL; + } + } + else { + smm_instance.active->props.size += buf_sz; + smm_instance.active->map_outdated = true; + buf = last; + + if(!(smm_instance.active->props.size - buf_sz)) { + /* Emit 'new pool' event */ + if((smm_instance.cbs.new_pool != NULL) && + (smm_instance.cbs.new_pool(smm_instance.cbs.ctx, + &smm_instance.active->props))) { + free_buffer(buf); + free_pool(smm_instance.active); + smm_instance.active = NULL; + buf = NULL; + } + } + else { + /* Emit 'expand pool' event */ + if(smm_instance.cbs.expand_pool != NULL) { + smm_instance.cbs.expand_pool(smm_instance.cbs.ctx, + &smm_instance.active->props); + } + } + } + } + } + } + + if(buf != NULL) { + /* Set buffer group */ + memcpy((void *)&buf->props.group, &grp, sizeof(struct smm_group *)); + + /* Emit 'new buffer' event */ + if(smm_instance.cbs.new_buffer != NULL) { + if(smm_instance.cbs.new_buffer(smm_instance.cbs.ctx, &buf->props)) { + grp = NULL; + memcpy((void *)&buf->props.group, &grp, sizeof(struct smm_group *)); + buf = NULL; + } + } + + if(buf != NULL) { + /* Update active pool usage statistic */ + smm_instance.statistics.active_used += grp->size; + grp->num_buffers++; + } + } + + return buf; +} + + +void return_to_pool(struct smm_buffer * buf) +{ + struct smm_group * grp = buf->props.group; + struct smm_pool * pool = buf->props.pool; + + /* Emit 'free buffer' event */ + if(smm_instance.cbs.free_buffer != NULL) { + smm_instance.cbs.free_buffer(smm_instance.cbs.ctx, &buf->props); + } + + /* Buffer is no longer part of history */ + purge_history(buf); + + /* Buffer is no longer part of group */ + grp->num_buffers--; + grp = NULL; + memcpy((void *)&buf->props.group, &grp, sizeof(struct smm_group *)); + + /* Update active pool usage statistic */ + if(smm_instance.active == pool) { + smm_instance.statistics.active_used -= calc_buffer_size(buf); + } + + /* Coalesce with ungrouped buffers beside this one */ + if((buf != LL_LAST(&pool->allocd)) && + (LL_NEXT(buf, pool)->props.group == NULL)) { + free_buffer(LL_NEXT(buf, pool)); + } + if((buf != LL_FIRST(&pool->allocd)) && + (LL_PREV(buf, pool)->props.group == NULL)) { + buf = LL_PREV(buf, pool); + pool = buf->props.pool; + free_buffer(LL_NEXT(buf, pool)); + } + + /* Free buffer (and pool), if only remaining buffer in pool */ + if((buf == LL_FIRST(&pool->allocd)) && + (buf == LL_LAST(&pool->allocd))) { + free_buffer(buf); + + /* Emit 'free pool' event */ + if(smm_instance.cbs.free_pool != NULL) { + smm_instance.cbs.free_pool(smm_instance.cbs.ctx, &pool->props); + } + + free_pool(pool); + if(smm_instance.active == pool) { + smm_instance.active = NULL; + } + } +} + + +struct smm_pool * alloc_pool(void) +{ + struct smm_pool * pool; + char name[] = WAYLAND_FD_NAME; + unsigned char attempts = 0; + bool opened = false; + + pool = malloc(sizeof(struct smm_pool)); + if(pool != NULL) { + do { + /* A randomized pool name should help reduce collisions */ + sprintf(name + sizeof(SMM_FD_NAME) + 1, "%05X", rand() & 0xFFFF); + pool->props.fd = shm_open(name, + O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR); + if(pool->props.fd >= 0) { + shm_unlink(name); + pool->props.size = 0; + pool->map = NULL; + pool->map_size = 0; + pool->map_outdated = false; + LL_INIT(&pool->allocd); + opened = true; + break; + } + else { + if(errno != EEXIST) { + break; + } + attempts++; + } + } while(attempts < MAX_NAME_ATTEMPTS); + + if(!opened) { + free(pool); + pool = NULL; + } + } + + return pool; +} + + +void free_pool(struct smm_pool * pool) +{ + if(pool->map != NULL) { + munmap(pool->map, pool->map_size); + } + + close(pool->props.fd); + free(pool); +} + + +struct smm_buffer * alloc_buffer(struct smm_buffer * last, size_t offset) +{ + struct smm_buffer * buf; + struct smm_buffer_properties initial_props = { + {NULL}, + NULL, + smm_instance.active, + offset + }; + + /* Allocate and intialize a new buffer (including linking in to pool) */ + buf = malloc(sizeof(struct smm_buffer)); + if(buf != NULL) { + memcpy(&buf->props, &initial_props, sizeof(struct smm_buffer_properties)); + buf->group_resized = false; + + if(last == NULL) { + LL_ENQUEUE(&smm_instance.active->allocd, buf, pool); + } + else { + LL_INSERT_AFTER(&smm_instance.active->allocd, last, buf, pool); + } + } + + return buf; +} + + +void free_buffer(struct smm_buffer * buf) +{ + struct smm_pool * buf_pool = buf->props.pool; + + /* Remove from pool */ + LL_REMOVE(&buf_pool->allocd, buf, pool); + free(buf); +} + +#endif /* LV_USE_WAYLAND */ +#endif /* _WIN32 */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.h new file mode 100644 index 000000000..617244f17 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.h @@ -0,0 +1,105 @@ +/** + * @file lv_wayland_smm.h + * + */ +#ifndef LV_WAYLAND_SMM_H +#define LV_WAYLAND_SMM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _WIN32 + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include LV_STDDEF_INCLUDE +#include LV_STDBOOL_INCLUDE + +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +#define SMM_FD_NAME "lvgl-wayland" +#define SMM_POOL_TAGS (1) +#define SMM_BUFFER_TAGS (2) +#define SMM_GROUP_TAGS (1) + +/********************** + * TYPEDEFS + **********************/ + +typedef void smm_pool_t; +typedef void smm_buffer_t; +typedef void smm_group_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +struct smm_events { + void * ctx; + bool (*new_pool)(void * ctx, smm_pool_t * pool); + void (*expand_pool)(void * ctx, smm_pool_t * pool); + void (*free_pool)(void * ctx, smm_pool_t * pool); + bool (*new_buffer)(void * ctx, smm_buffer_t * buf); + bool (*init_buffer)(void * ctx, smm_buffer_t * buf); + void (*free_buffer)(void * ctx, smm_buffer_t * buf); +}; + +struct smm_pool_properties { + void * tag[SMM_POOL_TAGS]; + size_t size; + int fd; +}; + +struct smm_buffer_properties { + void * tag[SMM_BUFFER_TAGS]; + smm_group_t * const group; + smm_pool_t * const pool; + size_t offset; +}; + +struct smm_group_properties { + void * tag[SMM_GROUP_TAGS]; +}; + +void smm_init(struct smm_events * evs); +void smm_setctx(void * ctx); +void smm_deinit(void); +smm_group_t * smm_create(void); +void smm_resize(smm_group_t * grp, size_t sz); +void smm_destroy(smm_group_t * grp); +smm_buffer_t * smm_acquire(smm_group_t * grp); +void * smm_map(smm_buffer_t * buf); +void smm_release(smm_buffer_t * buf); +smm_buffer_t * smm_latest(smm_group_t * grp); +smm_buffer_t * smm_next(smm_buffer_t * buf); + +/********************** + * MACROS + **********************/ + +#define SMM_POOL_PROPERTIES(p) ((const struct smm_pool_properties *)(p)) +#define SMM_BUFFER_PROPERTIES(b) ((const struct smm_buffer_properties *)(b)) +#define SMM_GROUP_PROPERTIES(g) ((const struct smm_group_properties *)(g)) +#define SMM_TAG(o, n, v) \ + do { \ + void **smm_tag = (void **)((char *)o + (n * sizeof(void *))); \ + *smm_tag = (v); \ + } while(0) + + +#endif /* LV_USE_WAYLAND */ +#endif /* _WIN32 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_WAYLAND_SMM_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.c b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.c index 1479d0ff6..7bf20385a 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.c @@ -10,7 +10,12 @@ #include "lv_windows_context.h" #if LV_USE_WINDOWS +#ifdef __GNUC__ + #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + #include "lv_windows_display.h" +#include "lv_windows_input_private.h" /********************* * DEFINES @@ -31,33 +36,19 @@ static void lv_windows_delay_callback(uint32_t ms); static void lv_windows_check_display_existence_timer_callback( lv_timer_t * timer); +static bool lv_windows_window_message_callback_nolock( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + static LRESULT CALLBACK lv_windows_window_message_callback( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -bool lv_windows_pointer_device_window_message_handler( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam, - LRESULT * plResult); - -bool lv_windows_keypad_device_window_message_handler( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam, - LRESULT * plResult); - -bool lv_windows_encoder_device_window_message_handler( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam, - LRESULT * plResult); - /********************** * STATIC VARIABLES **********************/ @@ -154,6 +145,7 @@ static void lv_windows_delay_callback(uint32_t ms) static void lv_windows_check_display_existence_timer_callback( lv_timer_t * timer) { + LV_UNUSED(timer); if(!lv_display_get_next(NULL)) { // Don't use lv_deinit() due to it will cause exception when parallel // rendering is enabled. @@ -186,7 +178,7 @@ static HDC lv_windows_create_frame_buffer( typedef struct _BITMAPINFO_16BPP { BITMAPINFOHEADER bmiHeader; DWORD bmiColorMask[3]; - } BITMAPINFO_16BPP, * PBITMAPINFO_16BPP; + } BITMAPINFO_16BPP; BITMAPINFO_16BPP bitmap_info = { 0 }; #else @@ -275,7 +267,7 @@ static void lv_windows_display_timer_callback(lv_timer_t * timer) context->display_device_object, context->display_framebuffer_base, NULL, - context->display_framebuffer_size, + (uint32_t)context->display_framebuffer_size, LV_DISPLAY_RENDER_MODE_DIRECT); } } @@ -290,6 +282,8 @@ static void lv_windows_display_driver_flush_callback( const lv_area_t * area, uint8_t * px_map) { + LV_UNUSED(area); + HWND window_handle = lv_windows_get_display_window_handle(display); if(!window_handle) { lv_display_flush_ready(display); @@ -465,11 +459,12 @@ static BOOL lv_windows_enable_child_window_dpi_message( return function(WindowHandle, TRUE); } -static LRESULT CALLBACK lv_windows_window_message_callback( +static bool lv_windows_window_message_callback_nolock( HWND hWnd, UINT uMsg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam, + LRESULT * plResult) { switch(uMsg) { case WM_CREATE: { @@ -659,15 +654,15 @@ static LRESULT CALLBACK lv_windows_window_message_callback( lv_windows_window_context_t * context = (lv_windows_window_context_t *)( lv_windows_get_window_context(hWnd)); if(context) { - LRESULT lResult = 0; if(context->pointer.indev && lv_windows_pointer_device_window_message_handler( hWnd, uMsg, wParam, lParam, - &lResult)) { - return lResult; + plResult)) { + // Handled + return true; } else if(context->keypad.indev && lv_windows_keypad_device_window_message_handler( @@ -675,8 +670,9 @@ static LRESULT CALLBACK lv_windows_window_message_callback( uMsg, wParam, lParam, - &lResult)) { - return lResult; + plResult)) { + // Handled + return true; } else if(context->encoder.indev && lv_windows_encoder_device_window_message_handler( @@ -684,16 +680,41 @@ static LRESULT CALLBACK lv_windows_window_message_callback( uMsg, wParam, lParam, - &lResult)) { - return lResult; + plResult)) { + // Handled + return true; } } - return DefWindowProcW(hWnd, uMsg, wParam, lParam); + // Not Handled + return false; } } - return 0; + // Handled + *plResult = 0; + return true; +} + +static LRESULT CALLBACK lv_windows_window_message_callback( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + lv_lock(); + + LRESULT lResult = 0; + bool Handled = lv_windows_window_message_callback_nolock( + hWnd, + uMsg, + wParam, + lParam, + &lResult); + + lv_unlock(); + + return Handled ? lResult : DefWindowProcW(hWnd, uMsg, wParam, lParam); } #endif // LV_USE_WINDOWS diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.h b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.h index 20e72af37..c4fc9417a 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_context.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows_context.h * */ @@ -19,8 +19,20 @@ extern "C" { #if LV_USE_WINDOWS +#if LV_USE_OS != LV_OS_WINDOWS +#error [lv_windows] LV_OS_WINDOWS is required. Enable it in lv_conf.h (LV_USE_OS LV_OS_WINDOWS) +#endif + #include +#ifndef CREATE_WAITABLE_TIMER_MANUAL_RESET +#define CREATE_WAITABLE_TIMER_MANUAL_RESET 0x00000001 +#endif + +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 +#endif + /********************* * DEFINES *********************/ @@ -29,32 +41,31 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct _lv_windows_pointer_context_t { +typedef struct lv_windows_pointer_context_t { lv_indev_state_t state; lv_point_t point; lv_indev_t * indev; } lv_windows_pointer_context_t; -typedef struct _lv_windows_keypad_queue_item_t { +typedef struct lv_windows_keypad_queue_item_t { uint32_t key; lv_indev_state_t state; } lv_windows_keypad_queue_item_t; -typedef struct _lv_windows_keypad_context_t { - CRITICAL_SECTION mutex; +typedef struct lv_windows_keypad_context_t { lv_ll_t queue; uint16_t utf16_high_surrogate; uint16_t utf16_low_surrogate; lv_indev_t * indev; } lv_windows_keypad_context_t; -typedef struct _lv_windows_encoder_context_t { +typedef struct lv_windows_encoder_context_t { lv_indev_state_t state; int16_t enc_diff; lv_indev_t * indev; } lv_windows_encoder_context_t; -typedef struct _lv_windows_window_context_t { +typedef struct lv_windows_window_context_t { lv_display_t * display_device_object; lv_timer_t * display_timer_object; @@ -75,7 +86,7 @@ typedef struct _lv_windows_window_context_t { } lv_windows_window_context_t; -typedef struct _lv_windows_create_display_data_t { +typedef struct lv_windows_create_display_data_t { const wchar_t * title; int32_t hor_res; int32_t ver_res; diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input.c b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input.c index 9830261cb..d3b781646 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows_input.c * */ @@ -10,12 +10,19 @@ #include "lv_windows_input.h" #if LV_USE_WINDOWS +#ifdef __GNUC__ + #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + #include "lv_windows_context.h" #include "lv_windows_display.h" +#include "lv_windows_input_private.h" +#include "../../misc/lv_text_private.h" +#include "../../core/lv_obj_private.h" #include -#include "../../widgets/textarea/lv_textarea.h" +#include "../../widgets/textarea/lv_textarea_private.h" #include "../../widgets/keyboard/lv_keyboard.h" /********************* @@ -122,8 +129,7 @@ lv_indev_t * lv_windows_acquire_keypad_indev(lv_display_t * display) } if(!context->keypad.indev) { - InitializeCriticalSection(&context->keypad.mutex); - _lv_ll_init( + lv_ll_init( &context->keypad.queue, sizeof(lv_windows_keypad_queue_item_t)); context->keypad.utf16_high_surrogate = 0; @@ -415,21 +421,17 @@ static void lv_windows_keypad_driver_read_callback( return; } - EnterCriticalSection(&context->keypad.mutex); - lv_windows_keypad_queue_item_t * current = (lv_windows_keypad_queue_item_t *)( - _lv_ll_get_head(&context->keypad.queue)); + lv_ll_get_head(&context->keypad.queue)); if(current) { data->key = current->key; data->state = current->state; - _lv_ll_remove(&context->keypad.queue, current); + lv_ll_remove(&context->keypad.queue, current); lv_free(current); data->continue_reading = true; } - - LeaveCriticalSection(&context->keypad.mutex); } static void lv_windows_release_keypad_device_event_callback(lv_event_t * e) @@ -450,8 +452,7 @@ static void lv_windows_release_keypad_device_event_callback(lv_event_t * e) return; } - DeleteCriticalSection(&context->keypad.mutex); - _lv_ll_clear(&context->keypad.queue); + lv_ll_clear(&context->keypad.queue); context->keypad.utf16_high_surrogate = 0; context->keypad.utf16_low_surrogate = 0; @@ -464,7 +465,7 @@ static void lv_windows_push_key_to_keyboard_queue( lv_indev_state_t state) { lv_windows_keypad_queue_item_t * current = (lv_windows_keypad_queue_item_t *)( - _lv_ll_ins_tail(&context->keypad.queue)); + lv_ll_ins_tail(&context->keypad.queue)); if(current) { current->key = key; current->state = state; @@ -557,14 +558,14 @@ bool lv_windows_keypad_device_window_message_handler( LPARAM lParam, LRESULT * plResult) { + LV_UNUSED(lParam); + switch(uMsg) { case WM_KEYDOWN: case WM_KEYUP: { lv_windows_window_context_t * context = (lv_windows_window_context_t *)( lv_windows_get_window_context(hWnd)); if(context) { - EnterCriticalSection(&context->keypad.mutex); - bool skip_translation = false; uint32_t translated_key = 0; @@ -619,8 +620,6 @@ bool lv_windows_keypad_device_window_message_handler( ? LV_INDEV_STATE_RELEASED : LV_INDEV_STATE_PRESSED)); } - - LeaveCriticalSection(&context->keypad.mutex); } break; @@ -629,8 +628,6 @@ bool lv_windows_keypad_device_window_message_handler( lv_windows_window_context_t * context = (lv_windows_window_context_t *)( lv_windows_get_window_context(hWnd)); if(context) { - EnterCriticalSection(&context->keypad.mutex); - uint16_t raw_code_point = (uint16_t)(wParam); if(raw_code_point >= 0x20 && raw_code_point != 0x7F) { @@ -658,7 +655,7 @@ bool lv_windows_keypad_device_window_message_handler( } uint32_t lvgl_code_point = - _lv_text_unicode_to_encoded(code_point); + lv_text_unicode_to_encoded(code_point); lv_windows_push_key_to_keyboard_queue( context, @@ -669,8 +666,6 @@ bool lv_windows_keypad_device_window_message_handler( lvgl_code_point, LV_INDEV_STATE_RELEASED); } - - LeaveCriticalSection(&context->keypad.mutex); } break; @@ -791,6 +786,8 @@ bool lv_windows_encoder_device_window_message_handler( LPARAM lParam, LRESULT * plResult) { + LV_UNUSED(lParam); + switch(uMsg) { case WM_MBUTTONDOWN: case WM_MBUTTONUP: { diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input_private.h new file mode 100644 index 000000000..7d1096ed5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/windows/lv_windows_input_private.h @@ -0,0 +1,65 @@ +/** + * @file lv_windows_input_private.h + * + */ + +#ifndef LV_WINDOWS_INPUT_PRIVATE_H +#define LV_WINDOWS_INPUT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#if LV_USE_WINDOWS + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +bool lv_windows_pointer_device_window_message_handler( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + +bool lv_windows_keypad_device_window_message_handler( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + +bool lv_windows_encoder_device_window_message_handler( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + +/********************** + * MACROS + **********************/ + +#endif // LV_USE_WINDOWS + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WINDOWS_INPUT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11.h b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11.h index a7f626768..7daabe3ef 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11.h @@ -39,11 +39,11 @@ typedef void(*lv_x11_close_cb)(void * user_data); **********************/ /** - * create and add keyboard, mouse and scrillwheel objects and connect them to x11 display. + * create and add keyboard, mouse and scrollwheel objects and connect them to x11 display. * * This is a convenience method handling the typical input initialisation of an X11 window: - * - create keyboard (@ref lv_x11_keyboard_create) - * - create mouse (with scrollwheel, @ref lv_x11_mouse_create @ref lv_x11_mousewheel_create) + * - create keyboard (lv_x11_keyboard_create) + * - create mouse (with scrollwheel, lv_x11_mouse_create lv_x11_mousewheel_create) * * @param[in] disp the created X11 display object from @ref lv_x11_window_create * @param[in] mouse_img optional image description for the mouse cursor (NULL for no/invisible mouse cursor) @@ -60,7 +60,7 @@ void lv_x11_inputs_create(lv_display_t * disp, lv_image_dsc_t const * mouse_img) * @endcode * or with mouse cursor icon: * @code - * lv_img_dsc_t mouse_symbol = {.....}; + * lv_image_dsc_t mouse_symbol = {.....}; * lv_display_t* disp = lv_x11_window_create("My Window Title", window_width, window_width); * lv_x11_inputs_create(disp, &mouse_symbol); * @endcode diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_display.c b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_display.c index 1321b82b3..1a2b83cad 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_display.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_display.c @@ -49,7 +49,7 @@ typedef struct { void * xdata; /**< allocated data for XImage */ /* LVGL related information */ lv_timer_t * timer; /**< timer object for @ref x11_event_handler */ - lv_color_t * buffer[2]; /**< (double) lv display buffers, depending on @ref LV_X11_RENDER_MODE */ + uint8_t * buffer[2]; /**< (double) lv display buffers, depending on @ref LV_X11_RENDER_MODE */ lv_area_t flush_area; /**< integrated area for a display update */ /* systemtick by thread related information */ pthread_t thr_tick; /**< pthread for SysTick simulation */ @@ -121,7 +121,7 @@ static void x11_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * .y2 = 0 }; - /* build display update area until lv_disp_flush_is_last */ + /* build display update area until lv_display_flush_is_last */ xd->flush_area.x1 = MIN(xd->flush_area.x1, area->x1); xd->flush_area.x2 = MAX(xd->flush_area.x2, area->x2); xd->flush_area.y1 = MIN(xd->flush_area.y1, area->y1); @@ -160,7 +160,7 @@ static void x11_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * } /** - * event callbed by lvgl display if resolution has been changed (@ref lv_display_set_resolution has been called) + * event called by lvgl display if resolution has been changed (@ref lv_display_set_resolution has been called) * @param[in] e event data, containing lv_display_t object */ static void x11_resolution_evt_cb(lv_event_t * e) @@ -175,8 +175,8 @@ static void x11_resolution_evt_cb(lv_event_t * e) if(LV_X11_RENDER_MODE != LV_DISPLAY_RENDER_MODE_PARTIAL) { /* update lvgl full-screen display draw buffers for new display size */ int sz_buffers = (hor_res * ver_res * (LV_COLOR_DEPTH + 7) / 8); - xd->buffer[0] = lv_realloc(xd->buffer[0], sz_buffers); - xd->buffer[1] = (LV_X11_DOUBLE_BUFFER ? lv_realloc(xd->buffer[1], sz_buffers) : NULL); + xd->buffer[0] = realloc(xd->buffer[0], sz_buffers); + xd->buffer[1] = (LV_X11_DOUBLE_BUFFER ? realloc(xd->buffer[1], sz_buffers) : NULL); lv_display_set_buffers(disp, xd->buffer[0], xd->buffer[1], sz_buffers, LV_X11_RENDER_MODE); } @@ -189,7 +189,7 @@ static void x11_resolution_evt_cb(lv_event_t * e) } /** - * event callbed by lvgl display if display has been closed (@ref lv_display_delete has been called) + * event called by lvgl display if display has been closed (@ref lv_display_delete has been called) * @param[in] e event data, containing lv_display_t object */ static void x11_disp_delete_evt_cb(lv_event_t * e) @@ -199,9 +199,9 @@ static void x11_disp_delete_evt_cb(lv_event_t * e) lv_timer_delete(xd->timer); - lv_free(xd->buffer[0]); + free(xd->buffer[0]); if(LV_X11_DOUBLE_BUFFER) { - lv_free(xd->buffer[1]); + free(xd->buffer[1]); } XDestroyImage(xd->ximage); @@ -378,8 +378,8 @@ lv_display_t * lv_x11_window_create(char const * title, int32_t hor_res, int32_t if(LV_X11_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) { sz_buffers /= 10; } - xd->buffer[0] = lv_malloc(sz_buffers); - xd->buffer[1] = (LV_X11_DOUBLE_BUFFER ? lv_malloc(sz_buffers) : NULL); + xd->buffer[0] = malloc(sz_buffers); + xd->buffer[1] = (LV_X11_DOUBLE_BUFFER ? malloc(sz_buffers) : NULL); lv_display_set_buffers(disp, xd->buffer[0], xd->buffer[1], sz_buffers, LV_X11_RENDER_MODE); xd->timer = lv_timer_create(x11_event_handler, 5, disp); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_input.c b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_input.c index efa94a560..ecbd8d4e7 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_input.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11_input.c @@ -10,12 +10,11 @@ #if LV_USE_X11 +#include #include #include #include -#include "../../stdlib/lv_string.h" #include "../../widgets/image/lv_image.h" -#include "../../core/lv_obj.h" /********************* * DEFINES @@ -34,7 +33,7 @@ typedef struct _x11_inp_data { lv_indev_t * mousewheel; /**< encoder input device object */ lv_timer_t * timer; /**< timer object for @ref x11_event_handler */ /* user input related information */ - char kb_buffer[32]; /**< keyboard buffer for X keyboard inpputs */ + char kb_buffer[32]; /**< keyboard buffer for X keyboard inputs */ lv_point_t mouse_pos; /**< current reported mouse position */ bool left_mouse_btn; /**< current state of left mouse button */ bool right_mouse_btn; /**< current state of right mouse button */ @@ -181,7 +180,7 @@ static void x11_inp_event_handler(lv_timer_t * t) } /** - * event callbed by lvgl display if display has been closed (@ref lv_display_delete has been called) + * event called by lvgl display if display has been closed (@ref lv_display_delete has been called) * @param[in] e event data, containing lv_display_t object */ static void x11_inp_delete_evt_cb(lv_event_t * e) @@ -274,7 +273,6 @@ static lv_indev_t * lv_x11_keyboard_create(lv_display_t * disp) static lv_indev_t * lv_x11_mouse_create(lv_display_t * disp, lv_image_dsc_t const * symb) { lv_indev_t * indev = lv_indev_create(); - LV_ASSERT_OBJ(indev, MY_CLASS); if(NULL != indev) { lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); lv_indev_set_read_cb(indev, x11_mouse_read_cb); @@ -293,7 +291,6 @@ static lv_indev_t * lv_x11_mouse_create(lv_display_t * disp, lv_image_dsc_t cons static lv_indev_t * lv_x11_mousewheel_create(lv_display_t * disp) { lv_indev_t * indev = lv_indev_create(); - LV_ASSERT_OBJ(indev, MY_CLASS); if(NULL != indev) { lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER); lv_indev_set_read_cb(indev, x11_mousewheel_read_cb); diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.c b/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.c index f121f4048..4746026f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.c @@ -6,12 +6,11 @@ /********************* * INCLUDES *********************/ - -#include -#include - +#include "lv_font_fmt_txt_private.h" #include "../lvgl.h" -#include "../misc/lv_fs.h" +#include "../misc/lv_fs_private.h" +#include "../misc/lv_types.h" +#include "../stdlib/lv_string.h" #include "lv_binfont_loader.h" /********************** @@ -208,7 +207,7 @@ static int read_label(lv_fs_file_t * fp, int start, const char * label) if(lv_fs_read(fp, &length, 4, NULL) != LV_FS_RES_OK || lv_fs_read(fp, buf, 4, NULL) != LV_FS_RES_OK - || memcmp(label, buf, 4) != 0) { + || lv_memcmp(label, buf, 4) != 0) { LV_LOG_WARN("Error reading '%s' label.", label); return -1; } @@ -298,7 +297,7 @@ static int32_t load_cmaps(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, u lv_font_fmt_txt_cmap_t * cmaps = lv_malloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); - memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + lv_memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); font_dsc->cmaps = cmaps; font_dsc->cmap_num = cmaps_subtables_count; @@ -323,7 +322,7 @@ static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *) lv_malloc(loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); - memset(glyph_dsc, 0, loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + lv_memset(glyph_dsc, 0, loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); font_dsc->glyph_dsc = glyph_dsc; @@ -462,7 +461,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) lv_malloc(sizeof(lv_font_fmt_txt_dsc_t)); - memset(font_dsc, 0, sizeof(lv_font_fmt_txt_dsc_t)); + lv_memset(font_dsc, 0, sizeof(lv_font_fmt_txt_dsc_t)); font->dsc = font_dsc; @@ -579,7 +578,7 @@ int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t f if(0 == kern_format_type) { /*sorted pairs*/ lv_font_fmt_txt_kern_pair_t * kern_pair = lv_malloc(sizeof(lv_font_fmt_txt_kern_pair_t)); - memset(kern_pair, 0, sizeof(lv_font_fmt_txt_kern_pair_t)); + lv_memset(kern_pair, 0, sizeof(lv_font_fmt_txt_kern_pair_t)); font_dsc->kern_dsc = kern_pair; font_dsc->kern_classes = 0; @@ -617,7 +616,7 @@ int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t f lv_font_fmt_txt_kern_classes_t * kern_classes = lv_malloc(sizeof(lv_font_fmt_txt_kern_classes_t)); - memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); + lv_memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); font_dsc->kern_dsc = kern_classes; font_dsc->kern_classes = 1; diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.h b/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.h index c8537ebae..25e7b8374 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.h +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_FONT_LOADER_H -#define LV_FONT_LOADER_H +#ifndef LV_BINFONT_LOADER_H +#define LV_BINFONT_LOADER_H #ifdef __cplusplus extern "C" { @@ -28,10 +28,10 @@ extern "C" { /** * Loads a `lv_font_t` object from a binary font file - * @param path path where the font file is located - * @return pointer to font where to load + * @param path path to font file + * @return pointer to font where to load */ -lv_font_t * lv_binfont_create(const char * font_name); +lv_font_t * lv_binfont_create(const char * path); #if LV_USE_FS_MEMFS /** @@ -58,4 +58,4 @@ void lv_binfont_destroy(lv_font_t * font); } /*extern "C"*/ #endif -#endif /*LV_FONT_LOADER_H*/ +#endif /* LV_BINFONT_LOADER_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font.c index 6484889f6..35ae352e3 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font.c @@ -8,7 +8,7 @@ *********************/ #include "lv_font.h" -#include "../misc/lv_text.h" +#include "../misc/lv_text_private.h" #include "../misc/lv_utils.h" #include "../misc/lv_log.h" #include "../misc/lv_assert.h" @@ -42,12 +42,20 @@ * GLOBAL FUNCTIONS **********************/ -const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t letter, - lv_draw_buf_t * draw_buf) +const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) { const lv_font_t * font_p = g_dsc->resolved_font; LV_ASSERT_NULL(font_p); - return font_p->get_glyph_bitmap(g_dsc, letter, draw_buf); + return font_p->get_glyph_bitmap(g_dsc, draw_buf); +} + +void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc) +{ + const lv_font_t * font = g_dsc->resolved_font; + + if(font != NULL && font->release_glyph) { + font->release_glyph(font, g_dsc); + } } bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, @@ -114,7 +122,7 @@ uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32 lv_font_glyph_dsc_t g; /*Return zero if letter is marker*/ - if(_lv_text_is_marker(letter)) return 0; + if(lv_text_is_marker(letter)) return 0; lv_font_get_glyph_dsc(font, &g, letter, letter_next); return g.adv_w; @@ -126,6 +134,16 @@ void lv_font_set_kerning(lv_font_t * font, lv_font_kerning_t kerning) font->kerning = kerning; } +int32_t lv_font_get_line_height(const lv_font_t * font) +{ + return font->line_height; +} + +const lv_font_t * lv_font_default(void) +{ + return LV_FONT_DEFAULT; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font.h b/lib/libesp32_lvgl/lvgl/src/font/lv_font.h index 85bdec101..2f172b9f8 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font.h +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font.h @@ -14,14 +14,11 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" -#include -#include -#include +#include "../misc/lv_types.h" #include "lv_symbol_def.h" #include "../draw/lv_draw_buf.h" #include "../misc/lv_area.h" -#include "../misc/lv_types.h" #include "../misc/cache/lv_cache.h" /********************* @@ -37,7 +34,7 @@ extern "C" { *-----------------*/ /** The font format.*/ -enum _lv_font_glyph_format_t { +typedef enum { LV_FONT_GLYPH_FORMAT_NONE = 0, /**< Maybe not visible*/ /**< Legacy simple formats*/ @@ -52,70 +49,55 @@ enum _lv_font_glyph_format_t { LV_FONT_GLYPH_FORMAT_VECTOR = 0x0A, /**< Vectorial format*/ LV_FONT_GLYPH_FORMAT_SVG = 0x0B, /**< SVG format*/ LV_FONT_GLYPH_FORMAT_CUSTOM = 0xFF, /**< Custom format*/ -}; - -#ifdef DOXYGEN -typedef _lv_font_glyph_format_t lv_font_glyph_format_t; -#else -typedef uint8_t lv_font_glyph_format_t; -#endif /*DOXYGEN*/ +} lv_font_glyph_format_t; /** Describes the properties of a glyph.*/ typedef struct { const lv_font_t * - resolved_font; /**< Pointer to a font where the glyph was actually found after handling fallbacks*/ + resolved_font; /**< Pointer to a font where the glyph was actually found after handling fallbacks*/ uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width.*/ uint16_t box_w; /**< Width of the glyph's bounding box*/ uint16_t box_h; /**< Height of the glyph's bounding box*/ int16_t ofs_x; /**< x offset of the bounding box*/ int16_t ofs_y; /**< y offset of the bounding box*/ - lv_font_glyph_format_t format; /**< Font format of the glyph see @lv_font_glyph_format_t*/ - uint8_t is_placeholder: 1; /**< Glyph is missing. But placeholder will still be displayed*/ + lv_font_glyph_format_t format; /**< Font format of the glyph see lv_font_glyph_format_t */ + uint8_t is_placeholder: 1; /**< Glyph is missing. But placeholder will still be displayed*/ - uint32_t glyph_index; /**< The index of the glyph in the font file. Used by the font cache*/ + union { + uint32_t index; /**< Unicode code point*/ + const void * src; /**< Pointer to the source data used by image fonts*/ + } gid; /**< The index of the glyph in the font file. Used by the font cache*/ lv_cache_entry_t * entry; /**< The cache entry of the glyph draw data. Used by the font cache*/ } lv_font_glyph_dsc_t; /** The bitmaps might be upscaled by 3 to achieve subpixel rendering.*/ -enum _lv_font_subpx_t { +typedef enum { LV_FONT_SUBPX_NONE, LV_FONT_SUBPX_HOR, LV_FONT_SUBPX_VER, LV_FONT_SUBPX_BOTH, -}; - -#ifdef DOXYGEN -typedef _lv_font_subpx_t lv_font_subpx_t; -#else -typedef uint8_t lv_font_subpx_t; -#endif /*DOXYGEN*/ +} lv_font_subpx_t; /** Adjust letter spacing for specific character pairs.*/ -enum _lv_font_kerning_t { +typedef enum { LV_FONT_KERNING_NORMAL, LV_FONT_KERNING_NONE, -}; - -#ifdef DOXYGEN -typedef _lv_font_kerning_t lv_font_kerning_t; -#else -typedef uint8_t lv_font_kerning_t; -#endif /*DOXYGEN*/ +} lv_font_kerning_t; /** Describe the properties of a font*/ -struct _lv_font_t { +struct lv_font_t { /** Get a glyph's descriptor from a font*/ bool (*get_glyph_dsc)(const lv_font_t *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next); /** Get a glyph's bitmap from a font*/ - const void * (*get_glyph_bitmap)(lv_font_glyph_dsc_t *, uint32_t, lv_draw_buf_t *); + const void * (*get_glyph_bitmap)(lv_font_glyph_dsc_t *, lv_draw_buf_t *); /** Release a glyph*/ void (*release_glyph)(const lv_font_t *, lv_font_glyph_dsc_t *); /*Pointer to the font in a font pack (must have the same line height)*/ int32_t line_height; /**< The real line height where any text fits*/ - int32_t base_line; /**< Base line measured from the top of the line_height*/ + int32_t base_line; /**< Base line measured from the bottom of the line_height*/ uint8_t subpx : 2; /**< An element of `lv_font_subpx_t`*/ uint8_t kerning : 1; /**< An element of `lv_font_kerning_t`*/ @@ -133,13 +115,12 @@ struct _lv_font_t { /** * Return with the bitmap of a font. - * @param g_dsc the glyph descriptor including which font to use etc. - * @param letter a UNICODE character code + * @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t) before you can call this function. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and the format. * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. * @return pointer to the glyph's data. It can be a draw buffer for bitmap fonts or an image source for imgfonts. */ -const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t letter, - lv_draw_buf_t * draw_buf); +const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); /** * Get the descriptor of a glyph @@ -153,6 +134,13 @@ const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t lett bool lv_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next); +/** + * Release the bitmap of a font. + * @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t) before you can call this function. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and the format. + */ +void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc); + /** * Get the width of a glyph with kerning * @param font pointer to a font @@ -167,10 +155,7 @@ uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32 * @param font pointer to a font * @return the height of a font */ -static inline int32_t lv_font_get_line_height(const lv_font_t * font) -{ - return font->line_height; -} +int32_t lv_font_get_line_height(const lv_font_t * font); /** * Configure the use of kerning information stored in a font @@ -277,6 +262,10 @@ LV_FONT_DECLARE(lv_font_montserrat_28_compressed) LV_FONT_DECLARE(lv_font_dejavu_16_persian_hebrew) #endif +#if LV_FONT_SIMSUN_14_CJK +LV_FONT_DECLARE(lv_font_simsun_14_cjk) +#endif + #if LV_FONT_SIMSUN_16_CJK LV_FONT_DECLARE(lv_font_simsun_16_cjk) #endif @@ -298,10 +287,7 @@ LV_FONT_CUSTOM_DECLARE * Just a wrapper around LV_FONT_DEFAULT because it might be more convenient to use a function in some cases * @return pointer to LV_FONT_DEFAULT */ -static inline const lv_font_t * lv_font_default(void) -{ - return LV_FONT_DEFAULT; -} +const lv_font_t * lv_font_default(void); #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.c index d1d3e38bd..5d0130454 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_font.h" -#include "lv_font_fmt_txt.h" +#include "lv_font_fmt_txt_private.h" #include "../core/lv_global.h" #include "../misc/lv_assert.h" #include "../misc/lv_types.h" @@ -35,9 +35,9 @@ typedef struct { **********************/ static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter); static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t gid_right); -static int32_t unicode_list_compare(const void * ref, const void * element); -static int32_t kern_pair_8_compare(const void * ref, const void * element); -static int32_t kern_pair_16_compare(const void * ref, const void * element); +static int unicode_list_compare(const void * ref, const void * element); +static int kern_pair_8_compare(const void * ref, const void * element); +static int kern_pair_16_compare(const void * ref, const void * element); #if LV_USE_FONT_COMPRESSED static void decompress(const uint8_t * in, uint8_t * out, int32_t w, int32_t h, uint8_t bpp, bool prefilter); @@ -75,16 +75,13 @@ static const uint8_t opa2_table[4] = {0, 85, 170, 255}; * GLOBAL FUNCTIONS **********************/ -const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode_letter, - lv_draw_buf_t * draw_buf) +const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) { const lv_font_t * font = g_dsc->resolved_font; uint8_t * bitmap_out = draw_buf->data; - if(unicode_letter == '\t') unicode_letter = ' '; - lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc; - uint32_t gid = get_glyph_dsc_id(font, unicode_letter); + uint32_t gid = g_dsc->gid.index; if(!gid) return NULL; const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid]; @@ -206,6 +203,7 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out->ofs_y = gdsc->ofs_y; dsc_out->format = (uint8_t)fdsc->bpp; dsc_out->is_placeholder = false; + dsc_out->gid.index = gid; if(is_tab) dsc_out->box_w = dsc_out->box_w * 2; @@ -238,8 +236,8 @@ static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter) } else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_TINY) { uint16_t key = rcp; - uint16_t * p = _lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, - sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare); + uint16_t * p = lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, + sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare); if(p) { lv_uintptr_t ofs = p - fdsc->cmaps[i].unicode_list; @@ -248,8 +246,8 @@ static uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter) } else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_FULL) { uint16_t key = rcp; - uint16_t * p = _lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, - sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare); + uint16_t * p = lv_utils_bsearch(&key, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, + sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare); if(p) { lv_uintptr_t ofs = p - fdsc->cmaps[i].unicode_list; @@ -279,7 +277,7 @@ static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t *The pairs are ordered left_id first, then right_id secondly.*/ const uint16_t * g_ids = kdsc->glyph_ids; kern_pair_ref_t g_id_both = {gid_left, gid_right}; - uint16_t * kid_p = _lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare); + uint16_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare); /*If the `g_id_both` were found get its index from the pointer*/ if(kid_p) { @@ -292,7 +290,7 @@ static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t *The pairs are ordered left_id first, then right_id secondly.*/ const uint32_t * g_ids = kdsc->glyph_ids; kern_pair_ref_t g_id_both = {gid_left, gid_right}; - uint32_t * kid_p = _lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare); + uint32_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare); /*If the `g_id_both` were found get its index from the pointer*/ if(kid_p) { @@ -321,25 +319,24 @@ static int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t return value; } -static int32_t kern_pair_8_compare(const void * ref, const void * element) +static int kern_pair_8_compare(const void * ref, const void * element) { const kern_pair_ref_t * ref8_p = ref; const uint8_t * element8_p = element; /*If the MSB is different it will matter. If not return the diff. of the LSB*/ - if(ref8_p->gid_left != element8_p[0]) return (int32_t) ref8_p->gid_left - element8_p[0]; - else return (int32_t) ref8_p->gid_right - element8_p[1]; - + if(ref8_p->gid_left != element8_p[0]) return ref8_p->gid_left - element8_p[0]; + else return ref8_p->gid_right - element8_p[1]; } -static int32_t kern_pair_16_compare(const void * ref, const void * element) +static int kern_pair_16_compare(const void * ref, const void * element) { const kern_pair_ref_t * ref16_p = ref; const uint16_t * element16_p = element; /*If the MSB is different it will matter. If not return the diff. of the LSB*/ - if(ref16_p->gid_left != element16_p[0]) return (int32_t) ref16_p->gid_left - element16_p[0]; - else return (int32_t) ref16_p->gid_right - element16_p[1]; + if(ref16_p->gid_left != element16_p[0]) return ref16_p->gid_left - element16_p[0]; + else return ref16_p->gid_right - element16_p[1]; } #if LV_USE_FONT_COMPRESSED @@ -490,13 +487,13 @@ static inline uint8_t rle_next(void) ret = get_bits(rle->in, rle->rdp, rle->bpp); if(rle->rdp != 0 && rle->prev_v == ret) { rle->count = 0; - rle->state = RLE_STATE_REPEATE; + rle->state = RLE_STATE_REPEATED; } rle->prev_v = ret; rle->rdp += rle->bpp; } - else if(rle->state == RLE_STATE_REPEATE) { + else if(rle->state == RLE_STATE_REPEATED) { v = get_bits(rle->in, rle->rdp, 1); rle->count++; rle->rdp += 1; @@ -552,7 +549,7 @@ static inline uint8_t rle_next(void) * @retval > 0 Reference is greater than element. * */ -static int32_t unicode_list_compare(const void * ref, const void * element) +static int unicode_list_compare(const void * ref, const void * element) { - return ((int32_t)(*(uint16_t *)ref)) - ((int32_t)(*(uint16_t *)element)); + return (*(uint16_t *)ref) - (*(uint16_t *)element); } diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.h b/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.h index 76bade065..4eeb0c6e1 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.h +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt.h @@ -13,10 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include -#include #include "lv_font.h" +#include "../misc/lv_types.h" /********************* * DEFINES @@ -46,18 +44,12 @@ typedef struct { } lv_font_fmt_txt_glyph_dsc_t; /** Format of font character map.*/ -enum _lv_font_fmt_txt_cmap_type_t { +typedef enum { LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, -}; - -#ifdef DOXYGEN -typedef _lv_font_fmt_txt_cmap_type_t lv_font_fmt_txt_cmap_type_t; -#else -typedef uint8_t lv_font_fmt_txt_cmap_type_t; -#endif /*DOXYGEN*/ +} lv_font_fmt_txt_cmap_type_t; /** * Map codepoints to a `glyph_dsc`s @@ -128,7 +120,7 @@ typedef struct { const void * glyph_ids; const int8_t * values; uint32_t pair_cnt : 30; - uint32_t glyph_ids_size : 2; /*0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t`*/ + uint32_t glyph_ids_size : 2; /**< 0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t` */ } lv_font_fmt_txt_kern_pair_t; /** More complex but more optimal class based kern value storage*/ @@ -141,9 +133,9 @@ typedef struct { 3. value = class_pair_values[(left_class-1)*right_class_cnt + (right_class-1)] */ - const int8_t * class_pair_values; /*left_class_cnt * right_class_cnt value*/ - const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/ - const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/ + const int8_t * class_pair_values; /**< left_class_cnt * right_class_cnt value */ + const uint8_t * left_class_mapping; /**< Map the glyph_ids to classes: index -> glyph_id -> class_id */ + const uint8_t * right_class_mapping; /**< Map the glyph_ids to classes: index -> glyph_id -> class_id */ uint8_t left_class_cnt; uint8_t right_class_cnt; } lv_font_fmt_txt_kern_classes_t; @@ -155,16 +147,16 @@ typedef enum { LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1, } lv_font_fmt_txt_bitmap_format_t; -/*Describe store additional data for fonts*/ +/** Describe store for additional data for fonts */ typedef struct { - /*The bitmaps of all glyphs*/ + /** The bitmaps of all glyphs */ const uint8_t * glyph_bitmap; - /*Describe the glyphs*/ + /** Describe the glyphs */ const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc; - /*Map the glyphs to Unicode characters. - *Array of `lv_font_cmap_fmt_txt_t` variables*/ + /** Map the glyphs to Unicode characters. + *Array of `lv_font_cmap_fmt_txt_t` variables */ const lv_font_fmt_txt_cmap_t * cmaps; /** @@ -174,55 +166,36 @@ typedef struct { */ const void * kern_dsc; - /*Scale kern values in 12.4 format*/ + /** Scale kern values in 12.4 format */ uint16_t kern_scale; - /*Number of cmap tables*/ + /** Number of cmap tables */ uint16_t cmap_num : 9; - /*Bit per pixel: 1, 2, 3, 4, 8*/ + /** Bit per pixel: 1, 2, 3, 4, 8 */ uint16_t bpp : 4; - /*Type of `kern_dsc`*/ + /** Type of `kern_dsc` */ uint16_t kern_classes : 1; - /* + /** * storage format of the bitmap * from `lv_font_fmt_txt_bitmap_format_t` */ uint16_t bitmap_format : 2; } lv_font_fmt_txt_dsc_t; -#if LV_USE_FONT_COMPRESSED -typedef enum { - RLE_STATE_SINGLE = 0, - RLE_STATE_REPEATE, - RLE_STATE_COUNTER, -} lv_font_fmt_rle_state_t; - -typedef struct { - uint32_t rdp; - const uint8_t * in; - uint8_t bpp; - uint8_t prev_v; - uint8_t count; - lv_font_fmt_rle_state_t state; -} lv_font_fmt_rle_t; -#endif - /********************** * GLOBAL PROTOTYPES **********************/ /** * Used as `get_glyph_bitmap` callback in lvgl's native font format if the font is uncompressed. - * @param g_dsc the glyph descriptor including which font to use etc. - * @param letter a UNICODE character code + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and format. * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. * @return pointer to an A8 bitmap (not necessarily bitmap_out) or NULL if `unicode_letter` not found */ -const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode_letter, - lv_draw_buf_t * draw_buf); +const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); /** * Used as `get_glyph_dsc` callback in lvgl's native font format if the font is uncompressed. diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt_private.h b/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt_private.h new file mode 100644 index 000000000..66df402d6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_fmt_txt_private.h @@ -0,0 +1,56 @@ +/** + * @file lv_font_fmt_txt_private.h + * + */ + +#ifndef LV_FONT_FMT_TXT_PRIVATE_H +#define LV_FONT_FMT_TXT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_font_fmt_txt.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_FONT_COMPRESSED +typedef enum { + RLE_STATE_SINGLE = 0, + RLE_STATE_REPEATED, + RLE_STATE_COUNTER, +} lv_font_fmt_rle_state_t; + +typedef struct { + uint32_t rdp; + const uint8_t * in; + uint8_t bpp; + uint8_t prev_v; + uint8_t count; + lv_font_fmt_rle_state_t state; +} lv_font_fmt_rle_t; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FONT_FMT_TXT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_14_cjk.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_14_cjk.c new file mode 100644 index 000000000..4cd687f94 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_14_cjk.c @@ -0,0 +1,20783 @@ +/******************************************************************************* + * Size: 14 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 14 --font SimSun.woff -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可廿节宵植树端阳旦腊妇费愚劳动儿军师庆圣诞闰 --font FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl -o lv_font_simsun_14_cjk.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE + #include "lvgl.h" +#else + #include "../../lvgl.h" +#endif + +#ifndef LV_FONT_SIMSUN_14_CJK + #define LV_FONT_SIMSUN_14_CJK 1 +#endif + +#if LV_FONT_SIMSUN_14_CJK + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0x1d, 0x2, 0xf0, 0xe, 0x0, 0xc0, 0xa, 0x0, + 0x80, 0x5, 0x0, 0x0, 0x18, 0x2, 0xe1, + + /* U+0022 "\"" */ + 0x0, 0x89, 0x5b, 0x1, 0xe3, 0xd5, 0x8, 0x45, + 0x60, 0x4, 0x4, 0x0, + + /* U+0023 "#" */ + 0x0, 0x70, 0x7, 0x0, 0x7, 0x0, 0x70, 0x7f, + 0xff, 0xff, 0x71, 0x46, 0x24, 0x61, 0x4, 0x30, + 0x43, 0x0, 0x52, 0x5, 0x20, 0x7f, 0xff, 0xff, + 0x71, 0x92, 0x28, 0x21, 0x7, 0x0, 0x70, 0x0, + 0x70, 0x7, 0x0, + + /* U+0024 "$" */ + 0x0, 0x4, 0x0, 0x0, 0x8, 0x0, 0x1, 0x8b, + 0x82, 0x9, 0x28, 0x4a, 0xc, 0x28, 0x46, 0x6, + 0xc9, 0x0, 0x0, 0x8f, 0x30, 0x0, 0xa, 0xe2, + 0x0, 0x8, 0x6a, 0xd, 0x28, 0xc, 0xe, 0x8, + 0x19, 0x4, 0x7b, 0x71, 0x0, 0x8, 0x0, 0x0, + 0x4, 0x0, + + /* U+0025 "%" */ + 0x0, 0x0, 0x2, 0x4, 0x76, 0x3, 0x40, 0xa0, + 0x90, 0x70, 0xb, 0x9, 0x16, 0x0, 0x90, 0xa5, + 0x10, 0x1, 0x64, 0x64, 0x60, 0x0, 0x15, 0x93, + 0x60, 0x6, 0x37, 0x9, 0x0, 0x64, 0x70, 0xa0, + 0x32, 0x18, 0x28, 0x5, 0x0, 0x78, 0x10, + + /* U+0026 "&" */ + 0x3, 0x79, 0x0, 0x0, 0xa0, 0x83, 0x0, 0xb, + 0x9, 0x20, 0x0, 0xa5, 0x80, 0x0, 0x8, 0xa0, + 0x78, 0x14, 0x6d, 0x4, 0x40, 0xb0, 0x95, 0x51, + 0xc, 0x2, 0xd7, 0x0, 0x95, 0x8, 0xb0, 0x31, + 0xb9, 0x68, 0xc5, + + /* U+0027 "'" */ + 0xd, 0x60, 0x8a, 0x5, 0x50, 0x60, + + /* U+0028 "(" */ + 0x0, 0x0, 0x0, 0x71, 0x5, 0x40, 0xa, 0x0, + 0x65, 0x0, 0xb1, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0xc0, 0x0, 0xb0, 0x0, 0x65, 0x0, 0x1a, 0x0, + 0x6, 0x40, 0x0, 0x81, 0x0, 0x1, + + /* U+0029 ")" */ + 0x0, 0x0, 0x26, 0x0, 0x5, 0x40, 0x0, 0xa0, + 0x0, 0x65, 0x0, 0x2a, 0x0, 0xc, 0x0, 0xc, + 0x0, 0xc, 0x0, 0x1b, 0x0, 0x66, 0x0, 0xa0, + 0x4, 0x50, 0x17, 0x0, 0x10, 0x0, + + /* U+002A "*" */ + 0x0, 0x5, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x6b, + 0xb, 0x1c, 0x50, 0x7a, 0x7a, 0x70, 0x0, 0x6a, + 0x60, 0x4, 0xe5, 0x86, 0xe3, 0x24, 0xd, 0x4, + 0x20, 0x0, 0xd0, 0x0, + + /* U+002B "+" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, + 0x7, 0x0, 0x0, 0x0, 0x70, 0x0, 0x38, 0x8c, + 0x88, 0x40, 0x0, 0x70, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x0, 0x70, 0x0, 0x0, 0x2, 0x0, 0x0, + + /* U+002C "," */ + 0xd, 0x60, 0x8a, 0x5, 0x50, 0x60, + + /* U+002D "-" */ + 0x48, 0x88, 0x88, 0x40, + + /* U+002E "." */ + 0x9, 0x40, 0xd6, + + /* U+002F "/" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x60, 0x0, + 0x0, 0x7, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, + 0x70, 0x0, 0x0, 0x43, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x2, 0x50, 0x0, 0x0, 0x70, 0x0, 0x0, + 0x6, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x70, + 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+0030 "0" */ + 0x0, 0x97, 0x90, 0x0, 0x95, 0x4, 0x90, 0xe, + 0x0, 0xe, 0x3, 0xc0, 0x0, 0xd3, 0x4b, 0x0, + 0xc, 0x45, 0xb0, 0x0, 0xc3, 0x3c, 0x0, 0xd, + 0x20, 0xe0, 0x0, 0xe0, 0x9, 0x50, 0x48, 0x0, + 0x9, 0x79, 0x0, + + /* U+0031 "1" */ + 0x26, 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, + 0xe, 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, + 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x2, 0x7f, + 0x83, + + /* U+0032 "2" */ + 0x3, 0x76, 0x93, 0x0, 0xb0, 0x1, 0xd0, 0x1f, + 0x0, 0xe, 0x0, 0x40, 0x1, 0xc0, 0x0, 0x0, + 0x84, 0x0, 0x0, 0x46, 0x0, 0x0, 0x36, 0x0, + 0x0, 0x17, 0x0, 0x20, 0x8, 0x0, 0x8, 0x4, + 0xee, 0xee, 0xd0, + + /* U+0033 "3" */ + 0x4, 0x67, 0x91, 0x0, 0xd0, 0x5, 0x90, 0x8, + 0x0, 0x3b, 0x0, 0x0, 0x8, 0x40, 0x0, 0x2a, + 0x80, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0xe, + 0x0, 0xb0, 0x0, 0xe0, 0x1e, 0x0, 0x2b, 0x0, + 0x57, 0x68, 0x10, + + /* U+0034 "4" */ + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6e, 0x0, 0x0, + 0x15, 0xd0, 0x0, 0x7, 0xd, 0x0, 0x4, 0x20, + 0xd0, 0x0, 0x60, 0xd, 0x0, 0x45, 0x55, 0xe5, + 0x20, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0x1, 0x6f, 0x81, + + /* U+0035 "5" */ + 0x8, 0xee, 0xec, 0x0, 0x60, 0x0, 0x0, 0x6, + 0x0, 0x0, 0x0, 0x68, 0x9b, 0x20, 0x9, 0x10, + 0x3b, 0x0, 0x0, 0x0, 0xe0, 0x1, 0x0, 0xd, + 0x11, 0xf0, 0x0, 0xd0, 0xc, 0x0, 0x2a, 0x0, + 0x37, 0x69, 0x10, + + /* U+0036 "6" */ + 0x0, 0x66, 0x96, 0x0, 0x73, 0x2, 0x60, 0xc, + 0x0, 0x0, 0x2, 0xb6, 0x9c, 0x40, 0x4e, 0x40, + 0x1d, 0x5, 0xc0, 0x0, 0xb3, 0x4c, 0x0, 0xa, + 0x41, 0xe0, 0x0, 0xb2, 0xb, 0x40, 0xb, 0x0, + 0x1a, 0x68, 0x20, + + /* U+0037 "7" */ + 0xd, 0xee, 0xef, 0x10, 0x90, 0x0, 0x70, 0x2, + 0x0, 0x61, 0x0, 0x0, 0x8, 0x0, 0x0, 0x5, + 0x40, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x0, 0x7b, 0x0, 0x0, + 0x6, 0xa0, 0x0, + + /* U+0038 "8" */ + 0x3, 0x86, 0x82, 0x0, 0xb0, 0x0, 0xb0, 0x2b, + 0x0, 0xb, 0x0, 0xd6, 0x1, 0xa0, 0x1, 0xec, + 0x90, 0x0, 0x83, 0x5e, 0x50, 0x39, 0x0, 0x2e, + 0x5, 0x60, 0x0, 0xb2, 0x29, 0x0, 0xb, 0x0, + 0x47, 0x67, 0x30, + + /* U+0039 "9" */ + 0x4, 0x87, 0x81, 0x1, 0xc0, 0x2, 0xa0, 0x59, + 0x0, 0xd, 0x5, 0x90, 0x0, 0xe2, 0x1d, 0x10, + 0x6e, 0x30, 0x49, 0x83, 0xe2, 0x0, 0x0, 0xf, + 0x0, 0x10, 0x3, 0xa0, 0xd, 0x30, 0x94, 0x0, + 0x79, 0x76, 0x0, + + /* U+003A ":" */ + 0x3e, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x80, 0x3e, 0x0, + + /* U+003B ";" */ + 0x3f, 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x50, 0x3f, 0x0, 0xa0, 0x3, 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x5, 0x0, 0x0, 0x5, 0x40, 0x0, + 0x5, 0x50, 0x0, 0x4, 0x60, 0x0, 0x3, 0x70, + 0x0, 0x0, 0xa0, 0x0, 0x0, 0x4, 0x60, 0x0, + 0x0, 0x5, 0x50, 0x0, 0x0, 0x6, 0x40, 0x0, + 0x0, 0x6, 0x30, 0x0, 0x0, 0x6, 0x0, + + /* U+003D "=" */ + 0x48, 0x88, 0x88, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x88, 0x88, 0x84, + + /* U+003E ">" */ + 0x5, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0x0, + 0x55, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, + 0x73, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x64, + 0x0, 0x0, 0x55, 0x0, 0x0, 0x46, 0x0, 0x0, + 0x37, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, + + /* U+003F "?" */ + 0x2, 0x88, 0xa4, 0x0, 0x80, 0x0, 0xd1, 0x3a, + 0x0, 0xb, 0x31, 0x90, 0x0, 0xe1, 0x0, 0x1, + 0xa5, 0x0, 0x0, 0x81, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x0, 0x20, 0x0, 0x0, 0x18, 0x0, 0x0, + 0x3, 0xe0, 0x0, + + /* U+0040 "@" */ + 0x0, 0x77, 0x74, 0x0, 0x72, 0x46, 0xa2, 0x9, + 0x17, 0x65, 0x74, 0x67, 0x27, 0x37, 0x65, 0xb0, + 0x91, 0x76, 0x5b, 0xa, 0x7, 0x46, 0xa1, 0xc4, + 0x31, 0x95, 0x66, 0x61, 0x8, 0x10, 0x4, 0x30, + 0x8, 0x77, 0x50, + + /* U+0041 "A" */ + 0x0, 0xb, 0x0, 0x0, 0x4, 0xe2, 0x0, 0x0, + 0x77, 0x60, 0x0, 0x8, 0x49, 0x0, 0x0, 0x70, + 0xd0, 0x0, 0x44, 0xc, 0x10, 0x7, 0x65, 0xb5, + 0x0, 0x80, 0x5, 0x80, 0x7, 0x0, 0x1c, 0x8, + 0xb0, 0x4, 0xf5, + + /* U+0042 "B" */ + 0x4e, 0x66, 0x95, 0x0, 0xd0, 0x0, 0xe0, 0xd, + 0x0, 0xe, 0x0, 0xd0, 0x3, 0xb0, 0xd, 0x56, + 0xb1, 0x0, 0xd0, 0x1, 0xc0, 0xd, 0x0, 0x9, + 0x60, 0xd0, 0x0, 0x97, 0xd, 0x0, 0xc, 0x34, + 0xe6, 0x68, 0x60, + + /* U+0043 "C" */ + 0x0, 0x87, 0x8f, 0x10, 0x94, 0x0, 0x54, 0x1d, + 0x0, 0x0, 0x36, 0x90, 0x0, 0x0, 0x88, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x4, 0xc0, 0x0, 0x4, 0xd, 0x30, 0x6, 0x10, + 0x1a, 0x88, 0x30, + + /* U+0044 "D" */ + 0x4e, 0x76, 0x80, 0x0, 0xd0, 0x3, 0xb0, 0xd, + 0x0, 0xc, 0x30, 0xd0, 0x0, 0x96, 0xd, 0x0, + 0x8, 0x70, 0xd0, 0x0, 0x87, 0xd, 0x0, 0xa, + 0x60, 0xd0, 0x0, 0xd2, 0xd, 0x0, 0x4a, 0x4, + 0xe7, 0x78, 0x0, + + /* U+0045 "E" */ + 0x3e, 0x75, 0x7d, 0x0, 0xc1, 0x0, 0x43, 0xc, + 0x10, 0x0, 0x0, 0xc1, 0x5, 0x0, 0xc, 0x65, + 0xd0, 0x0, 0xc1, 0x6, 0x0, 0xc, 0x10, 0x20, + 0x0, 0xc1, 0x0, 0x1, 0xc, 0x10, 0x2, 0x53, + 0xe7, 0x57, 0xe1, + + /* U+0046 "F" */ + 0x3e, 0x75, 0x6d, 0x30, 0xc1, 0x0, 0x17, 0xc, + 0x10, 0x0, 0x0, 0xc1, 0x2, 0x40, 0xc, 0x65, + 0xb4, 0x0, 0xc1, 0x2, 0x40, 0xc, 0x10, 0x1, + 0x0, 0xc1, 0x0, 0x0, 0xc, 0x10, 0x0, 0x4, + 0xe7, 0x0, 0x0, + + /* U+0047 "G" */ + 0x1, 0x97, 0xc8, 0x0, 0xa2, 0x0, 0x90, 0x1a, + 0x0, 0x3, 0x6, 0x70, 0x0, 0x0, 0x86, 0x0, + 0x0, 0x9, 0x60, 0x7, 0xa4, 0x77, 0x0, 0xe, + 0x3, 0xb0, 0x0, 0xd0, 0xc, 0x10, 0xd, 0x0, + 0x29, 0x67, 0x40, + + /* U+0048 "H" */ + 0x5f, 0x30, 0x3f, 0x40, 0xd0, 0x0, 0xe0, 0xd, + 0x0, 0xe, 0x0, 0xd0, 0x0, 0xe0, 0xe, 0x55, + 0x5e, 0x0, 0xd0, 0x0, 0xe0, 0xd, 0x0, 0xe, + 0x0, 0xd0, 0x0, 0xe0, 0xd, 0x0, 0xe, 0x5, + 0xf3, 0x4, 0xf4, + + /* U+0049 "I" */ + 0x36, 0xf6, 0x30, 0xe, 0x0, 0x0, 0xe0, 0x0, + 0xe, 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, + 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x3, 0x6f, + 0x63, + + /* U+004A "J" */ + 0x0, 0x46, 0xf5, 0x30, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xd, 0x0, 0x57, 0x3, 0x90, 0x3, 0xb6, + 0x70, 0x0, + + /* U+004B "K" */ + 0x4e, 0x50, 0x8c, 0x20, 0xd0, 0x7, 0x0, 0xd, + 0x4, 0x30, 0x0, 0xd1, 0x70, 0x0, 0xd, 0x8c, + 0x0, 0x0, 0xd4, 0xa4, 0x0, 0xd, 0x3, 0xb0, + 0x0, 0xd0, 0xc, 0x20, 0xd, 0x0, 0x59, 0x4, + 0xe6, 0x4, 0xf5, + + /* U+004C "L" */ + 0x2d, 0x80, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb, + 0x30, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb, 0x30, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb, 0x30, 0x0, + 0x0, 0xb3, 0x0, 0x1, 0xb, 0x30, 0x1, 0x53, + 0xd8, 0x56, 0xd2, + + /* U+004D "M" */ + 0x7c, 0x0, 0xf, 0x62, 0xe0, 0x3, 0xe2, 0x2b, + 0x30, 0x6c, 0x22, 0x86, 0x6, 0xc2, 0x25, 0x90, + 0x6c, 0x22, 0x2c, 0x14, 0xc2, 0x22, 0xb5, 0xc, + 0x22, 0x28, 0x90, 0xc2, 0x22, 0x59, 0xc, 0x27, + 0x72, 0x63, 0xe7, + + /* U+004E "N" */ + 0x4f, 0x10, 0x1a, 0x50, 0xc8, 0x0, 0x50, 0x5, + 0xd1, 0x5, 0x0, 0x57, 0x80, 0x50, 0x5, 0xd, + 0x5, 0x0, 0x50, 0x87, 0x50, 0x5, 0x1, 0xe5, + 0x0, 0x50, 0x8, 0xc0, 0x5, 0x0, 0x1f, 0x5, + 0xa1, 0x0, 0x90, + + /* U+004F "O" */ + 0x1, 0x96, 0x81, 0x0, 0xa2, 0x0, 0xb0, 0x1c, + 0x0, 0xb, 0x35, 0x90, 0x0, 0x87, 0x78, 0x0, + 0x7, 0x97, 0x80, 0x0, 0x79, 0x59, 0x0, 0x7, + 0x71, 0xb0, 0x0, 0xa3, 0xa, 0x20, 0xb, 0x0, + 0x18, 0x57, 0x20, + + /* U+0050 "P" */ + 0x3e, 0x75, 0x75, 0x0, 0xc1, 0x0, 0xb2, 0xc, + 0x10, 0x8, 0x60, 0xc1, 0x0, 0x95, 0xc, 0x10, + 0x1c, 0x0, 0xc6, 0x57, 0x10, 0xc, 0x10, 0x0, + 0x0, 0xc1, 0x0, 0x0, 0xc, 0x10, 0x0, 0x4, + 0xe7, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x2, 0x96, 0x81, 0x0, 0xc1, 0x1, 0xb0, 0x3b, + 0x0, 0xb, 0x36, 0x90, 0x0, 0x87, 0x87, 0x0, + 0x7, 0x88, 0x70, 0x0, 0x78, 0x78, 0x0, 0x8, + 0x74, 0xa8, 0xa1, 0xa3, 0xd, 0x44, 0x9b, 0x0, + 0x28, 0x7f, 0x30, 0x0, 0x0, 0x7d, 0x20, + + /* U+0052 "R" */ + 0x3d, 0x76, 0x95, 0x0, 0xb2, 0x0, 0xe1, 0xb, + 0x20, 0xc, 0x20, 0xb2, 0x2, 0xc0, 0xb, 0x68, + 0x91, 0x0, 0xb2, 0x58, 0x0, 0xb, 0x20, 0xd0, + 0x0, 0xb2, 0xa, 0x40, 0xb, 0x20, 0x49, 0x3, + 0xd7, 0x0, 0xe4, + + /* U+0053 "S" */ + 0x4, 0x67, 0xcb, 0x1, 0x80, 0x0, 0x90, 0x37, + 0x0, 0x1, 0x1, 0xd3, 0x0, 0x0, 0x3, 0xcb, + 0x20, 0x0, 0x0, 0x5d, 0x50, 0x0, 0x0, 0x1d, + 0x3, 0x10, 0x0, 0x92, 0x38, 0x0, 0xa, 0x0, + 0xfa, 0x67, 0x30, + + /* U+0054 "T" */ + 0x3b, 0x6f, 0x6b, 0x26, 0x0, 0xe0, 0x15, 0x10, + 0xe, 0x0, 0x10, 0x0, 0xe0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x6, 0xf5, 0x0, + + /* U+0055 "U" */ + 0x5f, 0x30, 0x1a, 0x40, 0xd0, 0x0, 0x50, 0xd, + 0x0, 0x5, 0x0, 0xd0, 0x0, 0x50, 0xd, 0x0, + 0x5, 0x0, 0xd0, 0x0, 0x50, 0xd, 0x0, 0x5, + 0x0, 0xd0, 0x0, 0x50, 0xc, 0x0, 0x6, 0x0, + 0x39, 0x77, 0x10, + + /* U+0056 "V" */ + 0x5f, 0x30, 0x2c, 0x40, 0xd1, 0x0, 0x70, 0x9, + 0x40, 0x15, 0x0, 0x58, 0x5, 0x10, 0x2, 0xc0, + 0x60, 0x0, 0xd, 0x6, 0x0, 0x0, 0xa4, 0x50, + 0x0, 0x7, 0xb1, 0x0, 0x0, 0x3d, 0x0, 0x0, + 0x0, 0x80, 0x0, + + /* U+0057 "W" */ + 0x9a, 0x2e, 0x36, 0x83, 0x80, 0xb0, 0x32, 0x1a, + 0xb, 0x25, 0x0, 0xb0, 0xd4, 0x50, 0xb, 0x1a, + 0x65, 0x0, 0xa5, 0x58, 0x50, 0x8, 0x91, 0xb5, + 0x0, 0x6b, 0xe, 0x20, 0x3, 0x90, 0xc0, 0x0, + 0x16, 0x7, 0x0, + + /* U+0058 "X" */ + 0x2d, 0x70, 0x4c, 0x20, 0x57, 0x3, 0x30, 0x0, + 0xc0, 0x70, 0x0, 0x8, 0x75, 0x0, 0x0, 0x1e, + 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x65, 0xa0, + 0x0, 0x7, 0xc, 0x10, 0x5, 0x20, 0x68, 0x3, + 0xd2, 0x5, 0xf4, + + /* U+0059 "Y" */ + 0x4f, 0x40, 0x3d, 0x40, 0xa3, 0x0, 0x60, 0x4, + 0x90, 0x41, 0x0, 0xd, 0x6, 0x0, 0x0, 0x95, + 0x50, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x6, 0xf5, 0x0, + + /* U+005A "Z" */ + 0xb, 0x95, 0x5e, 0x21, 0x70, 0x4, 0xa0, 0x0, + 0x0, 0xc2, 0x0, 0x0, 0x4a, 0x0, 0x0, 0xc, + 0x20, 0x0, 0x4, 0xa0, 0x0, 0x0, 0xb2, 0x0, + 0x0, 0x4a, 0x0, 0x1, 0xb, 0x20, 0x6, 0x24, + 0xd5, 0x57, 0xd0, + + /* U+005B "[" */ + 0x39, 0x88, 0x4, 0x40, 0x0, 0x44, 0x0, 0x4, + 0x40, 0x0, 0x44, 0x0, 0x4, 0x40, 0x0, 0x44, + 0x0, 0x4, 0x40, 0x0, 0x44, 0x0, 0x4, 0x40, + 0x0, 0x44, 0x0, 0x4, 0x40, 0x0, 0x44, 0x0, + 0x3, 0x98, 0x80, + + /* U+005C "\\" */ + 0xa0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x9, 0x0, + 0x0, 0x9, 0x0, 0x0, 0x4, 0x50, 0x0, 0x0, + 0xa0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x27, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x6, 0x30, 0x0, 0x1, + 0x90, 0x0, 0x0, 0x90, 0x0, 0x0, 0x32, + + /* U+005D "]" */ + 0x8, 0x89, 0x20, 0x0, 0x53, 0x0, 0x5, 0x30, + 0x0, 0x53, 0x0, 0x5, 0x30, 0x0, 0x53, 0x0, + 0x5, 0x30, 0x0, 0x53, 0x0, 0x5, 0x30, 0x0, + 0x53, 0x0, 0x5, 0x30, 0x0, 0x53, 0x0, 0x5, + 0x30, 0x88, 0x92, + + /* U+005E "^" */ + 0x8, 0xb8, 0x1, 0x30, 0x31, + + /* U+005F "_" */ + 0x55, 0x55, 0x55, 0x50, + + /* U+0060 "`" */ + 0x5c, 0x30, 0x4, + + /* U+0061 "a" */ + 0x5, 0x65, 0x81, 0x0, 0xd0, 0x4, 0x80, 0x0, + 0x4, 0x79, 0x0, 0x78, 0x23, 0x90, 0x3b, 0x0, + 0x39, 0x5, 0x90, 0x3, 0x92, 0xa, 0x76, 0x6b, + 0x50, + + /* U+0062 "b" */ + 0x3, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x47, + 0x94, 0x0, 0xd4, 0x0, 0xc0, 0xc, 0x0, 0xb, + 0x20, 0xc0, 0x0, 0xa3, 0xc, 0x0, 0xb, 0x10, + 0xd1, 0x0, 0xb0, 0x8, 0x66, 0x82, 0x0, + + /* U+0063 "c" */ + 0x0, 0x85, 0x83, 0x0, 0xa2, 0x3, 0xa0, 0xd, + 0x0, 0x2, 0x2, 0xb0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xb2, 0x0, 0x60, 0x1, 0x97, 0x73, + 0x0, + + /* U+0064 "d" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x1, 0x97, + 0x6c, 0x0, 0xa2, 0x0, 0xc0, 0xc, 0x0, 0xc, + 0x2, 0xb0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, + 0xb1, 0x3, 0xc0, 0x2, 0x97, 0x5c, 0x30, + + /* U+0065 "e" */ + 0x0, 0x86, 0x82, 0x0, 0x92, 0x1, 0xc0, 0xc, + 0x0, 0xc, 0x11, 0xd5, 0x55, 0x91, 0xd, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x50, 0x1, 0x97, 0x73, + 0x0, + + /* U+0066 "f" */ + 0x0, 0x7, 0x58, 0x50, 0x6, 0x40, 0x24, 0x0, + 0x83, 0x0, 0x1, 0x5b, 0x75, 0x20, 0x0, 0x83, + 0x0, 0x0, 0x8, 0x30, 0x0, 0x0, 0x83, 0x0, + 0x0, 0x8, 0x30, 0x0, 0x0, 0x83, 0x0, 0x0, + 0x5c, 0x95, 0x0, + + /* U+0067 "g" */ + 0x1, 0x86, 0x99, 0x70, 0xa1, 0x6, 0x60, 0xb, + 0x0, 0x47, 0x0, 0x83, 0x7, 0x30, 0x5, 0x75, + 0x40, 0x0, 0x99, 0x64, 0x0, 0x7, 0x2, 0x5b, + 0x2, 0x90, 0x0, 0x91, 0x7, 0x65, 0x66, 0x0, + + /* U+0068 "h" */ + 0x6, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x58, + 0xa4, 0x0, 0xc4, 0x0, 0xb0, 0xc, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0xc0, 0x3e, 0x50, 0x4e, 0x30, + + /* U+0069 "i" */ + 0x0, 0xe2, 0x0, 0x5, 0x0, 0x0, 0x20, 0x2, + 0x5d, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x2, 0x6e, + 0x63, + + /* U+006A "j" */ + 0x0, 0x8, 0x80, 0x0, 0x33, 0x0, 0x1, 0x10, + 0x5, 0xa6, 0x0, 0x5, 0x60, 0x0, 0x56, 0x0, + 0x5, 0x60, 0x0, 0x56, 0x0, 0x5, 0x60, 0x0, + 0x55, 0x60, 0x8, 0x29, 0x97, 0x50, + + /* U+006B "k" */ + 0x6, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, + 0xc7, 0x0, 0xb0, 0x26, 0x0, 0xb, 0x1b, 0x0, + 0x0, 0xb8, 0xa3, 0x0, 0xb, 0x12, 0xc0, 0x0, + 0xb0, 0x9, 0x50, 0x2d, 0x50, 0x5e, 0x30, + + /* U+006C "l" */ + 0x2, 0x90, 0x3, 0x5d, 0x0, 0x0, 0xc0, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0xc, + 0x0, 0x36, 0xe6, 0x30, + + /* U+006D "m" */ + 0x8a, 0x7a, 0x7a, 0x24, 0x90, 0xc0, 0x55, 0x47, + 0xc, 0x5, 0x64, 0x70, 0xc0, 0x56, 0x47, 0xc, + 0x5, 0x64, 0x70, 0xc0, 0x56, 0x8b, 0x2e, 0x39, + 0xa0, + + /* U+006E "n" */ + 0x3e, 0x47, 0x94, 0x0, 0xc4, 0x0, 0xb0, 0xc, + 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc0, 0xc, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0xc0, 0x3e, 0x50, 0x4e, + 0x30, + + /* U+006F "o" */ + 0x1, 0x86, 0x82, 0x0, 0xb0, 0x0, 0xb0, 0x2a, + 0x0, 0xa, 0x24, 0x80, 0x0, 0x84, 0x3a, 0x0, + 0xa, 0x30, 0xb0, 0x0, 0xb0, 0x2, 0x85, 0x71, + 0x0, + + /* U+0070 "p" */ + 0x4e, 0x57, 0x94, 0x0, 0xc3, 0x0, 0xc0, 0xc, + 0x0, 0x9, 0x30, 0xc0, 0x0, 0x84, 0xc, 0x0, + 0xa, 0x30, 0xc1, 0x0, 0xc0, 0xc, 0x66, 0x92, + 0x0, 0xc0, 0x0, 0x0, 0x3e, 0x50, 0x0, 0x0, + + /* U+0071 "q" */ + 0x2, 0x86, 0x68, 0x0, 0xb0, 0x2, 0xc0, 0x2a, + 0x0, 0xc, 0x4, 0x90, 0x0, 0xc0, 0x2a, 0x0, + 0xc, 0x0, 0xb0, 0x2, 0xc0, 0x3, 0x97, 0x5c, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6e, 0x30, + + /* U+0072 "r" */ + 0x38, 0xc2, 0x7c, 0x30, 0xc, 0x60, 0x42, 0x0, + 0xe0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x36, 0xe5, 0x20, + 0x0, + + /* U+0073 "s" */ + 0x17, 0x6b, 0xa8, 0x10, 0x8, 0x69, 0x10, 0x0, + 0x5c, 0xa1, 0x10, 0x4, 0xc8, 0x0, 0xa, 0xba, + 0x66, 0x40, + + /* U+0074 "t" */ + 0x0, 0x24, 0x0, 0x0, 0x94, 0x0, 0x5, 0xa8, + 0x52, 0x0, 0x74, 0x0, 0x0, 0x74, 0x0, 0x0, + 0x74, 0x0, 0x0, 0x74, 0x0, 0x0, 0x65, 0x5, + 0x0, 0x1a, 0x83, + + /* U+0075 "u" */ + 0x4d, 0x0, 0x5c, 0x0, 0xc0, 0x0, 0xc0, 0xc, + 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc0, 0xc, 0x0, + 0xc, 0x0, 0xb0, 0x4, 0xc0, 0x4, 0xb8, 0x5c, + 0x30, + + /* U+0076 "v" */ + 0x2d, 0x70, 0x3d, 0x20, 0x75, 0x1, 0x50, 0x2, + 0xa0, 0x50, 0x0, 0xc, 0x6, 0x0, 0x0, 0x84, + 0x50, 0x0, 0x3, 0xd1, 0x0, 0x0, 0xa, 0x0, + 0x0, + + /* U+0077 "w" */ + 0x9b, 0x3e, 0x28, 0x82, 0x90, 0xb0, 0x50, 0xb, + 0xd, 0x35, 0x0, 0xa2, 0x76, 0x50, 0x7, 0x81, + 0xa4, 0x0, 0x4b, 0xd, 0x10, 0x0, 0x80, 0x80, + 0x0, + + /* U+0078 "x" */ + 0x9, 0xd0, 0x89, 0x10, 0xc, 0x18, 0x0, 0x0, + 0x5d, 0x30, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x65, + 0x90, 0x0, 0x16, 0xa, 0x20, 0x2c, 0x50, 0x9c, + 0x20, + + /* U+0079 "y" */ + 0x2c, 0x80, 0x5c, 0x20, 0x57, 0x3, 0x40, 0x0, + 0xb0, 0x70, 0x0, 0x9, 0x17, 0x0, 0x0, 0x48, + 0x50, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x1, 0x50, 0x0, 0xd, 0x90, 0x0, 0x0, + + /* U+007A "z" */ + 0xc, 0x65, 0xa7, 0x0, 0x70, 0x1c, 0x0, 0x0, + 0x9, 0x40, 0x0, 0x2, 0xb0, 0x0, 0x0, 0xb2, + 0x2, 0x0, 0x58, 0x0, 0x70, 0xe, 0x65, 0x8b, + 0x0, + + /* U+007B "{" */ + 0x0, 0x26, 0x0, 0x80, 0x0, 0x70, 0x0, 0x80, + 0x0, 0x80, 0x0, 0x80, 0x5, 0x40, 0x5, 0x40, + 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x70, + 0x0, 0x80, 0x0, 0x27, + + /* U+007C "|" */ + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, + + /* U+007D "}" */ + 0x62, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, + 0x7, 0x0, 0x7, 0x0, 0x4, 0x50, 0x4, 0x50, + 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, + 0x7, 0x0, 0x62, 0x0, + + /* U+007E "~" */ + 0x5, 0x92, 0x0, 0x3, 0x11, 0xb2, 0x4, 0x0, + 0x1, 0x97, 0x0, + + /* U+007F "" */ + + /* U+3001 "、" */ + 0x0, 0x0, 0x29, 0x50, 0x0, 0xd7, 0x0, 0x4d, + 0x0, 0x1, + + /* U+3002 "。" */ + 0x0, 0x0, 0x67, 0x70, 0x70, 0x70, 0x77, 0x70, + 0x0, 0x0, + + /* U+3005 "々" */ + 0x0, 0x11, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, + 0x0, 0x82, 0x0, 0x11, 0x1, 0xc7, 0x55, 0xc8, + 0x7, 0x21, 0x0, 0xb0, 0x11, 0x0, 0x5, 0x50, + 0x0, 0x0, 0x8, 0x0, 0x0, 0x6, 0x52, 0x0, + 0x0, 0x2, 0xd3, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x0, 0x3, 0x0, + + /* U+300C "「" */ + 0x88, 0x86, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, + 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, + 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, + + /* U+300D "」" */ + 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, + 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, + 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x78, 0x88, + + /* U+3041 "ぁ" */ + 0x0, 0x33, 0x0, 0x0, 0x0, 0x55, 0x54, 0x0, + 0x5, 0xa8, 0x30, 0x0, 0x0, 0x63, 0x95, 0x10, + 0x0, 0xb4, 0x71, 0x91, 0x8, 0x67, 0x10, 0x46, + 0x70, 0x58, 0x0, 0x63, 0x78, 0x78, 0x3, 0x80, + 0x1, 0x0, 0x54, 0x0, + + /* U+3042 "あ" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x9, 0x30, + 0x10, 0x0, 0x0, 0xa, 0x7a, 0x91, 0x0, 0x6, + 0x7c, 0x21, 0x0, 0x0, 0x0, 0x9, 0x2c, 0x75, + 0x0, 0x0, 0x2d, 0x6c, 0x3, 0xb1, 0x3, 0xa9, + 0x37, 0x0, 0x48, 0x1a, 0x9, 0xa0, 0x0, 0x29, + 0x82, 0xa, 0x50, 0x0, 0x65, 0x93, 0x89, 0x90, + 0x2, 0xa0, 0x17, 0x20, 0x20, 0x67, 0x0, 0x0, + 0x0, 0x14, 0x10, 0x0, + + /* U+3043 "ぃ" */ + 0x0, 0x0, 0x0, 0x0, 0x55, 0x0, 0x1, 0x0, + 0x62, 0x0, 0x3, 0x50, 0x81, 0x0, 0x0, 0x82, + 0x71, 0x10, 0x1, 0x57, 0x37, 0x60, 0x0, 0x83, + 0x8, 0x30, 0x0, 0x0, + + /* U+3044 "い" */ + 0x34, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, + 0x5, 0x0, 0x65, 0x0, 0x0, 0x2, 0x90, 0x82, + 0x0, 0x0, 0x0, 0x56, 0x91, 0x1, 0x0, 0x0, + 0x1a, 0x74, 0x14, 0x0, 0x4, 0x7b, 0x1c, 0xb1, + 0x0, 0x0, 0x75, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3046 "う" */ + 0x0, 0x32, 0x0, 0x0, 0x0, 0x4, 0xdb, 0x0, + 0x0, 0x2, 0x42, 0x0, 0x0, 0x2, 0x78, 0x20, + 0x3, 0x97, 0x1, 0xb0, 0x58, 0x10, 0x0, 0x92, + 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x3, 0x90, 0x0, 0x0, 0x1b, 0x0, + 0x0, 0x3, 0x91, 0x0, 0x0, 0x43, 0x0, 0x0, + + /* U+3047 "ぇ" */ + 0x0, 0x3, 0x70, 0x0, 0x0, 0x1, 0x60, 0x0, + 0x0, 0x16, 0xb5, 0x0, 0x5, 0x71, 0xa0, 0x0, + 0x0, 0x8, 0x10, 0x0, 0x0, 0x78, 0x40, 0x0, + 0x9, 0x30, 0x80, 0x0, 0x45, 0x0, 0x88, 0x91, + 0x0, 0x0, 0x0, 0x0, + + /* U+3048 "え" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x78, + 0x10, 0x0, 0x0, 0x0, 0x5a, 0x40, 0x0, 0x0, + 0x0, 0x6, 0x30, 0x0, 0x1, 0x47, 0x78, 0x90, + 0x0, 0x6, 0x70, 0x1a, 0x0, 0x0, 0x0, 0x0, + 0x91, 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, + 0x0, 0x58, 0x86, 0x0, 0x0, 0x4, 0x80, 0xa, + 0x0, 0x0, 0x4c, 0x0, 0xb, 0x34, 0x81, 0x31, + 0x0, 0x2, 0x66, 0x30, + + /* U+304A "お" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x1, 0x68, + 0x10, 0x0, 0xa6, 0xb2, 0x0, 0xb8, 0x5, 0x9e, + 0x40, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x89, 0x96, + 0x0, 0x0, 0xc, 0x81, 0x0, 0x66, 0x0, 0x1a, + 0xc0, 0x0, 0x0, 0xc0, 0x6, 0x3a, 0x2, 0x0, + 0x39, 0x0, 0x8, 0xc1, 0x74, 0x4b, 0x20, 0x0, + 0x1d, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+304B "か" */ + 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x3, 0x5a, 0xc9, 0xc1, 0x6, 0x0, + 0x9, 0x5b, 0x10, 0x76, 0x1, 0xb0, 0x0, 0x29, + 0x0, 0x74, 0x0, 0x78, 0x0, 0x92, 0x0, 0xa1, + 0x6, 0xc9, 0x3, 0x80, 0x0, 0xb0, 0x0, 0x62, + 0xc, 0x4, 0x49, 0x60, 0x0, 0x0, 0x14, 0x0, + 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+304C "が" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x0, + 0x82, 0x0, 0x76, 0x50, 0x0, 0x0, 0xb3, 0x0, + 0x6, 0x0, 0x0, 0x1, 0xb1, 0x10, 0x20, 0x0, + 0x17, 0x8c, 0xa6, 0xc2, 0x19, 0x10, 0x4, 0x2b, + 0x0, 0x83, 0x2, 0xc0, 0x0, 0x47, 0x0, 0xa1, + 0x0, 0x95, 0x0, 0xb0, 0x0, 0xb0, 0x18, 0xd6, + 0x6, 0x60, 0x4, 0x70, 0x0, 0x81, 0x2c, 0x6, + 0x6d, 0x20, 0x0, 0x0, 0x12, 0x0, 0xb5, 0x0, + 0x0, 0x0, + + /* U+304D "き" */ + 0x0, 0x10, 0x0, 0x0, 0x1, 0xe1, 0x0, 0x0, + 0x0, 0x48, 0x6a, 0x20, 0x17, 0x8d, 0x40, 0x11, + 0x0, 0x2, 0xa6, 0xa1, 0x4, 0x79, 0xb7, 0x0, + 0x0, 0x0, 0xb, 0x10, 0x5, 0x99, 0x87, 0xb0, + 0x97, 0x0, 0x17, 0xf4, 0xc0, 0x0, 0x0, 0x10, + 0x69, 0x0, 0x1, 0x0, 0x5, 0xcc, 0xca, 0x0, + + /* U+304E "ぎ" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x1c, 0x0, + 0x0, 0x37, 0xb4, 0x0, 0x75, 0x2a, 0x40, 0xa1, + 0x1, 0x36, 0xe7, 0x10, 0x0, 0x0, 0x3, 0x25, + 0x54, 0xb2, 0x0, 0x0, 0x12, 0x6e, 0x80, 0x0, + 0x0, 0x2, 0x42, 0x1a, 0x0, 0x0, 0x0, 0x26, + 0x75, 0x69, 0x0, 0x0, 0x69, 0x32, 0x48, 0xe4, + 0x0, 0xb, 0x0, 0x0, 0x1, 0x0, 0x0, 0x5a, + 0x20, 0x26, 0x10, 0x0, 0x0, 0x4a, 0xca, 0x60, + 0x0, 0x0, + + /* U+304F "く" */ + 0x0, 0x1, 0x50, 0x0, 0x6, 0xe0, 0x0, 0x1c, + 0x20, 0x1, 0xa1, 0x0, 0x9, 0x10, 0x0, 0x71, + 0x0, 0x0, 0x46, 0x0, 0x0, 0x3, 0x91, 0x0, + 0x0, 0x2d, 0x20, 0x0, 0x7, 0xd0, 0x0, 0x0, + 0xe3, 0x0, 0x0, 0x30, + + /* U+3050 "ぐ" */ + 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x8b, 0x0, + 0x0, 0x0, 0x3c, 0x10, 0x8, 0x70, 0x1b, 0x10, + 0xa, 0x34, 0x9, 0x0, 0x0, 0x23, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, + 0x49, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x0, + 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x2, 0xf0, + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, + + /* U+3051 "け" */ + 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x2, 0xc0, + 0x0, 0x1, 0xe0, 0x0, 0x2, 0xa0, 0x0, 0x0, + 0xc0, 0x10, 0x6, 0x50, 0x4, 0x88, 0xea, 0x80, + 0xa, 0x10, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0xb, 0x3, 0x0, 0x0, + 0xb0, 0x0, 0xc, 0x43, 0x0, 0x2, 0x90, 0x0, + 0xa, 0xd0, 0x0, 0x8, 0x40, 0x0, 0x2, 0xc0, + 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x4, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + + /* U+3052 "げ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x15, 0x70, 0x18, 0x0, 0x0, + 0x1b, 0x6, 0x77, 0x1, 0xe0, 0x0, 0x0, 0xd0, + 0x4, 0x0, 0x48, 0x0, 0x0, 0x2d, 0x9a, 0x0, + 0x8, 0x30, 0x5, 0x87, 0xd1, 0x0, 0x0, 0xa0, + 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x30, 0x0, 0xb, + 0x0, 0x0, 0x8, 0x93, 0x0, 0x4, 0x70, 0x0, + 0x0, 0x3f, 0x10, 0x0, 0xb1, 0x0, 0x0, 0x0, + 0x40, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x50, 0x0, 0x0, 0x0, 0x0, + + /* U+3053 "こ" */ + 0x0, 0x11, 0x1, 0x30, 0x0, 0x0, 0x68, 0xed, + 0x20, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x90, 0x0, 0x0, 0x0, 0x7, 0x95, 0x45, 0x7b, + 0x60, 0x2, 0x67, 0x76, 0x20, + + /* U+3054 "ご" */ + 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x10, 0x0, + 0x10, 0x56, 0x72, 0x1, 0x69, 0xcf, 0x60, 0x90, + 0x0, 0x0, 0x37, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xa4, 0x22, 0x48, 0x90, 0x0, 0x1, + 0x69, 0xa9, 0x61, 0x0, 0x0, + + /* U+3055 "さ" */ + 0x1, 0x50, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, + 0x0, 0x1b, 0x25, 0xb0, 0x7, 0x7b, 0xf6, 0x0, + 0x1, 0x20, 0x49, 0x0, 0x0, 0x0, 0x9, 0x50, + 0x19, 0x9a, 0xa9, 0xe0, 0xb1, 0x0, 0x3, 0xd2, + 0xc0, 0x0, 0x0, 0x0, 0x4b, 0x42, 0x33, 0x0, + 0x2, 0x7a, 0xa5, 0x0, + + /* U+3056 "ざ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0x90, 0x0, 0xd3, 0x0, 0x3, 0xb5, + 0x0, 0x1, 0xb1, 0x5, 0x53, 0x0, 0x0, 0x4, + 0xca, 0x70, 0x0, 0x0, 0x36, 0x66, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0x16, + 0x75, 0x2d, 0x10, 0x0, 0x4a, 0x33, 0x59, 0xe7, + 0x0, 0x9, 0x20, 0x0, 0x2, 0x30, 0x0, 0x4a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xbc, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3057 "し" */ + 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, + 0x94, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0xa0, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0x33, 0x75, 0x0, 0x7, 0x60, + 0xc, 0x99, 0xc5, 0x0, 0x0, 0x22, 0x0, 0x0, + + /* U+3058 "じ" */ + 0x20, 0x0, 0x0, 0x0, 0x98, 0x0, 0x6, 0x0, + 0x85, 0x1, 0x74, 0x90, 0x83, 0x0, 0x56, 0x0, + 0x92, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x83, 0x0, 0x0, 0x34, 0x58, 0x0, 0x7, 0x70, + 0xa, 0xba, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3059 "す" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0x1, 0x13, 0x57, 0xd9, 0x9a, 0xa2, + 0x8, 0x96, 0x30, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x69, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0xa0, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x10, + 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, + + /* U+305A "ず" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x50, 0x0, + 0x0, 0x0, 0xe1, 0x0, 0x85, 0x80, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x6, 0x0, 0x0, 0x2, 0x47, + 0xd9, 0x9a, 0xa1, 0x0, 0x8, 0xa7, 0x41, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x90, 0x93, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x90, 0xa4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9a, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0x70, + 0x0, 0x0, 0x0, 0x0, + + /* U+305B "せ" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x91, + 0x0, 0xd1, 0x0, 0x0, 0x9, 0x20, 0xb, 0x0, + 0x0, 0x0, 0x93, 0x57, 0xda, 0xb6, 0x4a, 0x9c, + 0x73, 0xa, 0x0, 0x0, 0x0, 0x91, 0x0, 0xb0, + 0x0, 0x0, 0x8, 0x21, 0xb9, 0x0, 0x0, 0x0, + 0x73, 0x2, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xab, 0xbb, 0x30, + + /* U+305C "ぜ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, + 0x0, 0x0, 0x16, 0x7, 0x4a, 0x0, 0x3, 0x90, + 0x0, 0xe0, 0x37, 0x0, 0x0, 0xb, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x0, 0xb4, 0x69, 0xda, 0xa2, + 0x0, 0x9a, 0x9c, 0x52, 0xa, 0x0, 0x0, 0x0, + 0x0, 0xa0, 0x2, 0x90, 0x0, 0x0, 0x0, 0xa, + 0x2, 0xe4, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x8, 0xbc, 0xca, 0x0, 0x0, + + /* U+305D "そ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, + 0xc4, 0x0, 0x0, 0x8a, 0x42, 0xc4, 0x0, 0x0, + 0x0, 0x39, 0x10, 0x0, 0x0, 0x6, 0x60, 0x2, + 0x30, 0x3, 0x85, 0x79, 0xc9, 0x70, 0x7e, 0x84, + 0x48, 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, + 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x5, 0x50, + 0x0, 0x0, 0x0, 0x0, 0xc7, 0x41, 0x0, 0x0, + 0x0, 0x7, 0xa4, 0x0, + + /* U+305E "ぞ" */ + 0x0, 0x0, 0x0, 0x30, 0x2, 0x40, 0x0, 0x23, + 0x67, 0xe6, 0x36, 0x66, 0x0, 0x86, 0x18, 0x70, + 0x8, 0x30, 0x0, 0x1, 0x93, 0x0, 0x0, 0x0, + 0x0, 0x28, 0x0, 0x25, 0x71, 0x0, 0x6, 0x97, + 0x7c, 0xa5, 0x41, 0x0, 0x6a, 0x40, 0x75, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9c, 0x93, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x61, 0x0, 0x0, + + /* U+305F "た" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x48, 0x14, 0x0, 0x0, 0x24, + 0x9c, 0xa3, 0x0, 0x10, 0x14, 0xb1, 0x2, 0x77, + 0xf5, 0x0, 0xb0, 0x0, 0x17, 0x30, 0x2, 0x90, + 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x60, 0x0, 0x0, 0x67, 0x0, 0x80, + 0x0, 0x0, 0x90, 0x0, 0x39, 0xab, 0xc5, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+3060 "だ" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x6, + 0x70, 0x0, 0x43, 0xb2, 0x0, 0x7, 0x53, 0x20, + 0xb, 0x20, 0x3, 0x3b, 0xb7, 0x0, 0x1, 0x0, + 0x2, 0x5c, 0x0, 0x47, 0x8e, 0x10, 0x0, 0xa, + 0x0, 0x2, 0x73, 0x0, 0x0, 0x56, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x5, 0x0, 0x0, 0x0, 0x7, 0x50, + 0x19, 0x0, 0x0, 0x0, 0xa, 0x0, 0x4, 0xaa, + 0xbc, 0x10, + + /* U+3061 "ち" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xc, 0x30, + 0x0, 0x0, 0x0, 0xb, 0x3, 0x71, 0x0, 0x28, + 0xad, 0x86, 0x30, 0x0, 0x0, 0x54, 0x0, 0x0, + 0x0, 0x0, 0xa0, 0x48, 0x99, 0x20, 0x1, 0xc9, + 0x40, 0x2, 0xd0, 0x2, 0xd1, 0x0, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, + 0x3b, 0x30, 0x0, 0x0, 0x46, 0x40, 0x0, + + /* U+3063 "っ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x78, 0x78, + 0x80, 0xb, 0x71, 0x0, 0x7, 0x40, 0x0, 0x0, + 0x0, 0x47, 0x0, 0x0, 0x0, 0x8, 0x30, 0x0, + 0x0, 0x7, 0x70, 0x0, 0x4, 0x67, 0x20, 0x0, + + /* U+3064 "つ" */ + 0x0, 0x0, 0x17, 0x99, 0x81, 0x0, 0x36, 0xa8, + 0x20, 0x1, 0xb3, 0xb, 0x70, 0x0, 0x0, 0x3, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x0, 0x0, 0x2, 0xb5, 0x0, 0x0, + 0x3, 0x68, 0x81, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+3065 "づ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x39, 0x0, 0x0, 0x37, 0x89, + 0x61, 0x60, 0x14, 0x8a, 0x50, 0x0, 0x4a, 0x0, + 0x2a, 0x30, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, + 0x0, 0x0, 0x0, 0x18, 0x80, 0x0, 0x0, 0x3, + 0x68, 0x72, 0x0, 0x0, + + /* U+3066 "て" */ + 0x0, 0x0, 0x0, 0x36, 0x82, 0x35, 0x78, 0x87, + 0xbc, 0x83, 0x46, 0x30, 0x9, 0x30, 0x0, 0x0, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, + 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, + 0x0, 0x1, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x1a, + 0xd7, 0x0, + + /* U+3067 "で" */ + 0x0, 0x0, 0x0, 0x26, 0x89, 0x10, 0x3, 0x47, + 0x98, 0x7c, 0x85, 0x10, 0x8, 0x73, 0x2, 0xb2, + 0x2, 0x0, 0x0, 0x0, 0x1b, 0x10, 0x33, 0xa0, + 0x0, 0x0, 0x93, 0x0, 0x49, 0x40, 0x0, 0x0, + 0xc0, 0x0, 0x3, 0x0, 0x0, 0x1, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xde, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+3068 "と" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x40, + 0x0, 0x92, 0x3b, 0xb0, 0x0, 0x5d, 0x71, 0x0, + 0x9, 0x80, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, + 0xa0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x20, + 0x7, 0xbc, 0xcd, 0xc3, 0x0, 0x0, 0x0, 0x0, + + /* U+3069 "ど" */ + 0x0, 0x10, 0x0, 0x0, 0x20, 0x0, 0x8, 0x70, + 0x0, 0x43, 0xb0, 0x0, 0x65, 0x0, 0x3, 0x94, + 0x0, 0x5, 0x50, 0x3, 0x11, 0x0, 0x0, 0x28, + 0x19, 0xd4, 0x0, 0x0, 0x1, 0xda, 0x30, 0x0, + 0x0, 0x3, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xc1, 0x0, 0x0, 0x10, 0x0, 0x3, + 0xab, 0xbc, 0xd9, 0x0, 0x0, + + /* U+306A "な" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x82, 0x41, 0x0, + 0x0, 0x6, 0x8c, 0x96, 0x5, 0x30, 0x0, 0x8, + 0x10, 0x0, 0x2b, 0x60, 0x2, 0x80, 0x0, 0x96, + 0x56, 0x1, 0xb0, 0x0, 0x9, 0x0, 0x0, 0xb4, + 0x0, 0x1, 0x90, 0x0, 0x3, 0x0, 0x67, 0x59, + 0x0, 0x0, 0x0, 0x92, 0x4, 0xe6, 0x0, 0x0, + 0x9, 0x42, 0x94, 0xa5, 0x0, 0x0, 0x5, 0x73, + 0x0, 0x20, + + /* U+306B "に" */ + 0x26, 0x0, 0x24, 0x6a, 0x50, 0x2c, 0x0, 0x23, + 0x78, 0x20, 0x65, 0x0, 0x1, 0x30, 0x0, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x13, 0x0, 0x0, 0x0, 0xb6, 0x7, + 0x0, 0x0, 0x0, 0x7d, 0x6, 0x50, 0x0, 0x30, + 0x8, 0x0, 0x6a, 0xbc, 0x90, + + /* U+306C "ぬ" */ + 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xa, 0x20, 0x3d, 0x88, + 0x70, 0x0, 0x6, 0x48, 0x87, 0x0, 0x39, 0x0, + 0x3, 0xc2, 0x72, 0x0, 0xa, 0x10, 0x8, 0xa0, + 0x90, 0x0, 0x8, 0x30, 0x18, 0x69, 0x40, 0x0, + 0xa, 0x0, 0x53, 0xe, 0x32, 0xa9, 0xac, 0x0, + 0x46, 0x92, 0x56, 0x41, 0xa8, 0xb0, 0x6, 0x10, + 0x0, 0x78, 0x20, 0x40, + + /* U+306D "ね" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1b, 0x5, 0x98, 0xa5, 0x0, + 0x29, 0x99, 0x84, 0x0, 0xa, 0x10, 0x1, 0x8d, + 0x10, 0x0, 0x7, 0x40, 0x0, 0xc8, 0x0, 0x0, + 0x6, 0x50, 0x7, 0x48, 0x0, 0x1, 0x9, 0x20, + 0x2b, 0x8, 0x3, 0xb8, 0xae, 0x30, 0x84, 0x99, + 0x7, 0x40, 0x88, 0xa7, 0x0, 0x76, 0x1, 0x9a, + 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+306E "の" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, + 0xa9, 0x99, 0x10, 0x0, 0x69, 0x16, 0x0, 0x2c, + 0x10, 0x48, 0x0, 0x80, 0x0, 0x58, 0xb, 0x0, + 0x9, 0x0, 0x1, 0xc1, 0x90, 0x0, 0x90, 0x0, + 0xc, 0x36, 0x0, 0x19, 0x0, 0x0, 0xb2, 0x70, + 0x8, 0x30, 0x0, 0x57, 0xb, 0x15, 0x80, 0x0, + 0x2b, 0x0, 0x3a, 0x70, 0x0, 0x69, 0x10, 0x0, + 0x0, 0x2, 0x52, 0x0, 0x0, + + /* U+306F "は" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x24, 0x0, + 0x1, 0xe0, 0x0, 0x4, 0xa0, 0x0, 0xb, 0x0, + 0x0, 0x64, 0x0, 0x1, 0xc8, 0x90, 0xa, 0x0, + 0x16, 0x7c, 0x10, 0x0, 0xa0, 0x0, 0x0, 0xa0, + 0x0, 0x18, 0x0, 0x0, 0xa, 0x0, 0x3, 0x73, + 0x0, 0x0, 0xa0, 0x0, 0x3b, 0x51, 0xa8, 0x9d, + 0x30, 0x0, 0xe3, 0x55, 0x2, 0xaa, 0x70, 0x3, + 0x1, 0xb9, 0xa1, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+3070 "ば" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x5, 0x0, + 0x0, 0x92, 0x7, 0x49, 0xd, 0x0, 0x0, 0xa1, + 0x2, 0x70, 0x19, 0x0, 0x0, 0x94, 0x92, 0x0, + 0x45, 0x0, 0x68, 0xd5, 0x10, 0x0, 0x72, 0x0, + 0x0, 0x90, 0x0, 0x0, 0x90, 0x0, 0x0, 0x90, + 0x0, 0x0, 0x93, 0x0, 0x0, 0x90, 0x0, 0x0, + 0xa7, 0x5, 0x88, 0xd2, 0x0, 0x0, 0x97, 0xb, + 0x0, 0xaa, 0x70, 0x0, 0x33, 0x9, 0x9a, 0x50, + 0x80, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + + /* U+3071 "ぱ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x5, + 0x0, 0x0, 0xa1, 0x6, 0x42, 0x0, 0xd0, 0x0, + 0xa, 0x0, 0x66, 0x0, 0x28, 0x0, 0x0, 0xa5, + 0x92, 0x0, 0x5, 0x40, 0x6, 0x8c, 0x40, 0x0, + 0x0, 0x80, 0x0, 0x0, 0x90, 0x0, 0x0, 0x9, + 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x93, 0x0, + 0x0, 0x90, 0x0, 0x0, 0xa, 0x70, 0x78, 0x8d, + 0x30, 0x0, 0x0, 0x96, 0xa, 0x0, 0xb9, 0x80, + 0x0, 0x2, 0x20, 0x89, 0xa4, 0x5, 0x0, 0x0, + + /* U+3072 "ひ" */ + 0x0, 0x4, 0x60, 0x1, 0x20, 0x0, 0x1b, 0x99, + 0xb0, 0x6, 0xd0, 0x0, 0x0, 0x2a, 0x0, 0x3, + 0xd3, 0x0, 0x0, 0xa1, 0x0, 0x2, 0x89, 0x0, + 0x3, 0x70, 0x0, 0x3, 0x7a, 0x50, 0x8, 0x20, + 0x0, 0x6, 0x51, 0xa0, 0xa, 0x0, 0x0, 0xa, + 0x10, 0x0, 0x8, 0x30, 0x0, 0x2a, 0x0, 0x0, + 0x2, 0xa0, 0x1, 0xc2, 0x0, 0x0, 0x0, 0x5b, + 0xaa, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+3073 "び" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x17, + 0x30, 0x2, 0x8, 0x55, 0x5b, 0x7d, 0x60, 0xc, + 0x61, 0x60, 0x0, 0x76, 0x0, 0xa, 0x90, 0x0, + 0x2, 0xa0, 0x0, 0xa, 0x83, 0x0, 0x9, 0x20, + 0x0, 0xa, 0x1c, 0x0, 0xb, 0x0, 0x0, 0xb, + 0x5, 0x70, 0xa, 0x0, 0x0, 0x1a, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x84, 0x0, 0x0, 0x9, 0x30, + 0x5, 0xa0, 0x0, 0x0, 0x1, 0xbb, 0xb8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3074 "ぴ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x16, + 0x30, 0x2, 0x5, 0x5, 0x4b, 0x8c, 0x70, 0xa, + 0x72, 0x51, 0x0, 0x67, 0x0, 0x8, 0xa0, 0x0, + 0x1, 0xa0, 0x0, 0x7, 0x94, 0x0, 0x8, 0x30, + 0x0, 0x8, 0x2c, 0x10, 0xb, 0x0, 0x0, 0xb, + 0x4, 0x70, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x67, 0x0, 0x0, 0x9, 0x40, + 0x3, 0xc0, 0x0, 0x0, 0x1, 0xba, 0xba, 0x10, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + + /* U+3075 "ふ" */ + 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x94, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0x30, 0x0, 0x0, + 0x1, 0xa2, 0x0, 0x0, 0x0, 0x4, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x46, 0x3, 0x70, 0x21, 0x60, 0xb, 0x0, 0x78, + 0xba, 0x12, 0xb, 0x0, 0xa, 0x30, 0x5, 0x95, + 0x0, 0x0, + + /* U+3076 "ぶ" */ + 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x22, 0xa1, 0x0, 0x0, 0x5, 0xf0, + 0xb, 0x30, 0x0, 0x0, 0x57, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x50, + 0x53, 0x0, 0x10, 0x34, 0x0, 0xb0, 0xb, 0x40, + 0x3c, 0x70, 0x20, 0xb0, 0x2, 0x90, 0x4, 0x0, + 0x38, 0x30, 0x0, 0x0, + + /* U+3077 "ぷ" */ + 0x0, 0x0, 0x30, 0x0, 0x4, 0x10, 0x0, 0x0, + 0xa3, 0x2, 0x26, 0x0, 0x0, 0x7, 0xf0, 0x5, + 0x40, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x2, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x40, 0x64, 0x1, 0x3, + 0x50, 0xa, 0x0, 0xb4, 0x4c, 0x62, 0x0, 0xb0, + 0x3, 0x71, 0x40, 0x8, 0x93, 0x0, 0x0, + + /* U+3078 "へ" */ + 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x69, 0x0, 0x0, 0x0, 0x0, 0x85, 0x2, 0x80, + 0x0, 0x0, 0x1a, 0x80, 0x0, 0x57, 0x0, 0x0, + 0x13, 0x0, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3079 "べ" */ + 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, + 0x20, 0x1, 0x94, 0x80, 0x0, 0x8, 0x69, 0x0, + 0x25, 0x0, 0x0, 0x83, 0x2, 0x80, 0x0, 0x0, + 0x19, 0x60, 0x0, 0x56, 0x0, 0x0, 0x15, 0x0, + 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+307A "ぺ" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x52, 0x40, 0x0, 0x7, 0x69, 0x0, + 0x35, 0x10, 0x0, 0x75, 0x2, 0x90, 0x0, 0x0, + 0x19, 0x70, 0x0, 0x56, 0x0, 0x0, 0x14, 0x0, + 0x0, 0x8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+307B "ほ" */ + 0x3, 0x0, 0x0, 0x1, 0x10, 0xe, 0x0, 0x58, + 0xc8, 0x40, 0xa, 0x0, 0x0, 0xc0, 0x0, 0x46, + 0x0, 0x0, 0xa0, 0x30, 0x72, 0x0, 0x68, 0xda, + 0x70, 0x90, 0x0, 0x0, 0x90, 0x0, 0x91, 0x0, + 0x0, 0x90, 0x0, 0xa6, 0x0, 0x20, 0x90, 0x0, + 0x98, 0x1a, 0x68, 0xe4, 0x0, 0x34, 0x45, 0x3, + 0x98, 0x80, 0x0, 0xa, 0xbb, 0x10, 0x30, + + /* U+307C "ぼ" */ + 0x1, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0xc0, + 0x5, 0x8c, 0x84, 0x4, 0x0, 0xa, 0x0, 0x0, + 0xc0, 0x6, 0x3a, 0x3, 0x60, 0x0, 0xa, 0x0, + 0x28, 0x0, 0x63, 0x0, 0x11, 0xb7, 0x92, 0x0, + 0x7, 0x10, 0x3, 0x6c, 0x30, 0x0, 0x0, 0x91, + 0x0, 0x0, 0xa0, 0x0, 0x0, 0x9, 0x60, 0x0, + 0xa, 0x0, 0x0, 0x0, 0x7a, 0x7, 0x77, 0xd2, + 0x0, 0x0, 0x2, 0x72, 0x60, 0xb, 0x98, 0x0, + 0x0, 0x0, 0x9, 0x89, 0x40, 0x50, 0x0, 0x0, + + /* U+307D "ぽ" */ + 0x1, 0x0, 0x0, 0x1, 0x20, 0x0, 0xc, 0x0, + 0x58, 0xc8, 0x42, 0x83, 0xa, 0x0, 0x0, 0xc0, + 0x4, 0x6, 0x36, 0x0, 0x0, 0xa0, 0x0, 0x40, + 0x63, 0x0, 0x11, 0xb7, 0x92, 0x0, 0x71, 0x0, + 0x36, 0xc3, 0x0, 0x0, 0x90, 0x0, 0x0, 0xa0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0xa0, 0x0, 0x0, + 0x7a, 0x7, 0x77, 0xd2, 0x0, 0x0, 0x28, 0x26, + 0x0, 0xba, 0x70, 0x0, 0x0, 0x9, 0x89, 0x40, + 0x60, 0x0, + + /* U+307E "ま" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, + 0x0, 0x0, 0xb0, 0x21, 0x2, 0x67, 0xda, 0x81, + 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0xb5, 0x80, + 0x2, 0x79, 0xd4, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x7, 0x88, 0xb0, 0x0, 0x82, 0x3, 0xcb, 0x20, + 0x67, 0x3b, 0x22, 0xd3, 0x4, 0x62, 0x0, 0x12, + + /* U+307F "み" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, + 0x8d, 0x50, 0x0, 0x0, 0x3, 0x20, 0xc1, 0x0, + 0x0, 0x0, 0x0, 0x56, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x43, 0x0, 0x2, 0x6a, 0x92, 0x7, + 0x60, 0x7, 0x63, 0xa2, 0x7a, 0xc0, 0x3, 0x70, + 0xa1, 0x0, 0x4c, 0xb0, 0x53, 0x84, 0x0, 0x1a, + 0x5, 0x61, 0x84, 0x0, 0x19, 0x10, 0x0, 0x0, + 0x0, 0x15, 0x0, 0x0, 0x0, + + /* U+3080 "む" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x1b, 0x78, 0x0, 0x71, + 0x0, 0x37, 0xc2, 0x0, 0x1, 0xc0, 0x0, 0x3a, + 0x0, 0x0, 0x6, 0x10, 0x80, 0xc0, 0x0, 0x0, + 0x0, 0x26, 0x1d, 0x0, 0x0, 0x0, 0x1, 0xcd, + 0x80, 0x0, 0x5, 0x0, 0x0, 0x82, 0x0, 0x0, + 0x57, 0x0, 0x9, 0x40, 0x2, 0x6c, 0x50, 0x0, + 0x6, 0x99, 0x84, 0x0, 0x0, + + /* U+3081 "め" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x1d, 0x0, + 0xb, 0x10, 0x0, 0x0, 0xa1, 0x28, 0xd7, 0x30, + 0x0, 0x5, 0xb6, 0x38, 0x18, 0x80, 0x0, 0x99, + 0x7, 0x20, 0x9, 0x30, 0x73, 0x82, 0x90, 0x0, + 0x56, 0xa, 0x1, 0xd2, 0x0, 0x7, 0x40, 0x90, + 0x5a, 0x60, 0x0, 0xb0, 0xa, 0xa6, 0x0, 0x1, + 0x92, 0x0, 0x0, 0x0, 0x15, 0x60, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, + + /* U+3082 "も" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0x1a, 0x0, 0x0, 0x3, 0x46, 0x0, 0x0, + 0x3, 0xca, 0x80, 0x0, 0x0, 0xa0, 0x0, 0x0, + 0x20, 0xa0, 0x0, 0x20, 0x29, 0xd9, 0x80, 0x24, + 0x1, 0x90, 0x0, 0x25, 0x0, 0xa0, 0x0, 0x63, + 0x0, 0xa4, 0x3, 0xa0, 0x0, 0x7, 0x97, 0x0, + + /* U+3083 "ゃ" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x30, 0x38, + 0x0, 0x0, 0x0, 0xa0, 0x1a, 0x87, 0x10, 0x0, + 0x87, 0x94, 0x2, 0xc0, 0x17, 0xa9, 0x3, 0x0, + 0xc0, 0x13, 0x9, 0x12, 0x89, 0x30, 0x0, 0x2, + 0x90, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x40, 0x0, 0x0, + + /* U+3084 "や" */ + 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, 0xa3, + 0x3, 0xc3, 0x0, 0x0, 0x0, 0x74, 0x3, 0xb9, + 0x99, 0xa0, 0x0, 0xc, 0xa6, 0x0, 0x0, 0x74, + 0x3, 0xab, 0x40, 0x10, 0x0, 0x93, 0x49, 0x10, + 0xb0, 0x37, 0x57, 0xa0, 0x0, 0x0, 0x84, 0x0, + 0x32, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, + 0x0, 0x0, + + /* U+3085 "ゅ" */ + 0x0, 0x3, 0x60, 0x0, 0x65, 0x3, 0xd8, 0x40, + 0x91, 0x85, 0x72, 0x84, 0x95, 0x50, 0x72, 0x29, + 0xaa, 0x30, 0x90, 0x19, 0x97, 0x17, 0x90, 0x84, + 0x22, 0x7, 0xb9, 0x50, 0x0, 0x45, 0x0, 0x0, + + /* U+3086 "ゆ" */ + 0x0, 0x0, 0x49, 0x10, 0x0, 0x2, 0x30, 0x0, + 0x49, 0x10, 0x0, 0x39, 0x2, 0xa8, 0xc8, 0x90, + 0x6, 0x52, 0xa1, 0xa, 0x3, 0x90, 0x91, 0xa0, + 0x0, 0xa0, 0xc, 0xa, 0x55, 0x30, 0xa, 0x0, + 0xc0, 0xba, 0x6, 0x3, 0x70, 0xb, 0x9, 0xa0, + 0x18, 0x83, 0x9, 0x50, 0x26, 0x0, 0x4e, 0x9a, + 0x40, 0x0, 0x0, 0x2a, 0x20, 0x0, 0x0, 0x0, + 0x14, 0x0, 0x0, 0x0, 0x0, + + /* U+3087 "ょ" */ + 0x0, 0xa, 0x20, 0x0, 0x0, 0xb3, 0x31, 0x0, + 0xa, 0x66, 0x10, 0x0, 0xb0, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x67, 0xe9, 0x30, 0x37, 0x1c, 0x1a, + 0x0, 0xce, 0x40, 0x0, + + /* U+3088 "よ" */ + 0x0, 0xa, 0x20, 0x0, 0x0, 0xa, 0x20, 0x0, + 0x0, 0xa, 0x8a, 0x80, 0x0, 0xa, 0x0, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, + 0x39, 0x9d, 0x81, 0x0, 0xa0, 0xa, 0x3c, 0x10, + 0x7a, 0xa3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3089 "ら" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, + 0x0, 0x3, 0xc6, 0x0, 0x2, 0x93, 0x58, 0x0, + 0x9, 0x0, 0x0, 0x0, 0x18, 0x0, 0x21, 0x0, + 0x57, 0x98, 0x68, 0xb1, 0xac, 0x10, 0x0, 0x39, + 0x40, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x94, + 0x0, 0x13, 0x79, 0x50, 0x1, 0x33, 0x10, 0x0, + + /* U+308A "り" */ + 0x0, 0x0, 0x0, 0x7, 0x60, 0x68, 0x10, 0x83, + 0x93, 0x39, 0xa, 0x66, 0x0, 0xc0, 0xab, 0x0, + 0xb, 0xc, 0x70, 0x0, 0xb0, 0xd2, 0x0, 0xb, + 0x5, 0x0, 0x3, 0x70, 0x0, 0x0, 0x91, 0x0, + 0x0, 0x47, 0x0, 0x0, 0x27, 0x0, 0x0, 0x14, + 0x0, 0x0, + + /* U+308B "る" */ + 0x0, 0x0, 0x5a, 0x20, 0x0, 0x7a, 0x83, 0xb5, + 0x0, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x75, + 0x0, 0x0, 0x0, 0x66, 0x23, 0x10, 0x0, 0x6e, + 0x85, 0x5a, 0x70, 0x9b, 0x10, 0x0, 0xc, 0x7, + 0x3, 0x40, 0x0, 0xb1, 0x2, 0xa4, 0x80, 0x2b, + 0x0, 0xb, 0x46, 0x9b, 0x10, 0x0, 0x15, 0x63, + 0x0, 0x0, + + /* U+308C "れ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x46, + 0x0, 0x0, 0x0, 0xc, 0x29, 0x66, 0x50, 0x0, + 0x18, 0x8d, 0x91, 0x4, 0x60, 0x0, 0x0, 0x6c, + 0x0, 0x6, 0x40, 0x0, 0x0, 0xc9, 0x0, 0x8, + 0x10, 0x0, 0x5, 0x79, 0x0, 0xa, 0x0, 0x0, + 0xc, 0x9, 0x0, 0x9, 0x0, 0x12, 0x66, 0x9a, + 0x0, 0x9, 0x35, 0x70, 0x10, 0x68, 0x0, 0x1, + 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+308D "ろ" */ + 0x0, 0x0, 0x36, 0x90, 0x0, 0x0, 0x89, 0x43, + 0xd1, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, + 0x1, 0x90, 0x0, 0x0, 0x0, 0x1a, 0x57, 0x74, + 0x0, 0x2, 0xda, 0x40, 0x15, 0xa0, 0x2d, 0x40, + 0x0, 0x0, 0x92, 0x11, 0x0, 0x0, 0x0, 0xa1, + 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x2, 0x56, + 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+308F "わ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x30, 0x34, 0x30, 0x0, + 0x4, 0x8d, 0x79, 0x54, 0x6a, 0x10, 0x4, 0x1e, + 0x70, 0x0, 0x2, 0xa0, 0x0, 0x8e, 0x0, 0x0, + 0x0, 0xb0, 0x2, 0xba, 0x0, 0x0, 0x0, 0xa0, + 0xb, 0x2a, 0x0, 0x0, 0x2, 0x80, 0x2b, 0x7b, + 0x0, 0x0, 0x29, 0x0, 0x1, 0x2d, 0x0, 0x4, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3092 "を" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb2, + 0x0, 0x0, 0x1, 0x1, 0xa1, 0x64, 0x0, 0x2, + 0x8d, 0xa8, 0x40, 0x0, 0x0, 0x47, 0x0, 0x0, + 0x0, 0x1, 0xd8, 0x93, 0x0, 0x87, 0xd, 0x60, + 0xb, 0x7a, 0x51, 0x14, 0x0, 0x8d, 0x30, 0x0, + 0x0, 0x2a, 0x3a, 0x0, 0x0, 0x0, 0xa1, 0x16, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0xaa, 0xba, 0x0, + + /* U+3093 "ん" */ + 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x10, 0x0, 0x0, 0x0, 0x2, 0x98, 0xa5, 0x0, + 0x0, 0x0, 0x9c, 0x20, 0xa0, 0x0, 0x20, 0x2f, + 0x20, 0xa, 0x0, 0x6, 0xa, 0x70, 0x0, 0xb0, + 0x7, 0x11, 0xd0, 0x0, 0xb, 0x58, 0x50, 0x1, + 0x0, 0x0, 0x15, 0x10, 0x0, + + /* U+30A1 "ァ" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x46, 0x77, 0xc5, + 0x7, 0x62, 0x4, 0xa2, 0x0, 0x4, 0x74, 0x0, + 0x0, 0x6, 0x60, 0x0, 0x0, 0xa, 0x20, 0x0, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, + 0x4, 0x10, 0x0, 0x0, + + /* U+30A2 "ア" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, + 0x78, 0xe6, 0x1c, 0xb8, 0x62, 0x4, 0xd3, 0x1, + 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x5a, 0x50, + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, + 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x48, 0x0, + 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, 0x0, 0x0, + + /* U+30A3 "ィ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, + 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x69, 0x0, + 0x0, 0x8, 0x8a, 0x0, 0x2, 0x72, 0xa, 0x0, + 0x1, 0x0, 0x9, 0x0, 0x0, 0x0, 0x1a, 0x0, + 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+30A4 "イ" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, + 0xe0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x95, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x1, + 0xa5, 0xd0, 0x0, 0x5, 0x71, 0xb, 0x0, 0x3, + 0x10, 0x0, 0xa0, 0x0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, + + /* U+30A6 "ウ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x25, 0x80, 0x29, + 0x89, 0xa8, 0x63, 0xe3, 0xb, 0x0, 0x0, 0x4, + 0x90, 0xc, 0x0, 0x0, 0xb, 0x10, 0xd, 0x0, + 0x0, 0x66, 0x0, 0x2, 0x0, 0x2, 0xa0, 0x0, + 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x92, + 0x0, 0x0, 0x0, 0x17, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30A7 "ェ" */ + 0x0, 0x12, 0x36, 0x91, 0x0, 0x7, 0x7c, 0x40, + 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0x9, + 0x10, 0x0, 0x2, 0x45, 0xc9, 0xab, 0x50, 0x56, + 0x42, 0x0, 0x0, + + /* U+30A8 "エ" */ + 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x7, 0x89, + 0xa9, 0x97, 0x0, 0x0, 0x22, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x7, 0x78, 0x9c, 0x99, 0xaa, 0x70, 0x44, + 0x10, 0x0, 0x0, 0x0, + + /* U+30AA "オ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x92, 0x0, + 0x0, 0x0, 0x0, 0x2a, 0x68, 0xa3, 0x4, 0xb9, + 0x89, 0xf2, 0x10, 0x0, 0x0, 0x1, 0xb9, 0x10, + 0x0, 0x0, 0x0, 0xb2, 0x91, 0x0, 0x0, 0x0, + 0xa3, 0x9, 0x10, 0x0, 0x0, 0x92, 0x0, 0x91, + 0x0, 0x2, 0x60, 0x1, 0x19, 0x20, 0x0, 0x0, + 0x0, 0x9, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x0, 0x0, + + /* U+30AB "カ" */ + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x1a, 0x37, 0x90, 0x7, + 0x99, 0xba, 0x52, 0xe1, 0x2, 0x20, 0xb0, 0x2, + 0xa0, 0x0, 0x2, 0x90, 0x6, 0x60, 0x0, 0xa, + 0x10, 0xb, 0x10, 0x0, 0x65, 0x0, 0x1c, 0x0, + 0x4, 0x70, 0x9, 0xa7, 0x0, 0x14, 0x0, 0x3, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30AC "ガ" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x50, 0x0, 0x0, + 0x9, 0x30, 0x54, 0x92, 0x0, 0x0, 0xb, 0x30, + 0xb, 0x0, 0x0, 0x0, 0xc, 0x4, 0x81, 0x0, + 0x3, 0x68, 0x9d, 0x85, 0xb6, 0x0, 0x0, 0x41, + 0x56, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xb1, 0x0, + 0xb0, 0x0, 0x0, 0x3, 0x80, 0x4, 0x70, 0x0, + 0x0, 0xa, 0x0, 0x9, 0x20, 0x0, 0x0, 0x82, + 0x6, 0x6c, 0x0, 0x0, 0x4, 0x10, 0x1, 0xe5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30AD "キ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x1, 0xb6, 0x89, 0x30, 0x7, 0x97, 0xa3, 0x0, + 0x0, 0x0, 0x0, 0x54, 0x3, 0x40, 0x23, 0x57, + 0xac, 0x87, 0x51, 0x47, 0x31, 0x9, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, + + /* U+30AE "ギ" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2b, + 0x0, 0x32, 0xc0, 0x0, 0x0, 0xb0, 0x1, 0xc0, + 0x0, 0x0, 0x1b, 0x79, 0x80, 0x0, 0x6, 0x96, + 0x93, 0x0, 0x0, 0x0, 0x0, 0x4, 0x51, 0x35, + 0x0, 0x24, 0x68, 0x9c, 0x86, 0x51, 0x3, 0x63, + 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30AF "ク" */ + 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x9, 0x80, + 0x0, 0x0, 0x1, 0xd2, 0x25, 0x10, 0x0, 0x97, + 0x75, 0x9b, 0x0, 0x66, 0x0, 0xd, 0x20, 0x23, + 0x0, 0x8, 0x50, 0x0, 0x0, 0x3, 0xa0, 0x0, + 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0xb2, 0x0, + 0x0, 0x1, 0xa3, 0x0, 0x0, 0x3, 0x71, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + + /* U+30B0 "グ" */ + 0x0, 0x0, 0x31, 0x0, 0x31, 0x0, 0x0, 0xa, + 0x60, 0x36, 0xb0, 0x0, 0x2, 0xd3, 0x36, 0x82, + 0x0, 0x0, 0xa6, 0x64, 0xa9, 0x0, 0x0, 0x74, + 0x0, 0x1d, 0x10, 0x0, 0x32, 0x0, 0xa, 0x30, + 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, + 0x2, 0xb0, 0x0, 0x0, 0x0, 0x1, 0xb1, 0x0, + 0x0, 0x0, 0x2, 0xa1, 0x0, 0x0, 0x0, 0x4, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+30B1 "ケ" */ + 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, 0xe, 0x30, + 0x0, 0x0, 0x0, 0x67, 0x3, 0x69, 0xa4, 0x1, + 0xba, 0x89, 0x91, 0x0, 0x9, 0x10, 0x7, 0x70, + 0x0, 0x30, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, + 0x38, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, + 0x0, 0x6, 0x40, 0x0, 0x0, 0x0, 0x34, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30B2 "ゲ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, + 0x0, 0x0, 0x83, 0x0, 0xd, 0x20, 0x0, 0x75, + 0x70, 0x6, 0x70, 0x3, 0x66, 0x60, 0x1, 0xb9, + 0x8a, 0xa3, 0x20, 0x0, 0x91, 0x0, 0x69, 0x0, + 0x0, 0x30, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, + 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, + 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30B3 "コ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x78, 0x99, + 0xd6, 0x1, 0x53, 0x0, 0x8, 0x50, 0x0, 0x0, + 0x0, 0xa0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0xa0, 0x0, 0x0, 0x13, 0x79, 0x0, + 0x8b, 0xa8, 0x65, 0x40, + + /* U+30B4 "ゴ" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x72, 0xb0, 0x0, 0x0, 0x0, 0x1, + 0x19, 0x0, 0x2, 0x46, 0x78, 0x8c, 0x80, 0x0, + 0x1, 0x74, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0x13, 0x6a, 0x0, 0x0, 0x8, 0xb9, + 0x76, 0x54, 0x0, 0x0, + + /* U+30B5 "サ" */ + 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0xd, + 0x10, 0xd, 0x0, 0x0, 0x0, 0xa, 0x0, 0xb, + 0x0, 0x0, 0x1, 0x2c, 0x67, 0x8d, 0x9a, 0xa1, + 0x59, 0x6c, 0x20, 0xb, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0xb, 0x0, 0x47, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x10, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, + 0x0, 0x0, + + /* U+30B6 "ザ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, + 0x0, 0x0, 0x40, 0x43, 0x85, 0x0, 0x3, 0xa0, + 0xb, 0x20, 0xa1, 0x10, 0x0, 0xa, 0x0, 0xa0, + 0x0, 0x0, 0x0, 0x2, 0xc7, 0x7d, 0x89, 0xa2, + 0x0, 0x99, 0x5b, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0x1, 0xa0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x19, + 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + + /* U+30B7 "シ" */ + 0x2, 0x72, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x6, + 0x4, 0x93, 0x0, 0x0, 0x8, 0x10, 0x2, 0xc0, + 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x1a, 0x20, + 0x0, 0x0, 0x0, 0x5b, 0x10, 0x0, 0x0, 0x26, + 0xc8, 0x0, 0x0, 0x0, 0xa, 0xb2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30B8 "ジ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x48, 0x0, 0x2, 0x72, 0x0, 0x49, 0x50, + 0x0, 0x2, 0xd2, 0x0, 0x40, 0x0, 0x10, 0x1, + 0x0, 0x0, 0x6, 0x1, 0x96, 0x0, 0x0, 0x9, + 0x10, 0x0, 0xb3, 0x0, 0xa, 0x30, 0x0, 0x0, + 0x0, 0x1b, 0x30, 0x0, 0x0, 0x0, 0x5b, 0x10, + 0x0, 0x0, 0x15, 0xa7, 0x0, 0x0, 0x0, 0x6, + 0xb1, 0x0, 0x0, 0x0, 0x0, + + /* U+30B9 "ス" */ + 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x1, 0x34, + 0x89, 0xad, 0x0, 0x0, 0x39, 0x61, 0xa, 0x50, + 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x89, 0x60, + 0x0, 0x0, 0x0, 0x59, 0x4, 0x80, 0x0, 0x0, + 0x69, 0x0, 0x8, 0x80, 0x0, 0x85, 0x0, 0x0, + 0x1e, 0x20, 0x30, 0x0, 0x0, 0x0, 0x51, + + /* U+30BA "ズ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x71, 0x0, 0x0, + 0x0, 0x11, 0x57, 0x26, 0x1, 0x24, 0x79, 0xbc, + 0x8, 0x0, 0x3, 0xa5, 0x10, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x40, + 0x0, 0x0, 0x0, 0x4, 0x90, 0x58, 0x0, 0x0, + 0x0, 0x48, 0x0, 0x8, 0x80, 0x0, 0x6, 0x50, + 0x0, 0x0, 0xe2, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x30, 0x0, + + /* U+30BB "セ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x10, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x39, + 0x0, 0x0, 0xb, 0x6, 0x96, 0xe4, 0x0, 0x5, + 0xd8, 0x20, 0x84, 0x0, 0x6b, 0x5b, 0x0, 0x35, + 0x0, 0x0, 0x0, 0xb0, 0x1, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, + 0x14, 0x10, 0x0, 0x1, 0x9b, 0xba, 0x70, + + /* U+30BC "ゼ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x35, 0xb1, 0x0, 0x0, 0xd2, + 0x0, 0x0, 0x92, 0x0, 0x0, 0xb, 0x0, 0x2, + 0x81, 0x0, 0x0, 0x0, 0xb1, 0x69, 0x8e, 0x50, + 0x0, 0x0, 0x5e, 0x72, 0x8, 0x30, 0x0, 0x6, + 0xb4, 0xb0, 0x4, 0x40, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x50, 0x12, 0x52, + 0x0, 0x0, 0x0, 0x18, 0xab, 0xa8, 0x10, 0x0, + + /* U+30BD "ソ" */ + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x6a, + 0x59, 0x0, 0x0, 0x88, 0xd, 0x20, 0x0, 0xd1, + 0x5, 0x10, 0x5, 0x80, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x94, 0x0, 0x0, 0x6, 0x70, 0x0, + 0x0, 0x67, 0x0, 0x0, 0x6, 0x40, 0x0, 0x0, + 0x10, 0x0, 0x0, 0x0, + + /* U+30BF "タ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, + 0x0, 0x0, 0x0, 0x0, 0xd9, 0x8b, 0xe0, 0x0, + 0x8, 0x64, 0x18, 0x80, 0x0, 0x7b, 0x10, 0x1d, + 0x0, 0x7, 0x60, 0xb5, 0x95, 0x0, 0x21, 0x0, + 0x1d, 0xa0, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, + 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, 0x4a, 0x10, + 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x0, + + /* U+30C0 "ダ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x92, 0x0, 0x0, 0x9, + 0x20, 0x1, 0x95, 0x50, 0x0, 0x2, 0xe7, 0x8c, + 0xa1, 0x40, 0x0, 0x0, 0xb5, 0x40, 0xb3, 0x0, + 0x0, 0x0, 0x98, 0x0, 0x49, 0x0, 0x0, 0x0, + 0x83, 0x2c, 0x2c, 0x10, 0x0, 0x0, 0x20, 0x0, + 0x4d, 0x50, 0x0, 0x0, 0x0, 0x0, 0x5, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x17, 0x40, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30C1 "チ" */ + 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, + 0x48, 0xb6, 0x20, 0x0, 0x0, 0x14, 0x21, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x57, 0x50, + 0x7, 0xba, 0x99, 0xc5, 0x44, 0x40, 0x0, 0x0, + 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x9, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+30C3 "ッ" */ + 0x0, 0x20, 0x0, 0x0, 0x41, 0x47, 0x3, 0xd0, + 0x1c, 0x8, 0x6, 0x80, 0x4, 0x0, 0xc, 0x10, + 0x0, 0x0, 0x65, 0x0, 0x0, 0x3, 0x80, 0x0, + 0x0, 0x38, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, + + /* U+30C4 "ツ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, + 0x0, 0x70, 0x16, 0x1, 0xd0, 0x1, 0xe1, 0xa, + 0x40, 0x90, 0x7, 0x60, 0x5, 0x50, 0x0, 0x1b, + 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, + 0x4, 0x80, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, + 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x26, 0x0, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + + /* U+30C6 "テ" */ + 0x0, 0x0, 0x2, 0x61, 0x0, 0x0, 0x59, 0x86, + 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, + 0x56, 0x87, 0x8a, 0xb1, 0x36, 0x31, 0x79, 0x0, + 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, + 0x0, 0x38, 0x0, 0x0, 0x0, 0x2, 0x80, 0x0, + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + + /* U+30C7 "デ" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, + 0x1, 0x41, 0x25, 0x93, 0x0, 0x49, 0x87, 0x63, + 0x8, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x12, 0x46, 0x78, 0x9a, 0xb2, 0x0, 0x26, 0x42, + 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, 0x19, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30C8 "ト" */ + 0x18, 0x0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xb, 0x10, 0x0, 0xa, 0x59, 0x20, 0xa, + 0x1, 0xd5, 0xa, 0x0, 0x14, 0xa, 0x0, 0x0, + 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, 0x3, 0x0, + 0x0, + + /* U+30C9 "ド" */ + 0x81, 0x0, 0x3, 0x0, 0xb2, 0x1, 0x53, 0xb0, + 0xa0, 0x0, 0x67, 0x30, 0xa3, 0x0, 0x0, 0x0, + 0xa2, 0x94, 0x0, 0x0, 0xa0, 0xb, 0x70, 0x0, + 0xa0, 0x0, 0x50, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x0, 0x0, + + /* U+30CA "ナ" */ + 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, + 0x23, 0x6d, 0x99, 0xb5, 0x7a, 0x75, 0x58, 0x0, + 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, + 0x91, 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, + 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x44, 0x0, + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + + /* U+30CB "ニ" */ + 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x8, + 0xa8, 0x87, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0x88, + 0x88, 0x88, 0x9a, 0x90, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+30CD "ネ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x96, + 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x0, 0x37, 0xc7, 0x0, 0x1, 0xa9, 0x52, 0xc1, + 0x0, 0x0, 0x0, 0x1b, 0x10, 0x0, 0x0, 0x2, + 0xc6, 0x23, 0x0, 0x0, 0x49, 0x2a, 0x6, 0xa0, + 0x6, 0x50, 0x9, 0x0, 0x84, 0x20, 0x0, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x0, 0x0, + + /* U+30CE "ノ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, + 0x1, 0x92, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, + 0x0, 0x0, + + /* U+30CF "ハ" */ + 0x0, 0x0, 0x60, 0x1, 0x0, 0x0, 0x0, 0x1, + 0xf2, 0x1, 0x70, 0x0, 0x0, 0x9, 0x60, 0x0, + 0x49, 0x0, 0x0, 0x3a, 0x0, 0x0, 0xa, 0x60, + 0x1, 0xa0, 0x0, 0x0, 0x1, 0xe0, 0x7, 0x0, + 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30D0 "バ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x22, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x48, 0x51, 0x0, 0x0, 0x50, 0x1, 0x3, 0x0, + 0x0, 0x1, 0xe1, 0x0, 0x70, 0x0, 0x0, 0x8, + 0x50, 0x0, 0x29, 0x0, 0x0, 0x29, 0x0, 0x0, + 0x9, 0x60, 0x0, 0x90, 0x0, 0x0, 0x1, 0xe0, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30D1 "パ" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x41, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x16, 0x40, 0x0, 0x0, 0x40, 0x1, 0x20, 0x0, + 0x0, 0x0, 0xd3, 0x0, 0x71, 0x0, 0x0, 0x5, + 0x80, 0x0, 0xb, 0x0, 0x0, 0x1a, 0x0, 0x0, + 0x6, 0x90, 0x0, 0x91, 0x0, 0x0, 0x0, 0xe2, + 0x6, 0x10, 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30D2 "ヒ" */ + 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x1, 0x0, 0xb0, 0x15, 0xae, 0x40, + 0xb5, 0x53, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x96, 0x10, 0x13, 0x50, 0x6, 0x99, 0x98, 0x60, + + /* U+30D3 "ビ" */ + 0x0, 0x0, 0x0, 0x10, 0x2, 0xc0, 0x0, 0x2, + 0xa4, 0xb, 0x0, 0x0, 0x79, 0x30, 0xb0, 0x0, + 0x28, 0x20, 0xb, 0x3, 0x9a, 0x61, 0x0, 0xc6, + 0x40, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0xc, 0x30, 0x1, 0x44, + 0x0, 0x28, 0x99, 0x98, 0x40, + + /* U+30D4 "ピ" */ + 0x0, 0x0, 0x0, 0x6, 0x90, 0xa, 0x0, 0x0, + 0x5, 0x32, 0xc, 0x0, 0x0, 0x1, 0x20, 0xb, + 0x0, 0x1, 0xa1, 0x0, 0xb, 0x3, 0x8a, 0x61, + 0x0, 0xb, 0x54, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x52, 0x12, 0x46, 0x0, 0x0, 0x68, 0x98, + 0x75, 0x0, + + /* U+30D5 "フ" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x14, 0x46, 0x89, + 0x99, 0xf4, 0x7, 0x63, 0x10, 0x3, 0xc0, 0x0, + 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x67, + 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, + 0x2b, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, + 0x0, 0x57, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, + 0x0, 0x0, + + /* U+30D6 "ブ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x2b, 0x0, 0x0, 0x2, + 0x57, 0xa7, 0x25, 0x0, 0x7b, 0xa8, 0x63, 0x17, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30D7 "プ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x35, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x5, 0x15, 0x0, 0x0, 0x1, + 0x36, 0x95, 0x4, 0x0, 0x8b, 0x99, 0x75, 0x28, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30D9 "ベ" */ + 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, + 0x10, 0x4, 0x48, 0x50, 0x0, 0x9, 0xb5, 0x0, + 0x90, 0x0, 0x0, 0xa4, 0x9, 0x50, 0x0, 0x0, + 0x2b, 0x50, 0x0, 0xb4, 0x0, 0x0, 0x35, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, + + /* U+30DA "ペ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x26, 0x40, 0x0, 0x0, 0x0, 0x30, 0x34, + 0x60, 0x0, 0x0, 0xb, 0x98, 0x1, 0x0, 0x0, + 0x0, 0xb2, 0x7, 0x70, 0x0, 0x0, 0x3c, 0x30, + 0x0, 0x96, 0x0, 0x0, 0x13, 0x0, 0x0, 0xa, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+30DB "ホ" */ + 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x23, 0x30, 0x5b, + 0x99, 0xd8, 0x77, 0x70, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x0, 0x20, 0xb0, 0x4, 0x0, 0x5, 0x20, + 0xb0, 0x3, 0x80, 0x2c, 0x0, 0xb0, 0x0, 0xc2, + 0x52, 0x6, 0xd0, 0x0, 0x31, 0x0, 0x2, 0xc0, + 0x0, 0x0, + + /* U+30DC "ボ" */ + 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x9, + 0x10, 0x72, 0xb0, 0x0, 0x0, 0xb1, 0x2, 0x60, + 0x0, 0x0, 0xa, 0x1, 0x32, 0x0, 0x4a, 0x98, + 0xd8, 0x87, 0x70, 0x0, 0x0, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x20, 0xa0, 0x4, 0x0, 0x0, 0x52, + 0xa, 0x0, 0x47, 0x0, 0x1c, 0x0, 0xa0, 0x0, + 0xc2, 0x6, 0x30, 0x6c, 0x10, 0x4, 0x10, 0x0, + 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30DD "ポ" */ + 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x91, + 0x50, 0x50, 0x0, 0x0, 0xb1, 0x16, 0x20, 0x0, + 0x0, 0xa0, 0x23, 0x30, 0x5b, 0x98, 0xd8, 0x76, + 0x60, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x20, + 0xa0, 0x4, 0x0, 0x5, 0x20, 0xa0, 0x3, 0x80, + 0x2c, 0x0, 0xa0, 0x0, 0xc2, 0x52, 0x6, 0xc1, + 0x0, 0x31, 0x0, 0x2, 0xc0, 0x0, 0x0, + + /* U+30DE "マ" */ + 0x0, 0x0, 0x0, 0x24, 0x61, 0x7b, 0x98, 0x88, + 0x64, 0xb9, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, + 0x4, 0x0, 0x65, 0x0, 0x0, 0x2, 0x95, 0x20, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, + + /* U+30DF "ミ" */ + 0x4, 0x20, 0x0, 0x0, 0x6b, 0x70, 0x0, 0x0, + 0xa5, 0x1, 0x0, 0x0, 0x4, 0x96, 0x0, 0x0, + 0x7, 0xc0, 0x0, 0x0, 0x20, 0x35, 0x10, 0x0, + 0x1, 0x8b, 0x40, 0x0, 0x2, 0xc6, 0x0, 0x0, + 0x2, + + /* U+30E0 "ム" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x88, + 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, + 0x3, 0x90, 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, + 0x0, 0x0, 0x28, 0x0, 0x40, 0x0, 0x0, 0x91, + 0x0, 0x2a, 0x0, 0x3, 0x70, 0x15, 0x79, 0x90, + 0x1d, 0xaa, 0x83, 0x0, 0xe1, 0x18, 0x20, 0x0, + 0x0, 0x40, + + /* U+30E1 "メ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, + 0x2, 0x20, 0x2b, 0x0, 0x0, 0x0, 0x39, 0xc2, + 0x0, 0x0, 0x0, 0x7, 0xd8, 0x0, 0x0, 0x0, + 0x39, 0xa, 0x70, 0x0, 0x2, 0xb0, 0x0, 0x40, + 0x0, 0x39, 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+30E2 "モ" */ + 0x0, 0x0, 0x1, 0x47, 0x81, 0x0, 0x7, 0x98, + 0xc4, 0x21, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb2, 0x46, 0x71, 0x6, 0xa9, + 0x8c, 0x65, 0x43, 0x10, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x1, 0x20, 0x0, 0x0, 0x2, 0x9a, + 0xa6, 0x0, + + /* U+30E3 "ャ" */ + 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x3, 0x90, + 0x5, 0x70, 0x0, 0x4, 0xd8, 0x74, 0xc1, 0x6, + 0x94, 0x82, 0x6, 0x10, 0x0, 0x0, 0x37, 0x2, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x20, 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, + + /* U+30E4 "ヤ" */ + 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x5b, + 0x70, 0x0, 0x9, 0x98, 0x84, 0x97, 0x1a, 0xa8, + 0x68, 0x0, 0x19, 0x0, 0x0, 0x0, 0xa0, 0x7, + 0x0, 0x0, 0x0, 0x9, 0x10, 0x20, 0x0, 0x0, + 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x20, 0x0, 0x0, + + /* U+30E5 "ュ" */ + 0x0, 0x12, 0x35, 0x30, 0x0, 0x0, 0x67, 0x46, + 0xb0, 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x7, 0x88, 0x9d, 0xab, + 0x90, 0x0, 0x20, 0x0, 0x0, 0x0, + + /* U+30E7 "ョ" */ + 0x0, 0x0, 0x1, 0x10, 0x3, 0xba, 0x9a, 0xd0, + 0x0, 0x0, 0x2, 0xa0, 0x1, 0xa9, 0x8a, 0x70, + 0x0, 0x0, 0x6, 0x40, 0x0, 0x0, 0x8, 0x20, + 0x8, 0xa9, 0x9a, 0x30, + + /* U+30E8 "ヨ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0x89, 0xaa, + 0xd5, 0x0, 0x21, 0x0, 0x7, 0x70, 0x0, 0x0, + 0x0, 0x93, 0x0, 0x0, 0x0, 0xb, 0x0, 0x2b, + 0xb9, 0x98, 0xc0, 0x0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x0, 0x2, 0x80, 0xb, 0xba, 0x99, 0xb8, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30E9 "ラ" */ + 0x0, 0x0, 0x1, 0x35, 0x0, 0x0, 0x7a, 0x98, + 0x65, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x35, 0x69, 0x9a, 0xe0, 0x6, 0x74, 0x20, 0x3, + 0xb0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, + 0x0, 0x85, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x18, 0x30, + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + + /* U+30EA "リ" */ + 0x5, 0x0, 0xa, 0x0, 0xc1, 0x0, 0xe0, 0xb, + 0x0, 0xc, 0x0, 0xb0, 0x0, 0xc0, 0xb, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0xb0, 0x3, 0x0, 0x29, + 0x0, 0x0, 0x9, 0x30, 0x0, 0x3, 0x90, 0x0, + 0x3, 0x80, 0x0, 0x1, 0x30, 0x0, 0x0, + + /* U+30EB "ル" */ + 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x20, + 0xe, 0x10, 0x0, 0x0, 0x0, 0xd2, 0xc, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0xb, 0x0, 0x0, 0x50, + 0x0, 0xc0, 0xb, 0x0, 0x6, 0x30, 0x0, 0xc0, + 0xb, 0x0, 0x76, 0x0, 0x2, 0x80, 0xb, 0x1a, + 0x60, 0x0, 0x9, 0x10, 0xd, 0xd3, 0x0, 0x0, + 0x32, 0x0, 0x3, 0x10, 0x0, 0x0, + + /* U+30EC "レ" */ + 0x24, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x62, 0xb, 0x0, 0x59, 0x10, + 0xb, 0x3b, 0x60, 0x0, 0x1f, 0xb1, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, + + /* U+30ED "ロ" */ + 0x0, 0x0, 0x24, 0x69, 0x20, 0xf9, 0x97, 0x53, + 0xa9, 0xc, 0x0, 0x0, 0xb, 0x20, 0xb0, 0x0, + 0x0, 0xb0, 0xa, 0x10, 0x0, 0x19, 0x0, 0x91, + 0x0, 0x6, 0x60, 0xa, 0xaa, 0x99, 0x96, 0x0, + 0x40, 0x0, 0x0, 0x0, + + /* U+30EF "ワ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x56, 0x79, + 0xab, 0xe2, 0xd, 0x43, 0x20, 0x0, 0xd2, 0xc, + 0x0, 0x0, 0x5, 0x80, 0xd, 0x0, 0x0, 0xc, + 0x10, 0x9, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, + 0x2, 0xa0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, + 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x27, 0x0, + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + + /* U+30F3 "ン" */ + 0x15, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc4, 0x0, + 0x0, 0x2, 0x0, 0x3a, 0x0, 0x0, 0x53, 0x0, + 0x0, 0x0, 0x6, 0x60, 0x0, 0x0, 0x0, 0x66, + 0x0, 0x0, 0x0, 0x9, 0x50, 0x0, 0x0, 0x3, + 0xb3, 0x0, 0x0, 0x6, 0xa9, 0x10, 0x0, 0x0, + 0x6, 0x30, 0x0, 0x0, 0x0, + + /* U+30F6 "ヶ" */ + 0x0, 0x82, 0x0, 0x0, 0x0, 0xc1, 0x2, 0x50, + 0x8, 0xa9, 0xd7, 0x51, 0x35, 0x0, 0xc2, 0x0, + 0x0, 0x2, 0x90, 0x0, 0x0, 0x9, 0x10, 0x0, + 0x0, 0x45, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + + /* U+30FC "ー" */ + 0x2, 0x10, 0x0, 0x1, 0x24, 0x69, 0x40, 0x8, + 0xff, 0xcb, 0xa9, 0x87, 0x77, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E00 "一" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x30, 0x6, + 0x55, 0x55, 0x55, 0x55, 0x58, 0x70, + + /* U+4E03 "七" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0xd3, 0x55, + 0x51, 0x0, 0x0, 0x3, 0x55, 0xd1, 0x0, 0x0, + 0x0, 0x7, 0x51, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x50, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x5b, + 0xbb, 0xbb, 0xa2, + + /* U+4E07 "万" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x10, 0x75, + 0x55, 0xa7, 0x55, 0x55, 0x85, 0x0, 0x0, 0xc, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, + 0x1, 0x0, 0x0, 0x0, 0xf, 0x55, 0x55, 0xb8, + 0x0, 0x0, 0x2, 0xc0, 0x0, 0x9, 0x40, 0x0, + 0x0, 0x68, 0x0, 0x0, 0xa3, 0x0, 0x0, 0xb, + 0x30, 0x0, 0xb, 0x20, 0x0, 0x2, 0xa0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0xa2, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x73, 0x0, 0x5, 0x78, 0xc0, 0x0, + 0x43, 0x0, 0x0, 0x6, 0xb2, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E08 "丈" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x30, 0x1, 0x0, 0x5, 0x65, 0x55, + 0x5b, 0x75, 0x5a, 0xa0, 0x0, 0x1, 0x0, 0xa, + 0x20, 0x0, 0x0, 0x0, 0x5, 0x0, 0xb, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x60, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x73, 0xd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xbe, 0x70, 0x0, 0x0, 0x0, 0x0, 0x88, + 0x1, 0xbe, 0x95, 0x30, 0x0, 0x58, 0x30, 0x0, + 0x3, 0xaf, 0x50, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E09 "三" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x65, 0x55, 0x55, 0x55, 0x6d, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x90, 0x0, 0x0, 0x26, 0x55, 0x55, 0x55, 0x52, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x16, 0x55, + 0x55, 0x55, 0x55, 0x58, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+4E0A "上" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, + 0xa8, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x3, 0x80, 0x7, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x51, + + /* U+4E0B "下" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x30, 0x65, + 0x55, 0x5d, 0x55, 0x55, 0x54, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd6, 0x50, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x5, 0xd7, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x2, 0xe2, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, 0x0, 0x0, 0x0, + + /* U+4E0D "不" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x55, 0x55, 0x56, 0x55, 0x5b, 0x80, 0x0, 0x0, + 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0xa2, 0x25, + 0x0, 0x0, 0x0, 0x1, 0xc2, 0xa2, 0x2, 0xa1, + 0x0, 0x0, 0xb, 0x20, 0xa2, 0x0, 0x3d, 0x30, + 0x0, 0x92, 0x0, 0xa2, 0x0, 0x6, 0xc0, 0x16, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x40, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E13 "专" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x90, 0x0, 0x70, 0x0, 0x0, 0x55, 0x59, + 0x95, 0x55, 0x52, 0x0, 0x0, 0x0, 0x8, 0x30, + 0x0, 0x0, 0x0, 0x15, 0x55, 0x5d, 0x65, 0x55, + 0x58, 0xb0, 0x1, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, 0x57, 0x55, 0x57, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, + 0x16, 0x30, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6c, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+4E14 "且" */ + 0x0, 0x0, 0x95, 0x55, 0x55, 0xb0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd5, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0xd5, 0x55, 0x55, 0xc0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xc0, 0x80, 0x6, 0x55, 0x75, + 0x55, 0x55, 0x76, 0x74, + + /* U+4E16 "世" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc1, 0x0, 0xd1, 0x0, 0x0, 0x2c, + 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x0, 0x1a, 0x0, + 0xc0, 0x0, 0xc0, 0x0, 0x0, 0x1a, 0x0, 0xc0, + 0x0, 0xc0, 0x91, 0x6, 0x6c, 0x55, 0xd5, 0x55, + 0xd5, 0x52, 0x0, 0x1a, 0x0, 0xc0, 0x0, 0xc0, + 0x0, 0x0, 0x1a, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0x0, 0x1a, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x0, + 0x1a, 0x0, 0xc5, 0x55, 0xc0, 0x0, 0x0, 0x1a, + 0x0, 0x90, 0x0, 0x70, 0x0, 0x0, 0x1a, 0x0, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x3b, 0x55, 0x55, + 0x55, 0x56, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E21 "両" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, + 0x55, 0x55, 0x57, 0x55, 0x59, 0x90, 0x0, 0x0, + 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x1, 0x0, 0x0, 0xc5, 0x55, 0x6b, + 0x55, 0x5c, 0x30, 0x0, 0xb0, 0x0, 0x29, 0x1, + 0xa, 0x10, 0x0, 0xb0, 0xb1, 0x29, 0xd, 0xa, + 0x10, 0x0, 0xb0, 0xb0, 0x29, 0xc, 0xa, 0x10, + 0x0, 0xb0, 0xb0, 0x29, 0xc, 0xa, 0x10, 0x0, + 0xb0, 0xc5, 0x6a, 0x5d, 0xa, 0x10, 0x0, 0xb0, + 0x20, 0x0, 0x5, 0xa, 0x10, 0x0, 0xb0, 0x0, + 0x0, 0x3, 0x2c, 0x0, 0x0, 0xa0, 0x0, 0x0, + 0x2, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E26 "並" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x1, 0x81, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x3d, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x42, 0x7, 0x0, 0x2, 0x65, 0x5d, 0x55, + 0xd5, 0x55, 0x20, 0x0, 0x20, 0xc, 0x0, 0xc0, + 0x4, 0x10, 0x0, 0x70, 0xc, 0x0, 0xc0, 0xd, + 0x50, 0x0, 0x56, 0xc, 0x0, 0xc0, 0x67, 0x0, + 0x0, 0x1d, 0xc, 0x0, 0xc0, 0xa0, 0x0, 0x0, + 0xd, 0xc, 0x0, 0xc6, 0x10, 0x0, 0x0, 0x3, + 0xc, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x3, 0x40, 0x6, 0x55, 0x57, 0x55, + 0x75, 0x57, 0x80, + + /* U+4E2D "中" */ + 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x50, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, + 0x8, 0x55, 0x5b, 0x75, 0x55, 0xa2, 0xc0, 0x0, + 0xa3, 0x0, 0xc, 0xc, 0x0, 0xa, 0x30, 0x0, + 0xc0, 0xc0, 0x0, 0xa3, 0x0, 0xc, 0xd, 0x55, + 0x5b, 0x75, 0x55, 0xd0, 0xb0, 0x0, 0xa3, 0x0, + 0xa, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0xa, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, 0x0, 0x0, + + /* U+4E3B "主" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x15, 0x0, 0x18, 0x0, 0x3, 0x65, 0x55, 0xc7, + 0x55, 0x55, 0x10, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa3, 0x11, 0x90, 0x0, + 0x0, 0x46, 0x55, 0xc6, 0x44, 0x41, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x5, 0x10, 0x26, 0x55, 0x55, 0x75, + 0x55, 0x58, 0x60, + + /* U+4E45 "久" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89, + 0x55, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x4, + 0xb0, 0x0, 0x0, 0x0, 0x7, 0x20, 0xa, 0x50, + 0x0, 0x0, 0x0, 0x36, 0x0, 0x1d, 0x50, 0x0, + 0x0, 0x1, 0x50, 0x0, 0x94, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xb0, 0x45, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x10, 0xb, 0x10, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x4, 0xc1, 0x0, 0x0, 0x28, 0x10, + 0x0, 0x0, 0x8d, 0x50, 0x5, 0x60, 0x0, 0x0, + 0x0, 0x8, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E4B "之" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3, 0x55, 0x55, + 0x65, 0x59, 0x50, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x3d, 0x40, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1a, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x70, 0x87, + 0x31, 0x0, 0x2, 0x31, 0x4, 0x0, 0x4, 0xad, + 0xef, 0xff, 0x70, + + /* U+4E4E "乎" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, + 0x0, 0x0, 0x14, 0x7b, 0xd8, 0x0, 0x0, 0x45, + 0x67, 0x8b, 0x20, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x2a, 0x0, 0xa5, 0x0, 0x0, 0x4, 0x90, 0x2a, + 0x1, 0xa0, 0x0, 0x0, 0x0, 0xc2, 0x2a, 0x7, + 0x10, 0x0, 0x0, 0x0, 0x20, 0x2a, 0x2, 0x1, + 0x80, 0x6, 0x55, 0x55, 0x6c, 0x55, 0x55, 0x52, + 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, + 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+4E4F "乏" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x48, 0xd5, 0x0, 0x15, 0x56, 0x78, + 0x86, 0x53, 0x20, 0x0, 0x0, 0x3, 0x91, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, + 0x0, 0x45, 0x55, 0x56, 0x55, 0xb0, 0x0, 0x1, + 0x0, 0x0, 0x2, 0xb5, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x8, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x58, 0x10, 0x0, 0x0, + 0x0, 0x2, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xb0, 0x68, 0x41, 0x0, 0x1, 0x21, 0x21, 0x0, + 0x17, 0xbd, 0xef, 0xf8, 0x0, + + /* U+4E57 "乗" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0x46, 0x8b, 0xe8, 0x0, 0x0, 0x44, + 0x33, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x43, 0x0, 0x0, 0x65, 0x85, 0xb7, + 0x59, 0x54, 0x0, 0x0, 0x0, 0xc0, 0x92, 0xc, + 0x4, 0x0, 0x6, 0x55, 0xd5, 0xb7, 0x5d, 0x56, + 0x30, 0x0, 0x0, 0xc0, 0x92, 0xc, 0x12, 0x0, + 0x0, 0x65, 0x79, 0xe9, 0x57, 0x66, 0x0, 0x0, + 0x0, 0x1b, 0x94, 0x70, 0x0, 0x0, 0x0, 0x1, + 0xa1, 0x92, 0x58, 0x0, 0x0, 0x0, 0x38, 0x10, + 0x92, 0x6, 0xc5, 0x0, 0x5, 0x40, 0x0, 0x93, + 0x0, 0x4d, 0x80, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+4E5D "九" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x10, 0x0, 0x0, 0x1, 0x65, 0x5d, 0x55, + 0xb5, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0xa1, + 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0xa1, 0x0, + 0x0, 0x0, 0x0, 0x64, 0x0, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0xa0, 0x0, 0xa1, 0x0, 0x0, 0x0, + 0x2, 0x90, 0x0, 0xa1, 0x0, 0x10, 0x0, 0x9, + 0x10, 0x0, 0xa2, 0x0, 0x60, 0x0, 0x63, 0x0, + 0x0, 0x92, 0x0, 0x90, 0x4, 0x30, 0x0, 0x0, + 0x6c, 0xaa, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E5F "也" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x92, 0x0, 0x3a, 0x0, 0x0, 0xc, 0x0, 0x95, + 0x66, 0x69, 0x0, 0x0, 0xc, 0x16, 0xc5, 0x0, + 0x39, 0x0, 0x2, 0x5d, 0x40, 0x92, 0x0, 0x47, + 0x0, 0x4, 0xc, 0x0, 0x92, 0x0, 0x66, 0x0, + 0x0, 0xc, 0x0, 0x93, 0x57, 0xd2, 0x0, 0x0, + 0xc, 0x0, 0x93, 0x7, 0x60, 0x20, 0x0, 0xc, + 0x0, 0x71, 0x0, 0x0, 0x60, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0xa0, 0x0, 0xa, 0xba, 0xaa, + 0xaa, 0xac, 0xd1, + + /* U+4E86 "了" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, + 0x55, 0x57, 0xc0, 0x0, 0x0, 0x0, 0x3, 0xb5, + 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, + 0x29, 0x30, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x2, 0x15, 0xa0, + 0x0, 0x0, 0x0, 0x17, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, 0x0, 0x0, + + /* U+4E88 "予" */ + 0x0, 0x55, 0x55, 0x55, 0x5b, 0x10, 0x0, 0x1, + 0x0, 0x0, 0x1a, 0x82, 0x0, 0x0, 0x0, 0x54, + 0x27, 0x10, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x15, + 0x4, 0x65, 0x55, 0x5e, 0x55, 0x5b, 0xc0, 0x0, + 0x0, 0x0, 0xd0, 0x3, 0x70, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x17, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, 0x0, + + /* U+4E89 "争" */ + 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x99, 0x0, 0x50, 0x0, 0x0, 0x0, 0x5, + 0xa5, 0x57, 0xd2, 0x0, 0x0, 0x0, 0x28, 0x0, + 0x8, 0x0, 0x0, 0x0, 0x2, 0x66, 0x55, 0x96, + 0x55, 0xd1, 0x0, 0x2, 0x0, 0x0, 0xa1, 0x0, + 0xb0, 0x0, 0x15, 0x55, 0x55, 0xc6, 0x55, 0xc8, + 0xa0, 0x1, 0x0, 0x0, 0xa1, 0x0, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0xa1, 0x0, 0xb0, 0x0, 0x0, + 0x55, 0x55, 0xc6, 0x55, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0x0, + + /* U+4E8B "事" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0x0, 0x4, 0x20, 0x5, 0x55, + 0x55, 0x6b, 0x55, 0x57, 0x60, 0x0, 0x7, 0x55, + 0x6b, 0x55, 0x92, 0x0, 0x0, 0xb, 0x0, 0x29, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, 0x6b, 0x55, + 0xd0, 0x0, 0x0, 0x3, 0x0, 0x29, 0x0, 0x50, + 0x0, 0x0, 0x36, 0x55, 0x6b, 0x55, 0xd2, 0x0, + 0x16, 0x55, 0x55, 0x6b, 0x55, 0xd7, 0xb0, 0x0, + 0x0, 0x0, 0x29, 0x0, 0xc0, 0x0, 0x0, 0x36, + 0x55, 0x6b, 0x55, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x39, 0x0, 0x20, 0x0, 0x0, 0x0, 0x17, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+4E8C "二" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x46, 0x55, 0x55, 0x55, 0x98, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x50, 0x6, + 0x55, 0x55, 0x55, 0x55, 0x56, 0x60, + + /* U+4E94 "五" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, + 0x65, 0x55, 0xc6, 0x55, 0x55, 0x30, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa0, + 0x0, 0x30, 0x0, 0x0, 0x36, 0x58, 0xa5, 0x55, + 0xd0, 0x0, 0x0, 0x0, 0x6, 0x50, 0x1, 0xa0, + 0x0, 0x0, 0x0, 0x9, 0x30, 0x2, 0xa0, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x2, 0x90, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x3, 0x80, 0x70, 0x5, 0x55, 0x56, + 0x55, 0x55, 0x66, 0x72, + + /* U+4E9B "些" */ + 0x0, 0x0, 0x92, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0xb0, 0x2, 0x0, 0x0, 0xc0, + 0xb0, 0x50, 0xb0, 0x3c, 0x40, 0x0, 0xb0, 0xb5, + 0x52, 0xb5, 0x50, 0x0, 0x0, 0xb0, 0xb0, 0x0, + 0xb0, 0x0, 0x50, 0x0, 0xb0, 0xb0, 0x1, 0xb0, + 0x0, 0x90, 0x5, 0xd9, 0xa6, 0x41, 0x9a, 0x99, + 0xc2, 0x8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x15, 0x55, 0x55, 0x56, 0xd3, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x60, 0x6, 0x55, 0x55, + 0x55, 0x55, 0x56, 0x60, + + /* U+4EA1 "亡" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x4, 0x80, 0x16, 0x5d, 0x55, 0x55, + 0x55, 0x55, 0x51, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xe, 0x55, + 0x55, 0x55, 0x7d, 0x20, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4EA4 "交" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x37, 0x0, 0x6, 0x50, 0x6, 0x55, 0x65, + 0x55, 0x65, 0x55, 0x50, 0x0, 0x0, 0xc4, 0x0, + 0x18, 0x30, 0x0, 0x0, 0xa, 0x40, 0x0, 0x10, + 0xb9, 0x0, 0x1, 0x81, 0x31, 0x0, 0x88, 0xc, + 0x0, 0x3, 0x0, 0x6, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x26, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69, + 0x13, 0xc7, 0x20, 0x0, 0x1, 0x57, 0x20, 0x0, + 0x6, 0xcf, 0xc1, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+4EA6 "亦" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x58, 0x0, 0x8, 0x20, 0x65, 0x55, 0xd5, 0x5d, + 0x55, 0x54, 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, + 0x0, 0x3, 0xa0, 0xc0, 0xc, 0x12, 0x0, 0x0, + 0x76, 0xc, 0x0, 0xc0, 0x82, 0x0, 0xb, 0x0, + 0xb0, 0xc, 0x1, 0xd1, 0x3, 0x50, 0x39, 0x0, + 0xc0, 0x8, 0x90, 0x60, 0x9, 0x20, 0xc, 0x0, + 0x27, 0x0, 0x2, 0x90, 0x0, 0xc0, 0x0, 0x0, + 0x1, 0x90, 0x4, 0x4e, 0x0, 0x0, 0x3, 0x50, + 0x0, 0x1a, 0x90, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4EAC "京" */ + 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x5, 0x55, + 0x55, 0x96, 0x55, 0x5a, 0xc0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x55, 0x55, + 0x55, 0xa0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, + 0xb0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, 0xa0, + 0x0, 0x0, 0xd, 0x55, 0x55, 0x56, 0xb0, 0x0, + 0x0, 0x8, 0x0, 0xd0, 0x1, 0x30, 0x0, 0x0, + 0x3, 0xa0, 0xd0, 0x6, 0x0, 0x0, 0x0, 0x1b, + 0x20, 0xd0, 0x1, 0xb2, 0x0, 0x1, 0x91, 0x0, + 0xd0, 0x0, 0x3e, 0x0, 0x15, 0x0, 0x4c, 0xd0, + 0x0, 0x7, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, + + /* U+4EBA "人" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x76, 0x30, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x31, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x5, + 0x80, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x57, 0x0, + 0x0, 0x0, 0xbd, 0x61, 0x5, 0x40, 0x0, 0x0, + 0x0, 0x9, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4EC0 "什" */ + 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x4, 0xd0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x9, + 0x50, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, + 0xc0, 0x0, 0x10, 0x0, 0xac, 0x36, 0x55, 0xd5, + 0x58, 0x90, 0x5, 0x3c, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x15, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x10, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+4ECA "今" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0x0, 0x90, 0x0, 0x0, 0x0, 0x1, 0xc2, 0x0, + 0x3b, 0x10, 0x0, 0x0, 0x1a, 0x11, 0x92, 0x3, + 0xd7, 0x10, 0x2, 0x81, 0x0, 0x3b, 0x0, 0x1b, + 0xd2, 0x14, 0x0, 0x0, 0x1, 0x0, 0x20, 0x0, + 0x0, 0x16, 0x55, 0x55, 0x58, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, + 0x0, 0x0, + + /* U+4ECB "介" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x86, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, + 0x2b, 0x10, 0x0, 0x0, 0x8, 0x42, 0x0, 0x44, + 0xd8, 0x20, 0x1, 0x71, 0x2c, 0x0, 0xa4, 0x1a, + 0x80, 0x3, 0x0, 0x29, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x39, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x56, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x6, 0x60, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+4ECD "仍" */ + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xb0, 0x0, 0x0, 0x13, 0x0, 0x0, 0xa, + 0x25, 0x6d, 0x55, 0x99, 0x0, 0x0, 0x1a, 0x0, + 0xc, 0x0, 0x84, 0x0, 0x0, 0x7c, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0x0, 0x8c, 0x0, 0x1a, 0x0, + 0xc0, 0x40, 0x6, 0x1c, 0x0, 0x29, 0x2, 0x85, + 0xd1, 0x12, 0xc, 0x0, 0x47, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x74, 0x0, 0x1, 0xb0, 0x0, + 0xc, 0x0, 0xb0, 0x0, 0x3, 0x90, 0x0, 0xc, + 0x3, 0x80, 0x0, 0x6, 0x70, 0x0, 0xc, 0x9, + 0x0, 0x4, 0x3c, 0x30, 0x0, 0xd, 0x62, 0x0, + 0x1, 0xc9, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+4ED5 "仕" */ + 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x3, 0xe1, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x8, + 0x70, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0xd0, 0x0, 0x20, 0x0, 0xbe, 0x26, 0x55, 0xd5, + 0x57, 0x90, 0x4, 0x4d, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x6, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0xd0, 0x7, 0x10, 0x0, 0xe, 0x6, 0x55, + 0x55, 0x55, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4ED6 "他" */ + 0x0, 0x1, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x6, 0xd0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xa, + 0x40, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x1c, 0x0, + 0x90, 0xb0, 0x2, 0x0, 0x0, 0x7a, 0x0, 0xc0, + 0xb5, 0x5d, 0x10, 0x0, 0xac, 0x14, 0xd5, 0xc0, + 0xb, 0x0, 0x5, 0x3c, 0x21, 0xb0, 0xb0, 0xc, + 0x0, 0x6, 0xc, 0x0, 0xb0, 0xb0, 0xc, 0x0, + 0x0, 0xc, 0x0, 0xb0, 0xb1, 0x7d, 0x0, 0x0, + 0xc, 0x0, 0xb0, 0xb0, 0x23, 0x0, 0x0, 0xc, + 0x0, 0xb0, 0x70, 0x0, 0x50, 0x0, 0xc, 0x0, + 0xb0, 0x0, 0x0, 0x90, 0x0, 0xc, 0x0, 0xa9, + 0x99, 0x99, 0xd3, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4ED8 "付" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x1, 0xe1, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x6, + 0x70, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xd0, 0x10, 0x0, 0x3c, 0x5, 0x55, + 0x55, 0xe5, 0xa1, 0x0, 0xad, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x4, 0x5c, 0x0, 0x40, 0x0, 0xd0, + 0x0, 0x6, 0xc, 0x0, 0x67, 0x0, 0xd0, 0x0, + 0x10, 0xc, 0x0, 0xe, 0x0, 0xd0, 0x0, 0x0, + 0xc, 0x0, 0x2, 0x0, 0xd0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x5c, 0xd0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, + 0x10, 0x0, + + /* U+4EE3 "代" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xf2, 0x4, 0x90, 0x40, 0x0, 0x0, 0x6, + 0x80, 0x3, 0x90, 0x3d, 0x20, 0x0, 0xc, 0x10, + 0x2, 0xa0, 0x5, 0x40, 0x0, 0x4d, 0x10, 0x1, + 0xb0, 0x3, 0x70, 0x0, 0xad, 0x15, 0x55, 0xd5, + 0x54, 0x30, 0x6, 0x3c, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x15, 0xc, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x10, 0xc, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xa, 0x60, 0x32, 0x0, 0xc, 0x0, + 0x0, 0x1, 0xd6, 0x81, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x1b, 0xf2, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x31, + + /* U+4EE4 "令" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xb4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x10, 0x90, 0x0, 0x0, 0x0, 0x0, 0xb5, 0x20, + 0x2a, 0x0, 0x0, 0x0, 0x9, 0x50, 0x87, 0x4, + 0xd3, 0x0, 0x0, 0x72, 0x0, 0xd, 0x0, 0x3d, + 0xc1, 0x14, 0x5, 0x55, 0x56, 0x57, 0xb0, 0x10, + 0x0, 0x1, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, + 0x47, 0x23, 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xac, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+4EE5 "以" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, + 0x0, 0x0, 0x3c, 0x0, 0xd, 0x10, 0x70, 0x0, + 0x3b, 0x0, 0xd, 0x0, 0x3d, 0x0, 0x3a, 0x0, + 0xd, 0x0, 0xc, 0x40, 0x3a, 0x0, 0xd, 0x0, + 0x2, 0x0, 0x49, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x58, 0x0, 0xd, 0x0, 0x4, 0x0, 0x85, 0x0, + 0xd, 0x3, 0x80, 0x0, 0xd1, 0x0, 0xd, 0x99, + 0x0, 0x5, 0xa8, 0x0, 0xe, 0x80, 0x0, 0x3c, + 0x3, 0xd1, 0x1, 0x0, 0x7, 0x80, 0x0, 0x97, + 0x0, 0x35, 0x61, 0x0, 0x0, 0x12, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+4EEE "仮" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd0, 0x10, 0x4, 0x8d, 0x70, 0x0, 0x8, + 0x50, 0xc4, 0x42, 0x0, 0x0, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x0, 0xc5, + 0x55, 0x59, 0x30, 0x0, 0x9b, 0x0, 0xb4, 0x0, + 0xc, 0x10, 0x6, 0x1b, 0x0, 0xc4, 0x10, 0x1a, + 0x0, 0x2, 0xb, 0x0, 0xb0, 0x60, 0x74, 0x0, + 0x0, 0xb, 0x3, 0x80, 0x80, 0xb0, 0x0, 0x0, + 0xb, 0x6, 0x40, 0x3b, 0x70, 0x0, 0x0, 0xb, + 0x9, 0x0, 0x2e, 0x50, 0x0, 0x0, 0xb, 0x16, + 0x4, 0x91, 0xb7, 0x0, 0x0, 0xb, 0x62, 0x64, + 0x0, 0x8, 0xd2, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+4EF6 "件" */ + 0x0, 0x0, 0x30, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x2, 0xf1, 0x0, 0xe, 0x0, 0x0, 0x0, 0x8, + 0x70, 0xa5, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, + 0xd0, 0xc, 0x0, 0x20, 0x0, 0x6e, 0x1, 0xb5, + 0x5d, 0x56, 0x70, 0x0, 0x9c, 0x6, 0x20, 0xc, + 0x0, 0x0, 0x6, 0x1c, 0x5, 0x0, 0xc, 0x0, + 0x0, 0x13, 0xc, 0x5, 0x55, 0x5d, 0x55, 0xa4, + 0x0, 0xc, 0x1, 0x0, 0xc, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+4EFB "任" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x6, + 0x70, 0x35, 0x89, 0xa9, 0x10, 0x0, 0xc, 0x2, + 0x10, 0xb1, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0xad, 0x0, 0x0, 0xb1, + 0x0, 0x0, 0x5, 0x3c, 0x0, 0x0, 0xb1, 0x3, + 0x40, 0x15, 0xc, 0x26, 0x55, 0xc5, 0x55, 0x40, + 0x0, 0xc, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xb1, 0x0, 0x30, 0x0, 0xd, 0x36, 0x55, + 0x75, 0x56, 0x70, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4EFD "份" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x6, 0x7, 0x0, 0x0, 0x0, 0x4, + 0x90, 0x2c, 0x6, 0x10, 0x0, 0x0, 0xb, 0x10, + 0x84, 0x1, 0x70, 0x0, 0x0, 0x3a, 0x0, 0xa0, + 0x0, 0x93, 0x0, 0x0, 0x9d, 0x7, 0x20, 0x0, + 0x1d, 0x60, 0x5, 0x2c, 0x34, 0x55, 0x55, 0x84, + 0xa3, 0x13, 0xc, 0x20, 0xd, 0x0, 0xa1, 0x0, + 0x0, 0xc, 0x0, 0x1b, 0x0, 0xb0, 0x0, 0x0, + 0xc, 0x0, 0x38, 0x0, 0xb0, 0x0, 0x0, 0xc, + 0x0, 0x92, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x2, + 0x80, 0x22, 0xc0, 0x0, 0x0, 0xc, 0x36, 0x0, + 0x3d, 0x60, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F01 "企" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd4, 0x30, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x30, 0x73, 0x0, 0x0, 0x0, 0x0, 0x95, 0x2, + 0xa, 0x50, 0x0, 0x0, 0x8, 0x40, 0xe, 0x10, + 0xab, 0x41, 0x1, 0x72, 0x0, 0xc, 0x0, 0x6, + 0x91, 0x3, 0x0, 0xe1, 0xc, 0x0, 0x60, 0x0, + 0x0, 0x0, 0xc0, 0xd, 0x55, 0x61, 0x0, 0x0, + 0x0, 0xc0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0xc, 0x0, 0x2, 0x40, 0x5, 0x55, 0x75, 0x57, + 0x55, 0x56, 0x70, + + /* U+4F0A "伊" */ + 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x90, 0x0, 0x0, 0x4, 0x0, 0x0, 0xc, + 0x16, 0x5c, 0x55, 0x5d, 0x0, 0x0, 0x39, 0x0, + 0xc, 0x0, 0xc, 0x0, 0x0, 0x9b, 0x0, 0xc, + 0x0, 0xc, 0x20, 0x2, 0x6c, 0x46, 0x5d, 0x55, + 0x5d, 0x74, 0x6, 0xc, 0x0, 0xc, 0x0, 0xc, + 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0xc, 0x0, + 0x0, 0xc, 0x7, 0x5d, 0x55, 0x5c, 0x0, 0x0, + 0xc, 0x0, 0x2a, 0x0, 0x5, 0x0, 0x0, 0xc, + 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0xc, 0x3, + 0x80, 0x0, 0x0, 0x0, 0x0, 0xc, 0x35, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F11 "休" */ + 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x2, 0xd1, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x8, + 0x50, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xc0, 0x3, 0x40, 0x0, 0x6b, 0x36, 0x5a, + 0xf7, 0x55, 0x50, 0x0, 0xac, 0x0, 0xc, 0xd5, + 0x0, 0x0, 0x6, 0x2c, 0x0, 0x2a, 0xc3, 0x40, + 0x0, 0x13, 0xc, 0x0, 0xa2, 0xc0, 0xa0, 0x0, + 0x0, 0xc, 0x3, 0x80, 0xc0, 0x67, 0x0, 0x0, + 0xc, 0x8, 0x0, 0xc0, 0xc, 0x70, 0x0, 0xc, + 0x51, 0x0, 0xc0, 0x2, 0x92, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+4F1A "会" */ + 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x47, 0x10, 0x0, 0x0, 0x0, 0x0, 0x68, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x3, 0x90, 0x0, + 0x1c, 0x70, 0x0, 0x0, 0x3a, 0x55, 0x55, 0x79, + 0x9f, 0xa2, 0x4, 0x40, 0x10, 0x0, 0x0, 0x2, + 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, + 0x2, 0x65, 0x58, 0x95, 0x55, 0x58, 0x30, 0x0, + 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x64, 0x0, 0x0, 0x0, 0x6, 0x50, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x5e, 0xca, 0x87, + 0x65, 0xc5, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x21, 0x0, + + /* U+4F1D "伝" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x0, 0x0, 0x1, 0x0, 0x0, 0x5, + 0xa0, 0x55, 0x55, 0x68, 0x0, 0x0, 0xc, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xad, 0x15, 0x55, 0x55, + 0x56, 0xc1, 0x7, 0x1c, 0x1, 0x0, 0xd2, 0x0, + 0x0, 0x11, 0xc, 0x0, 0x3, 0xa0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x9, 0x20, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x29, 0x0, 0x52, 0x0, 0x0, 0xc, + 0x0, 0x90, 0x0, 0xc, 0x10, 0x0, 0xc, 0x8, + 0xa7, 0x86, 0x5a, 0x80, 0x0, 0xd, 0x4, 0x62, + 0x0, 0x3, 0x50, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F38 "伸" */ + 0x0, 0x1, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, + 0x8, 0x70, 0x0, 0x2b, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x2a, 0x0, 0x20, 0x0, 0x39, 0xb, + 0x55, 0x6b, 0x55, 0xe0, 0x0, 0xab, 0xc, 0x0, + 0x2a, 0x0, 0xc0, 0x2, 0x9a, 0xc, 0x0, 0x2a, + 0x0, 0xc0, 0x8, 0x1a, 0xc, 0x55, 0x6b, 0x55, + 0xc0, 0x11, 0x1a, 0xc, 0x0, 0x2a, 0x0, 0xc0, + 0x0, 0x1a, 0xc, 0x55, 0x6b, 0x55, 0xc0, 0x0, + 0x1a, 0x8, 0x0, 0x2a, 0x0, 0x80, 0x0, 0x1a, + 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x1a, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+4F3C "似" */ + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x70, 0x0, 0x0, 0x8, 0x20, 0x0, 0xc, + 0x3, 0x1, 0x0, 0xc, 0x10, 0x0, 0x48, 0xb, + 0x14, 0x60, 0xc, 0x0, 0x0, 0xab, 0xb, 0x0, + 0xe1, 0xd, 0x0, 0x2, 0x7b, 0xb, 0x0, 0x60, + 0xd, 0x0, 0x7, 0xb, 0xb, 0x0, 0x0, 0xd, + 0x0, 0x10, 0xb, 0xb, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0xb, 0xb, 0x0, 0x50, 0x77, 0x0, 0x0, + 0xb, 0xb, 0x59, 0x10, 0xd6, 0x0, 0x0, 0xb, + 0xc, 0x90, 0xa, 0x63, 0xa0, 0x0, 0xb, 0x2, + 0x0, 0x96, 0x0, 0x97, 0x0, 0x1b, 0x0, 0x56, + 0x10, 0x0, 0x23, 0x0, 0x1, 0x3, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F46 "但" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x31, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2c, + 0xc, 0x55, 0x55, 0x5e, 0x0, 0x0, 0x84, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x1, 0xe1, 0xc, 0x0, + 0x0, 0xc, 0x0, 0x7, 0xd0, 0xc, 0x55, 0x55, + 0x5c, 0x0, 0x25, 0xc0, 0xc, 0x0, 0x0, 0xc, + 0x0, 0x30, 0xc0, 0xc, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xc0, 0xc, 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, + 0x7, 0x0, 0x0, 0x3, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x40, 0x0, 0xc2, 0x65, 0x55, + 0x55, 0x55, 0x71, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F4D "位" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xc0, 0x3, 0x80, 0x0, 0x0, 0x0, 0x9, + 0x50, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x20, 0x4, 0x50, 0x0, 0x5a, 0x16, 0x55, + 0x55, 0x55, 0x40, 0x0, 0xac, 0x0, 0x20, 0x0, + 0x87, 0x0, 0x4, 0x4b, 0x0, 0x80, 0x0, 0xa3, + 0x0, 0x5, 0xb, 0x0, 0x74, 0x0, 0xb0, 0x0, + 0x0, 0xb, 0x0, 0x3b, 0x1, 0x80, 0x0, 0x0, + 0xb, 0x0, 0x1d, 0x6, 0x30, 0x0, 0x0, 0xb, + 0x0, 0x4, 0x8, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x6, 0x0, 0x70, 0x0, 0xb, 0x36, 0x55, + 0x55, 0x55, 0x62, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F4E "低" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd3, 0x0, 0x0, 0x3b, 0x30, 0x0, 0x49, 0x4, + 0x46, 0xc7, 0x41, 0x0, 0xa, 0x10, 0xc0, 0xb, + 0x0, 0x0, 0x2, 0xf2, 0xb, 0x0, 0xb0, 0x0, + 0x0, 0x9b, 0x10, 0xb0, 0xb, 0x0, 0x20, 0x43, + 0xa1, 0xc, 0x55, 0xb6, 0x57, 0x41, 0xa, 0x10, + 0xb0, 0x6, 0x40, 0x0, 0x0, 0xa1, 0xb, 0x0, + 0x38, 0x0, 0x0, 0xa, 0x10, 0xb0, 0x0, 0xc0, + 0x1, 0x0, 0xa1, 0xb, 0x36, 0x6, 0x90, 0x70, + 0xa, 0x10, 0xf7, 0x53, 0xa, 0x99, 0x0, 0xa1, + 0x3, 0x0, 0xc0, 0x7, 0xa0, 0x1, 0x0, 0x0, + 0x1, 0x0, 0x0, + + /* U+4F4F "住" */ + 0x0, 0x0, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x7, 0x70, 0x0, 0x0, 0x0, 0x5, + 0x90, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xb, 0x15, + 0x55, 0x75, 0x59, 0x90, 0x0, 0x4c, 0x1, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x9c, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x6, 0x1c, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x12, 0xc, 0x3, 0x55, 0xd5, 0x6c, 0x10, + 0x0, 0xc, 0x1, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x0, 0x30, 0x0, 0xd, 0x36, 0x55, + 0x85, 0x57, 0x80, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F53 "体" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xb0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x9, + 0x40, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xc0, 0x2, 0x50, 0x0, 0x69, 0x16, 0x5b, + 0xf8, 0x55, 0x50, 0x0, 0xac, 0x0, 0xc, 0xc5, + 0x0, 0x0, 0x6, 0x1b, 0x0, 0x57, 0xc1, 0x60, + 0x0, 0x13, 0xb, 0x0, 0xa0, 0xc0, 0x91, 0x0, + 0x0, 0xb, 0x7, 0x30, 0xc0, 0x2c, 0x0, 0x0, + 0xb, 0x25, 0x0, 0xc0, 0x59, 0xc2, 0x0, 0xb, + 0x30, 0x75, 0xd5, 0x53, 0x30, 0x0, 0xb, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+4F55 "何" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x8, + 0x46, 0x55, 0x55, 0x59, 0x93, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x5c, 0x2, 0x0, + 0x30, 0xb, 0x0, 0x0, 0xab, 0xb, 0x55, 0xb4, + 0xb, 0x0, 0x6, 0x2b, 0xb, 0x0, 0xa2, 0xb, + 0x0, 0x2, 0xb, 0xb, 0x0, 0xa2, 0xb, 0x0, + 0x0, 0xb, 0xb, 0x55, 0xb2, 0xb, 0x0, 0x0, + 0xb, 0xa, 0x0, 0x40, 0xb, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x17, 0xd9, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x20, 0x0, + + /* U+4F59 "余" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x46, 0x10, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, + 0xb, 0x60, 0x0, 0x0, 0x68, 0x65, 0x65, 0x7a, + 0xae, 0x80, 0x16, 0x10, 0x0, 0xb1, 0x0, 0x4, + 0x30, 0x0, 0x55, 0x55, 0xc5, 0x55, 0xc3, 0x0, + 0x0, 0x10, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xb0, 0xb1, 0x45, 0x0, 0x0, 0x0, 0x2c, + 0x10, 0xb1, 0x5, 0xc2, 0x0, 0x2, 0x90, 0x0, + 0xb0, 0x0, 0x5e, 0x0, 0x15, 0x0, 0x3b, 0xe0, + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+4F5C "作" */ + 0x0, 0x0, 0x30, 0x3, 0x10, 0x0, 0x0, 0x0, + 0x2, 0xd1, 0xa, 0x50, 0x0, 0x0, 0x0, 0x7, + 0x50, 0x1b, 0x0, 0x0, 0x20, 0x0, 0xb, 0x0, + 0x87, 0x95, 0x55, 0x91, 0x0, 0x5b, 0x1, 0x90, + 0xc0, 0x0, 0x0, 0x0, 0xac, 0x7, 0x0, 0xc0, + 0x0, 0x0, 0x6, 0x2c, 0x21, 0x0, 0xd5, 0x5a, + 0x70, 0x3, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xd5, 0x56, 0xb0, 0x0, 0xc, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+4F60 "你" */ + 0x0, 0x0, 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe1, 0xe, 0x20, 0x0, 0x0, 0x0, 0x8, + 0x60, 0x58, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0xb6, 0x55, 0x58, 0x90, 0x0, 0x7c, 0x2, 0x70, + 0x30, 0x9, 0x30, 0x1, 0x9c, 0x7, 0x0, 0x94, + 0x2, 0x0, 0x7, 0x1c, 0x11, 0x51, 0x93, 0x10, + 0x0, 0x12, 0xc, 0x0, 0xd1, 0x93, 0x53, 0x0, + 0x0, 0xc, 0x3, 0x70, 0x93, 0xb, 0x20, 0x0, + 0xc, 0x8, 0x0, 0x93, 0x4, 0xc0, 0x0, 0xc, + 0x24, 0x0, 0x93, 0x0, 0xc0, 0x0, 0xc, 0x20, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, 0x0, 0x19, + 0xe1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+4F7F "使" */ + 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x3, 0xe1, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x8, + 0x60, 0x0, 0xa1, 0x1, 0x60, 0x0, 0xc, 0x5, + 0x55, 0xc5, 0x55, 0x50, 0x0, 0x6b, 0x1, 0x65, + 0xc5, 0x58, 0x10, 0x0, 0x8b, 0x2, 0x90, 0xa0, + 0xb, 0x0, 0x5, 0x1b, 0x1, 0x90, 0xa0, 0xb, + 0x0, 0x12, 0xb, 0x2, 0xb5, 0xc5, 0x5c, 0x0, + 0x0, 0xb, 0x0, 0x30, 0xb0, 0x2, 0x0, 0x0, + 0xb, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x2a, 0x7a, 0x30, 0x0, 0x0, 0xb, 0x5, 0x60, + 0x2, 0xae, 0xa1, 0x0, 0x2, 0x30, 0x0, 0x0, + 0x0, 0x10, + + /* U+4F86 "來" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x3, 0x0, 0x1, 0x65, 0x55, + 0x6c, 0x55, 0x59, 0x50, 0x0, 0x3, 0xb0, 0x2a, + 0x1, 0xd0, 0x0, 0x0, 0x8, 0x60, 0x2a, 0x4, + 0x80, 0x0, 0x0, 0x1a, 0x76, 0x3b, 0x9, 0x5a, + 0x10, 0x0, 0x81, 0x9, 0xbd, 0x64, 0x4, 0x50, + 0x1, 0x0, 0x6, 0xaa, 0x81, 0x0, 0x0, 0x0, + 0x0, 0x49, 0x2a, 0xb, 0x20, 0x0, 0x0, 0x5, + 0x80, 0x2a, 0x1, 0xd6, 0x0, 0x0, 0x64, 0x0, + 0x2a, 0x0, 0x1b, 0xe3, 0x4, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x12, 0x0, + 0x0, 0x0, + + /* U+4F8B "例" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xd0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x76, 0x57, + 0x76, 0x80, 0xb, 0x0, 0xb, 0x0, 0x83, 0x0, + 0x82, 0xb0, 0x2, 0xe1, 0xb, 0x3, 0x1b, 0xb, + 0x0, 0x8d, 0x1, 0xa5, 0xb5, 0xb0, 0xb0, 0x25, + 0xb0, 0x73, 0xc, 0xb, 0xb, 0x2, 0xb, 0x7, + 0x93, 0xa0, 0xb0, 0xb0, 0x0, 0xb2, 0x4, 0x94, + 0xb, 0xb, 0x0, 0xb, 0x0, 0x1b, 0x0, 0xb0, + 0xb0, 0x0, 0xb0, 0x8, 0x30, 0x1, 0xb, 0x0, + 0xb, 0x4, 0x50, 0x0, 0x0, 0xb0, 0x0, 0xb4, + 0x30, 0x0, 0x3, 0x9e, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x20, + + /* U+4F9B "供" */ + 0x0, 0x0, 0x20, 0x2, 0x0, 0x10, 0x0, 0x0, + 0x1, 0xe1, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x7, + 0x70, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, + 0xb, 0x0, 0xb0, 0x40, 0x0, 0x6b, 0x6, 0x5c, + 0x55, 0xc5, 0x60, 0x0, 0xaa, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0x6, 0x1a, 0x0, 0xb, 0x0, 0xb0, + 0x0, 0x2, 0xa, 0x0, 0xb, 0x0, 0xb0, 0x30, + 0x0, 0xa, 0x56, 0x57, 0x55, 0x75, 0x84, 0x0, + 0xa, 0x0, 0x8, 0x1, 0x10, 0x0, 0x0, 0xa, + 0x0, 0x79, 0x0, 0x85, 0x0, 0x0, 0xa, 0x3, + 0x90, 0x0, 0xa, 0x80, 0x0, 0x1b, 0x27, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x3, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F9D "依" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x80, 0x3, 0x80, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0xc1, 0x2, 0x30, 0x0, 0x29, 0x26, + 0x56, 0xe5, 0x55, 0x50, 0x0, 0x9c, 0x0, 0x7, + 0x90, 0x0, 0x0, 0x1, 0x7b, 0x0, 0x1a, 0x50, + 0x6, 0x0, 0x6, 0xb, 0x0, 0xa1, 0x51, 0x5b, + 0x20, 0x2, 0xb, 0x6, 0xe1, 0x19, 0x50, 0x0, + 0x0, 0xb, 0x44, 0xb0, 0xa, 0x0, 0x0, 0x0, + 0xb, 0x20, 0xb0, 0x6, 0x70, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x41, 0xc4, 0x0, 0x0, 0xb, 0x0, + 0xb9, 0x20, 0x2e, 0x70, 0x0, 0xc, 0x0, 0xa2, + 0x0, 0x3, 0x60, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FA1 "価" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x8, + 0x56, 0x58, 0x58, 0x55, 0xa2, 0x0, 0xb, 0x0, + 0xa, 0x9, 0x10, 0x0, 0x0, 0x6c, 0x0, 0xa, + 0x9, 0x10, 0x0, 0x0, 0x9a, 0xa, 0x5c, 0x5b, + 0x55, 0xd0, 0x5, 0x1a, 0xb, 0xa, 0x9, 0x10, + 0xb0, 0x2, 0xa, 0xb, 0xa, 0x9, 0x10, 0xb0, + 0x0, 0xa, 0xb, 0xa, 0x9, 0x10, 0xb0, 0x0, + 0xa, 0xb, 0xa, 0x9, 0x10, 0xb0, 0x0, 0xa, + 0xb, 0xa, 0x9, 0x10, 0xb0, 0x0, 0xa, 0xb, + 0x58, 0x57, 0x55, 0xb0, 0x0, 0xb, 0xb, 0x0, + 0x0, 0x0, 0xa0, 0x0, 0x1, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FBF "便" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x40, 0x0, 0x0, 0x3, 0x40, 0x0, 0x1c, + 0x36, 0x55, 0xc5, 0x55, 0x40, 0x0, 0x74, 0x6, + 0x55, 0xc5, 0x58, 0x10, 0x0, 0xd2, 0xb, 0x0, + 0xb0, 0xb, 0x0, 0x5, 0xc2, 0xc, 0x55, 0xc5, + 0x5b, 0x0, 0x6, 0x92, 0xb, 0x0, 0xb0, 0xb, + 0x0, 0x30, 0x92, 0xb, 0x0, 0xb0, 0xb, 0x0, + 0x0, 0x92, 0xb, 0x55, 0xc5, 0x59, 0x0, 0x0, + 0x92, 0x1, 0x20, 0xa0, 0x0, 0x0, 0x0, 0x92, + 0x0, 0x67, 0x60, 0x0, 0x0, 0x0, 0x92, 0x0, + 0x1e, 0x80, 0x0, 0x0, 0x0, 0x92, 0x5, 0x91, + 0x5c, 0xb8, 0x70, 0x0, 0x32, 0x51, 0x0, 0x0, + 0x25, 0x30, + + /* U+4FC2 "係" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe2, 0x0, 0x2, 0x5a, 0x80, 0x0, 0x7, + 0x73, 0x56, 0xb8, 0x53, 0x30, 0x0, 0xd, 0x0, + 0x3, 0xb4, 0x14, 0x0, 0x0, 0x5b, 0x0, 0x66, + 0x0, 0xc8, 0x0, 0x0, 0xbb, 0x5, 0xa8, 0x7c, + 0x31, 0x0, 0x6, 0x3b, 0x0, 0x4, 0x70, 0x6, + 0x20, 0x3, 0xb, 0x2, 0xca, 0x77, 0x55, 0xd0, + 0x0, 0xb, 0x0, 0x41, 0xb, 0x0, 0x90, 0x0, + 0xb, 0x0, 0x2a, 0xb, 0x51, 0x0, 0x0, 0xb, + 0x0, 0xb3, 0xb, 0xa, 0x40, 0x0, 0xb, 0x7, + 0x30, 0xb, 0x1, 0xe0, 0x0, 0xc, 0x22, 0x6, + 0xc9, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+4FDD "保" */ + 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xd0, 0x85, 0x55, 0x5b, 0x10, 0x0, 0x8, + 0x50, 0xc0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, + 0xc0, 0x0, 0xb, 0x0, 0x0, 0x6b, 0x0, 0xc0, + 0x0, 0xb, 0x0, 0x0, 0xaa, 0x0, 0xd5, 0xb5, + 0x5a, 0x0, 0x6, 0x1a, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x1, 0xa, 0x45, 0x56, 0xd6, 0x55, 0xa2, + 0x0, 0xa, 0x0, 0x9, 0xd4, 0x20, 0x0, 0x0, + 0xa, 0x0, 0x38, 0xb0, 0x80, 0x0, 0x0, 0xa, + 0x0, 0x90, 0xb0, 0x39, 0x0, 0x0, 0xa, 0x7, + 0x10, 0xb0, 0x6, 0xd2, 0x0, 0x1b, 0x40, 0x0, + 0xb0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+4FE1 "信" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x8, + 0x50, 0x0, 0x75, 0x1, 0x50, 0x0, 0xb, 0x17, + 0x55, 0x55, 0x55, 0x50, 0x0, 0x6a, 0x0, 0x0, + 0x0, 0x6, 0x0, 0x0, 0xba, 0x1, 0x65, 0x55, + 0x55, 0x10, 0x6, 0x49, 0x0, 0x0, 0x0, 0x6, + 0x0, 0x13, 0x19, 0x1, 0x65, 0x55, 0x55, 0x20, + 0x0, 0x19, 0x0, 0x75, 0x55, 0x58, 0x20, 0x0, + 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x19, + 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x19, 0x0, + 0xc5, 0x55, 0x5c, 0x0, 0x0, 0x19, 0x0, 0xa0, + 0x0, 0xa, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FEE "修" */ + 0x0, 0x3, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x9, 0x60, 0x0, 0x0, 0x0, 0x57, + 0x0, 0xd, 0x55, 0x59, 0x10, 0x0, 0xa1, 0x40, + 0x65, 0x30, 0x69, 0x0, 0x2, 0xf2, 0xb2, 0x40, + 0x78, 0x80, 0x0, 0x8, 0xa1, 0xa0, 0x0, 0x8b, + 0x60, 0x0, 0x34, 0x91, 0xa0, 0x47, 0x14, 0x6c, + 0x90, 0x10, 0x91, 0xa3, 0x10, 0x69, 0x20, 0x0, + 0x0, 0x91, 0xa0, 0x17, 0x30, 0xa6, 0x0, 0x0, + 0x91, 0xa1, 0x20, 0x2a, 0x60, 0x20, 0x0, 0x91, + 0xa0, 0x17, 0x70, 0x2c, 0x90, 0x0, 0x91, 0x1, + 0x30, 0x28, 0xa2, 0x0, 0x0, 0x91, 0x1, 0x57, + 0x71, 0x0, 0x0, 0x0, 0x20, 0x13, 0x0, 0x0, + 0x0, 0x0, + + /* U+500B "個" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc7, 0x30, 0x0, 0x0, 0x30, 0x0, 0x2c, 0xc, + 0x55, 0x65, 0x5c, 0x20, 0x8, 0x40, 0xb0, 0xa, + 0x0, 0xb0, 0x0, 0xe2, 0xb, 0x35, 0xa6, 0x6b, + 0x0, 0x6e, 0x0, 0xb0, 0x8, 0x0, 0xb0, 0x16, + 0xb0, 0xb, 0x1, 0x82, 0xb, 0x2, 0xb, 0x0, + 0xb0, 0xc5, 0xc1, 0xb0, 0x0, 0xb0, 0xb, 0xa, + 0xa, 0xb, 0x0, 0xb, 0x0, 0xb0, 0xc5, 0xc0, + 0xb0, 0x0, 0xb0, 0xb, 0x8, 0x6, 0xb, 0x0, + 0xb, 0x0, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0xb0, + 0xb, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5011 "們" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x41, 0x4, 0x3, 0x0, 0x40, 0x0, 0x4a, + 0x2b, 0x5c, 0x1d, 0x56, 0xb0, 0x0, 0x93, 0x2a, + 0xb, 0xb, 0x2, 0x90, 0x0, 0xe1, 0x2b, 0x5c, + 0xc, 0x56, 0x90, 0x5, 0xf0, 0x2a, 0xb, 0xb, + 0x2, 0x90, 0x8, 0xb0, 0x2b, 0x5a, 0xa, 0x56, + 0x90, 0x31, 0xb0, 0x2a, 0x0, 0x0, 0x2, 0x90, + 0x0, 0xb0, 0x2a, 0x0, 0x0, 0x2, 0x90, 0x0, + 0xb0, 0x2a, 0x0, 0x0, 0x2, 0x90, 0x0, 0xb0, + 0x2a, 0x0, 0x0, 0x2, 0x90, 0x0, 0xb0, 0x2a, + 0x0, 0x0, 0x2, 0x90, 0x0, 0xb0, 0x2a, 0x0, + 0x0, 0x6c, 0x80, 0x0, 0x30, 0x11, 0x0, 0x0, + 0x3, 0x0, + + /* U+5019 "候" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x10, 0x45, 0x55, 0xa0, 0x0, 0x0, 0x58, + 0x0, 0x0, 0x3, 0x90, 0x0, 0x0, 0xa2, 0x82, + 0x0, 0x5, 0x61, 0x30, 0x0, 0xe1, 0xa2, 0x7a, + 0x55, 0x55, 0x40, 0x6, 0xe0, 0xa0, 0x57, 0x0, + 0x11, 0x0, 0x16, 0xb0, 0xa0, 0x85, 0xa6, 0x65, + 0x0, 0x20, 0xb0, 0xa0, 0x30, 0xa2, 0x0, 0x0, + 0x0, 0xb0, 0xa2, 0x65, 0xc7, 0x58, 0x60, 0x0, + 0xb0, 0xa0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0xb0, + 0xa0, 0x6, 0x52, 0x60, 0x0, 0x0, 0xb0, 0x0, + 0x29, 0x0, 0x87, 0x0, 0x0, 0xb0, 0x4, 0x60, + 0x0, 0xa, 0xb1, 0x0, 0x20, 0x11, 0x0, 0x0, + 0x0, 0x0, + + /* U+501F "借" */ + 0x0, 0x0, 0x10, 0x3, 0x0, 0x30, 0x0, 0x0, + 0x1, 0xe1, 0xb, 0x10, 0xd0, 0x0, 0x0, 0x6, + 0x70, 0xa, 0x0, 0xb0, 0x30, 0x0, 0xc, 0x14, + 0x5c, 0x55, 0xc5, 0x60, 0x0, 0x57, 0x0, 0xa, + 0x0, 0xb0, 0x0, 0x0, 0xba, 0x0, 0xa, 0x0, + 0xb0, 0x51, 0x7, 0x39, 0x36, 0x55, 0x55, 0x55, + 0x53, 0x1, 0x19, 0x0, 0x75, 0x55, 0x59, 0x0, + 0x0, 0x19, 0x0, 0xc0, 0x0, 0xb, 0x0, 0x0, + 0x19, 0x0, 0xc0, 0x0, 0xb, 0x0, 0x0, 0x19, + 0x0, 0xd5, 0x55, 0x5b, 0x0, 0x0, 0x19, 0x0, + 0xc0, 0x0, 0xb, 0x0, 0x0, 0x2a, 0x0, 0xd5, + 0x55, 0x5b, 0x0, 0x0, 0x12, 0x0, 0x20, 0x0, + 0x1, 0x0, + + /* U+5024 "値" */ + 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x2a, + 0x35, 0x55, 0xd5, 0x56, 0xa0, 0x0, 0x84, 0x10, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x86, + 0xc5, 0x5a, 0x0, 0x7, 0xd1, 0x51, 0xb0, 0x0, + 0x1a, 0x0, 0x16, 0xa1, 0xc0, 0xc5, 0x55, 0x5a, + 0x0, 0x20, 0xa1, 0xb0, 0xb0, 0x0, 0x1a, 0x0, + 0x0, 0xa1, 0xb0, 0xc5, 0x55, 0x5a, 0x0, 0x0, + 0xa1, 0xb0, 0xb0, 0x0, 0x1a, 0x0, 0x0, 0xa1, + 0xb0, 0xc5, 0x55, 0x5a, 0x0, 0x0, 0xa1, 0xb0, + 0x90, 0x0, 0x7, 0x10, 0x0, 0xa1, 0xd5, 0x55, + 0x55, 0x56, 0xe1, 0x0, 0x50, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+503C "值" */ + 0x0, 0x2, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0xa, 0x40, 0x0, 0x0, 0x0, 0x2a, + 0x45, 0x5c, 0x65, 0x5c, 0x20, 0x0, 0x84, 0x10, + 0xb, 0x10, 0x0, 0x0, 0x0, 0xe2, 0x7, 0x5c, + 0x55, 0xa2, 0x0, 0x6, 0xd2, 0xb, 0x0, 0x0, + 0xb0, 0x0, 0x8, 0x92, 0xb, 0x55, 0x55, 0xc0, + 0x0, 0x40, 0x92, 0xb, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x92, 0xb, 0x55, 0x55, 0xc0, 0x0, 0x0, + 0x92, 0xb, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x92, + 0xb, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x92, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x94, 0x5c, 0x55, + 0x55, 0xc7, 0xb0, 0x0, 0x41, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+505A "做" */ + 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xd, 0x14, 0x80, 0x7, 0x60, 0x0, 0x0, 0x39, + 0x3, 0x70, 0xa, 0x0, 0x0, 0x0, 0x83, 0x3, + 0x72, 0x8, 0x0, 0x30, 0x0, 0xd2, 0x67, 0x96, + 0x59, 0x5b, 0x60, 0x4, 0xe0, 0x3, 0x70, 0x44, + 0xa, 0x0, 0x7, 0xb0, 0x3, 0x70, 0x44, 0xa, + 0x0, 0x21, 0xb0, 0xa6, 0x6c, 0x16, 0xa, 0x0, + 0x0, 0xb0, 0xa0, 0xa, 0x6, 0x56, 0x0, 0x0, + 0xb0, 0xa0, 0xa, 0x1, 0xe1, 0x0, 0x0, 0xb0, + 0xb5, 0x5b, 0x5, 0xc2, 0x0, 0x0, 0xb0, 0xa0, + 0x7, 0x57, 0x1b, 0x20, 0x0, 0xc0, 0x30, 0x16, + 0x30, 0x2, 0xa1, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+505C "停" */ + 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x10, 0x2, 0xa0, 0x1, 0x0, 0x0, 0x57, + 0x36, 0x55, 0x85, 0x58, 0x50, 0x0, 0xa1, 0x0, + 0x75, 0x55, 0x90, 0x0, 0x1, 0xf2, 0x0, 0xb0, + 0x0, 0xb0, 0x0, 0x7, 0xd0, 0x0, 0xc5, 0x55, + 0xc0, 0x0, 0x16, 0xb0, 0x20, 0x20, 0x0, 0x10, + 0x30, 0x20, 0xb0, 0xb5, 0x55, 0x55, 0x58, 0x80, + 0x0, 0xb1, 0x54, 0x55, 0x55, 0x97, 0x0, 0x0, + 0xb0, 0x1, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x39, + 0xc0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x1, 0x10, + 0x0, 0x0, + + /* U+5065 "健" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0xb, 0x0, 0x0, 0x0, 0x1b, + 0x47, 0x62, 0x5c, 0x5a, 0x0, 0x0, 0x74, 0x9, + 0x20, 0xa, 0xa, 0x10, 0x0, 0xc0, 0xb, 0x5, + 0x5c, 0x5c, 0x70, 0x5, 0xe1, 0x56, 0x20, 0x2b, + 0x2b, 0x0, 0x15, 0xb0, 0x85, 0xc1, 0x3b, 0x35, + 0x0, 0x20, 0xb0, 0x0, 0x93, 0x5c, 0x59, 0x10, + 0x0, 0xb0, 0x53, 0x70, 0xa, 0x0, 0x0, 0x0, + 0xb0, 0x67, 0x45, 0x5c, 0x56, 0x60, 0x0, 0xb0, + 0x1e, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, 0x48, + 0xa4, 0x5, 0x0, 0x0, 0x0, 0xb3, 0x40, 0x18, + 0xbb, 0xbc, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5074 "側" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0xd, 0x37, 0x55, 0x80, 0x0, 0xc0, 0x0, 0x2b, + 0xa, 0x0, 0xa0, 0x70, 0xa0, 0x0, 0x74, 0xa, + 0x0, 0xa0, 0xb0, 0xa0, 0x0, 0xc2, 0xc, 0x55, + 0xa0, 0xa0, 0xa0, 0x3, 0xe0, 0xa, 0x0, 0xa0, + 0xa0, 0xa0, 0x7, 0xa0, 0xa, 0x0, 0xa0, 0xa0, + 0xa0, 0x21, 0xa0, 0xc, 0x55, 0xa0, 0xa0, 0xa0, + 0x0, 0xa0, 0xa, 0x0, 0xa0, 0xa0, 0xa0, 0x0, + 0xa0, 0xc, 0x55, 0xa0, 0xa0, 0xa0, 0x0, 0xa0, + 0x6, 0x33, 0x10, 0x0, 0xa0, 0x0, 0xa0, 0x1b, + 0x21, 0xa0, 0x0, 0xa0, 0x0, 0xb0, 0x70, 0x0, + 0x93, 0x5b, 0x80, 0x0, 0x11, 0x0, 0x0, 0x10, + 0x2, 0x0, + + /* U+5099 "備" */ + 0x0, 0x1, 0x0, 0x40, 0x3, 0x0, 0x0, 0x0, + 0xd, 0x30, 0xd1, 0xa, 0x40, 0x0, 0x0, 0x3b, + 0x36, 0xd5, 0x5c, 0x6b, 0x30, 0x0, 0x84, 0x0, + 0xc0, 0xa, 0x20, 0x10, 0x0, 0xe2, 0x65, 0xd5, + 0x5a, 0x67, 0xb1, 0x6, 0xe0, 0x2, 0xc1, 0x0, + 0x1, 0x0, 0x16, 0xb0, 0xd, 0x65, 0xa5, 0x5d, + 0x0, 0x20, 0xb0, 0x7c, 0x0, 0xb0, 0xb, 0x0, + 0x0, 0xb3, 0xb, 0x55, 0xc5, 0x5b, 0x0, 0x0, + 0xb0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xb0, + 0xb, 0x55, 0xc5, 0x5b, 0x0, 0x0, 0xb0, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0x0, 0xb0, 0xb, 0x0, + 0xb3, 0xa9, 0x0, 0x0, 0x30, 0x3, 0x0, 0x0, + 0x31, 0x0, + + /* U+50B3 "傳" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x5, 0x90, 0x0, 0xc0, 0x2, 0x30, 0x0, 0xa, + 0x37, 0x55, 0xc5, 0x56, 0x50, 0x0, 0x1a, 0xa, + 0x55, 0xc5, 0x5c, 0x0, 0x0, 0x8b, 0xb, 0x55, + 0xc5, 0x5b, 0x0, 0x1, 0xa9, 0xb, 0x0, 0xb0, + 0xb, 0x0, 0x6, 0x29, 0x8, 0x55, 0xc5, 0x77, + 0x0, 0x1, 0x19, 0x13, 0x44, 0xc5, 0x5b, 0x40, + 0x0, 0x19, 0x28, 0x53, 0x10, 0x81, 0x40, 0x0, + 0x19, 0x55, 0x55, 0x55, 0xc5, 0xb1, 0x0, 0x19, + 0x4, 0x80, 0x0, 0xb0, 0x0, 0x0, 0x19, 0x0, + 0x71, 0x0, 0xb0, 0x0, 0x0, 0x2a, 0x0, 0x2, + 0x6c, 0x90, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+50C5 "僅" */ + 0x0, 0x2, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, + 0xe, 0x20, 0xc1, 0x1, 0xc0, 0x0, 0x0, 0x59, + 0x55, 0xd5, 0x55, 0xc6, 0xb0, 0x0, 0xb2, 0x10, + 0xb0, 0x0, 0xa0, 0x0, 0x1, 0xe2, 0x0, 0xb5, + 0xa5, 0x80, 0x0, 0x7, 0xd0, 0x7, 0x55, 0xc5, + 0x58, 0x0, 0x16, 0xb0, 0xb, 0x0, 0xb0, 0xb, + 0x0, 0x30, 0xb0, 0xc, 0x55, 0xc5, 0x5b, 0x0, + 0x0, 0xb0, 0x5, 0x0, 0xb0, 0x5, 0x0, 0x0, + 0xb0, 0x6, 0x55, 0xc5, 0x67, 0x0, 0x0, 0xb0, + 0x5, 0x55, 0xc5, 0x69, 0x0, 0x0, 0xb0, 0x1, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb1, 0x55, 0x55, + 0xc5, 0x56, 0xd1, 0x0, 0x30, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+50CD "働" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x2d, 0x13, 0x6a, 0x60, 0xd1, 0x0, 0x0, 0x66, + 0x22, 0xa0, 0x0, 0xb0, 0x0, 0x0, 0xa2, 0x75, + 0xc5, 0x90, 0xb0, 0x0, 0x1, 0xd1, 0x20, 0xa0, + 0x36, 0xc5, 0xd0, 0x7, 0xc0, 0xb5, 0xc5, 0xb0, + 0xb0, 0xb0, 0x8, 0xa0, 0xa5, 0xc5, 0x90, 0xb0, + 0xb0, 0x30, 0xa0, 0xa0, 0xa1, 0x90, 0xa0, 0xb0, + 0x0, 0xa0, 0xb5, 0xc5, 0x92, 0x80, 0xa0, 0x0, + 0xa0, 0x0, 0xa1, 0x46, 0x30, 0x90, 0x0, 0xa0, + 0x65, 0xc5, 0x49, 0x1, 0x80, 0x0, 0xa0, 0x24, + 0xc5, 0x55, 0x3, 0x70, 0x0, 0xb1, 0xb5, 0x11, + 0x60, 0x7d, 0x30, 0x0, 0x20, 0x0, 0x2, 0x0, + 0x2, 0x0, + + /* U+50CF "像" */ + 0x0, 0x1, 0x50, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xb0, 0x4d, 0x55, 0x80, 0x0, 0x0, 0xb, + 0x30, 0xb1, 0x8, 0x40, 0x0, 0x0, 0x1b, 0x8, + 0xb5, 0x78, 0x5b, 0x20, 0x0, 0x9c, 0x33, 0xb0, + 0xb0, 0xb, 0x0, 0x1, 0x9a, 0x0, 0xd5, 0xc5, + 0x5d, 0x10, 0x6, 0x1a, 0x0, 0x26, 0x50, 0x5, + 0x0, 0x11, 0x1a, 0x0, 0x56, 0x93, 0xa6, 0x0, + 0x0, 0x1a, 0x5, 0x28, 0x98, 0x50, 0x0, 0x0, + 0x1a, 0x1, 0x83, 0x9b, 0x81, 0x0, 0x0, 0x1a, + 0x14, 0x9, 0x5d, 0x2c, 0x0, 0x0, 0x1a, 0x3, + 0x92, 0xd, 0x9, 0xd3, 0x0, 0x1a, 0x43, 0x6, + 0xd8, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+50D5 "僕" */ + 0x0, 0x3, 0x0, 0x3, 0x3, 0x0, 0x0, 0x0, + 0xd, 0x30, 0xd, 0xd, 0x0, 0x0, 0x0, 0x3a, + 0x8, 0x1b, 0xb, 0x2c, 0x0, 0x0, 0x84, 0x5, + 0x4b, 0xb, 0x81, 0x0, 0x0, 0xd3, 0x56, 0x5a, + 0x5b, 0x67, 0x80, 0x5, 0xd2, 0x0, 0x82, 0x4, + 0x60, 0x0, 0x7, 0x92, 0x15, 0x78, 0x59, 0x6a, + 0x0, 0x20, 0x92, 0x1, 0x0, 0xb0, 0x10, 0x0, + 0x0, 0x92, 0x3, 0x65, 0xc5, 0x73, 0x0, 0x0, + 0x92, 0x45, 0x57, 0xa5, 0x59, 0x60, 0x0, 0x92, + 0x10, 0xa, 0x15, 0x0, 0x0, 0x0, 0x92, 0x1, + 0x92, 0x3, 0x80, 0x0, 0x0, 0x92, 0x46, 0x0, + 0x0, 0x3c, 0x80, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+50F9 "價" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x46, 0x57, 0x57, 0x56, 0x90, 0x0, 0x85, + 0x2, 0xa, 0xa, 0x2, 0x10, 0x0, 0xc2, 0xc, + 0x5c, 0x5c, 0x5a, 0x40, 0x2, 0xf3, 0xc, 0x5c, + 0x5c, 0x5a, 0x30, 0x7, 0xa2, 0x4, 0x0, 0x0, + 0x3, 0x0, 0x6, 0x82, 0x6, 0x65, 0x55, 0x5b, + 0x0, 0x30, 0x82, 0x6, 0x75, 0x55, 0x59, 0x0, + 0x0, 0x82, 0x6, 0x30, 0x0, 0x19, 0x0, 0x0, + 0x82, 0x6, 0x75, 0x55, 0x59, 0x0, 0x0, 0x82, + 0x6, 0x75, 0x55, 0x59, 0x0, 0x0, 0x82, 0x1, + 0xb3, 0x3, 0x86, 0x0, 0x0, 0x82, 0x48, 0x10, + 0x0, 0x6, 0xb0, 0x0, 0x10, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+5104 "億" */ + 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x70, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xd, + 0x4, 0x65, 0x95, 0x58, 0x50, 0x0, 0x49, 0x0, + 0x55, 0x5, 0xa0, 0x0, 0x0, 0xab, 0x24, 0x48, + 0x49, 0x44, 0xa1, 0x1, 0x99, 0x12, 0x31, 0x11, + 0x24, 0x10, 0x6, 0x29, 0x0, 0xc5, 0x55, 0x6b, + 0x0, 0x2, 0x19, 0x0, 0xc5, 0x55, 0x69, 0x0, + 0x0, 0x19, 0x0, 0xd5, 0x55, 0x6a, 0x0, 0x0, + 0x19, 0x0, 0x42, 0x70, 0x22, 0x0, 0x0, 0x19, + 0x5, 0x1a, 0x63, 0x2a, 0x20, 0x0, 0x19, 0x38, + 0x19, 0x0, 0x83, 0x80, 0x0, 0x2a, 0x41, 0xc, + 0xab, 0xd2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+512A "優" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x26, 0x55, 0x85, 0x5a, 0x20, 0x0, 0x48, + 0x0, 0xb5, 0x75, 0xb1, 0x0, 0x0, 0x92, 0x0, + 0xc5, 0x55, 0xc0, 0x0, 0x0, 0xd2, 0x0, 0xc5, + 0x55, 0xc0, 0x0, 0x5, 0xe0, 0x75, 0xa5, 0x55, + 0xa5, 0xb0, 0x7, 0xb1, 0xa2, 0x73, 0xa2, 0x25, + 0x40, 0x21, 0xb0, 0x38, 0x83, 0x12, 0x7a, 0x10, + 0x0, 0xb0, 0x31, 0x5a, 0x88, 0x33, 0x0, 0x0, + 0xb0, 0x0, 0xd7, 0x55, 0x92, 0x0, 0x0, 0xb0, + 0x9, 0x47, 0x7, 0x70, 0x0, 0x0, 0xb0, 0x30, + 0x5, 0xf9, 0x0, 0x0, 0x0, 0xb0, 0x4, 0x75, + 0x6, 0xcb, 0x50, 0x0, 0x20, 0x30, 0x0, 0x0, + 0x2, 0x0, + + /* U+513F "儿" */ + 0x0, 0x0, 0x20, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x1, 0xb0, + 0xa, 0x20, 0x0, 0x0, 0x0, 0x1b, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x1, 0xa0, 0xa, 0x20, 0x0, + 0x0, 0x0, 0x29, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x4, 0x80, 0xa, 0x20, 0x0, 0x0, 0x0, 0x75, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0xb, 0x10, 0xa, + 0x20, 0x4, 0x0, 0x3, 0x90, 0x0, 0xa2, 0x0, + 0x60, 0x0, 0xb1, 0x0, 0x9, 0x20, 0xa, 0x21, + 0x81, 0x0, 0x0, 0x5d, 0xbb, 0xe4, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5143 "元" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, + 0x6, 0x55, 0x55, 0x55, 0x53, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0x0, 0x4, 0x65, 0x59, 0x55, + 0x95, 0x5a, 0x60, 0x0, 0x0, 0xe, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x49, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x95, 0x0, 0xd0, 0x0, 0x30, 0x0, + 0x1, 0xc0, 0x0, 0xd0, 0x0, 0x60, 0x0, 0xb, + 0x30, 0x0, 0xd0, 0x0, 0xc0, 0x1, 0x92, 0x0, + 0x0, 0xac, 0xbc, 0xc2, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5144 "兄" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x55, 0x55, 0x55, 0xc2, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xe5, 0xb8, 0x5d, 0x5c, 0x0, 0x0, 0x3, 0xa, + 0x30, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xd, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, + 0x40, 0x0, 0x6, 0x70, 0xd, 0x0, 0x6, 0x0, + 0x2, 0xb0, 0x0, 0xd0, 0x0, 0xc0, 0x4, 0x80, + 0x0, 0xb, 0xcb, 0xcd, 0x23, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5145 "充" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x4, 0x55, + 0x55, 0x7b, 0x55, 0x59, 0x90, 0x1, 0x0, 0x3, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x30, + 0x23, 0x0, 0x0, 0x0, 0x2, 0x91, 0x0, 0x6, + 0x90, 0x0, 0x0, 0x4f, 0xaa, 0x87, 0x95, 0x9c, + 0x0, 0x0, 0x2, 0xd, 0x1, 0xb0, 0x8, 0x0, + 0x0, 0x0, 0x1c, 0x1, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x57, 0x1, 0xb0, 0x0, 0x30, 0x0, 0x0, + 0xb1, 0x1, 0xb0, 0x0, 0x60, 0x0, 0x7, 0x60, + 0x0, 0xb0, 0x0, 0xb0, 0x1, 0x73, 0x0, 0x0, + 0xbb, 0xbc, 0xd2, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5148 "先" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x30, 0x92, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x55, + 0xb6, 0x55, 0xd2, 0x0, 0x0, 0x92, 0x0, 0x92, + 0x0, 0x0, 0x0, 0x2, 0x50, 0x0, 0x92, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x92, 0x0, 0x6, + 0x30, 0x17, 0x55, 0x7b, 0x59, 0x95, 0x55, 0x40, + 0x0, 0x0, 0x66, 0x6, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x93, 0x6, 0x60, 0x0, 0x10, 0x0, 0x0, + 0xb0, 0x6, 0x60, 0x0, 0x50, 0x0, 0xa, 0x30, + 0x5, 0x60, 0x1, 0x80, 0x2, 0x82, 0x0, 0x2, + 0xda, 0xab, 0xb0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5149 "光" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x0, 0x48, 0x0, 0x91, 0x0, 0x0, 0x2, 0xc0, + 0x48, 0x4, 0xb0, 0x0, 0x0, 0x0, 0xa4, 0x48, + 0xa, 0x10, 0x0, 0x0, 0x0, 0x20, 0x48, 0x33, + 0x2, 0x40, 0x6, 0x55, 0x5c, 0x56, 0xc5, 0x56, + 0x60, 0x0, 0x0, 0x1c, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x29, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0xb0, 0x0, 0x30, 0x0, 0x0, + 0xb0, 0x0, 0xb0, 0x0, 0x60, 0x0, 0x8, 0x50, + 0x0, 0xc0, 0x0, 0xa0, 0x1, 0x73, 0x0, 0x0, + 0xab, 0xaa, 0xd2, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+514B "克" */ + 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x5, 0x55, + 0x55, 0xb6, 0x55, 0x59, 0x70, 0x1, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x55, 0xc5, + 0x55, 0xa0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xa0, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0xb, 0x5c, 0x5a, 0x95, 0x80, 0x0, 0x0, + 0x0, 0xb, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x47, 0x7, 0x60, 0x0, 0x50, 0x0, 0x1, 0xb0, + 0x7, 0x60, 0x0, 0x80, 0x0, 0x57, 0x10, 0x5, + 0xd9, 0x9b, 0xb0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+514D "免" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd7, 0x55, 0xb5, 0x0, 0x0, 0x0, 0x8, 0x50, + 0x0, 0xc1, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x5, + 0x20, 0x4, 0x0, 0x3, 0x7c, 0x55, 0x6c, 0x55, + 0x5d, 0x0, 0x3, 0xc, 0x0, 0x39, 0x0, 0x1b, + 0x0, 0x0, 0xd, 0x55, 0x8a, 0x55, 0x5b, 0x0, + 0x0, 0x8, 0x0, 0x86, 0xb0, 0x5, 0x0, 0x0, + 0x0, 0x0, 0xd2, 0xb0, 0x0, 0x20, 0x0, 0x0, + 0x7, 0x81, 0xb0, 0x0, 0x60, 0x0, 0x0, 0x5b, + 0x0, 0xb0, 0x0, 0x91, 0x0, 0x38, 0x50, 0x0, + 0xda, 0xaa, 0xe4, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5152 "兒" */ + 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x59, 0x73, 0x55, 0x93, 0x0, 0x0, 0xd0, 0x0, + 0x1, 0xa, 0x20, 0x0, 0xc, 0x2, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0xd5, 0x74, 0x6, 0x5c, 0x10, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, + 0xd5, 0x55, 0x55, 0x5c, 0x20, 0x0, 0x7, 0xc, + 0x0, 0xc0, 0x50, 0x0, 0x0, 0x0, 0xc0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0xc0, 0x0, + 0x40, 0x0, 0xa, 0x20, 0xc, 0x0, 0x7, 0x0, + 0x7, 0x60, 0x0, 0xd1, 0x1, 0xd4, 0x6, 0x40, + 0x0, 0x6, 0x99, 0x97, 0x12, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+515A "党" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x2b, 0x5, 0x30, 0x0, 0x0, 0x1, + 0xc2, 0x19, 0xc, 0x30, 0x0, 0x0, 0x30, 0x42, + 0x19, 0x52, 0x0, 0x30, 0x1, 0xa5, 0x55, 0x55, + 0x55, 0x5a, 0xa0, 0x9, 0x40, 0x30, 0x0, 0x4, + 0x5, 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5c, 0x20, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0xd6, 0x86, 0x7c, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x72, 0x60, 0x0, 0x10, 0x0, 0x0, + 0xb, 0x22, 0x60, 0x0, 0x50, 0x0, 0x0, 0x78, + 0x2, 0x70, 0x0, 0xa0, 0x1, 0x57, 0x40, 0x1, + 0xca, 0xab, 0xc1, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5165 "入" */ + 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb9, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x8, 0x54, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0xc1, 0x0, + 0x0, 0x0, 0x0, 0x94, 0x0, 0x6a, 0x0, 0x0, + 0x0, 0x5, 0x90, 0x0, 0xc, 0x60, 0x0, 0x0, + 0x29, 0x0, 0x0, 0x2, 0xe8, 0x0, 0x3, 0x70, + 0x0, 0x0, 0x0, 0x2e, 0xc2, 0x24, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x10, + + /* U+5167 "內" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, + 0xa, 0x55, 0x57, 0x95, 0x55, 0xc1, 0xc0, 0x0, + 0x3c, 0x0, 0xc, 0xc, 0x0, 0x6, 0xc1, 0x0, + 0xc0, 0xc0, 0x0, 0xb3, 0x70, 0xc, 0xc, 0x0, + 0x46, 0xb, 0x10, 0xc0, 0xc0, 0x9, 0x0, 0x4c, + 0xc, 0xc, 0x7, 0x10, 0x0, 0xa9, 0xc0, 0xc1, + 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, 0x0, + 0x10, 0xd0, 0xb0, 0x0, 0x0, 0x4, 0xca, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5168 "全" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x3, 0x70, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, + 0x59, 0x10, 0x0, 0x0, 0x49, 0x0, 0x0, 0x9, + 0xe9, 0x40, 0x6, 0x66, 0x55, 0xc6, 0x55, 0x39, + 0x70, 0x20, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa1, 0x2, 0x40, 0x0, 0x0, + 0x16, 0x55, 0xc6, 0x55, 0x40, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0x0, 0x4, 0x55, 0x55, 0xc6, + 0x55, 0x5d, 0x50, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5169 "兩" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x55, + 0x55, 0x55, 0x55, 0x57, 0xe2, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x10, 0xc, 0x55, 0x55, 0xc5, 0x55, 0x5c, + 0x0, 0xb1, 0x10, 0xb, 0x10, 0x0, 0xa0, 0xb, + 0x7, 0x10, 0xb0, 0x70, 0xa, 0x0, 0xb0, 0x3b, + 0xb, 0x5, 0x90, 0xa0, 0xb, 0x9, 0xa4, 0xb0, + 0x9b, 0x4a, 0x0, 0xb3, 0x52, 0x9b, 0x44, 0x59, + 0xa0, 0xc, 0x50, 0x2, 0xb4, 0x1, 0x3a, 0x0, + 0xb0, 0x0, 0xb, 0x0, 0x1, 0xa0, 0xb, 0x0, + 0x0, 0xa0, 0x6, 0xe6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+516B "八" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x10, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x57, 0x0, 0x81, + 0x0, 0x0, 0x0, 0x0, 0x84, 0x0, 0x55, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1a, 0x0, 0x0, + 0x0, 0x1, 0xa0, 0x0, 0xa, 0x10, 0x0, 0x0, + 0x8, 0x30, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x19, + 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x80, 0x0, + 0x0, 0x0, 0x1e, 0x80, 0x5, 0x10, 0x0, 0x0, + 0x0, 0x3, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+516C "公" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x10, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0xb2, + 0x0, 0x55, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, + 0xc, 0x10, 0x0, 0x0, 0x1a, 0x0, 0x20, 0x3, + 0xc1, 0x0, 0x0, 0x81, 0x0, 0xa8, 0x0, 0x6e, + 0x60, 0x5, 0x0, 0x3, 0xc0, 0x0, 0x5, 0x40, + 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x74, 0x0, 0x53, 0x0, 0x0, 0x0, 0x3, + 0x70, 0x0, 0xa, 0x30, 0x0, 0x0, 0x4c, 0x66, + 0x76, 0x67, 0xe1, 0x0, 0x0, 0x28, 0x42, 0x10, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+516D "六" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0x0, 0x0, 0x10, 0x6, 0x55, 0x55, 0x55, + 0x55, 0x58, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3c, 0x10, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x98, 0x0, 0x28, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x6, 0x80, 0x0, 0x0, + 0x9, 0x40, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x57, + 0x0, 0x0, 0x0, 0x3f, 0x20, 0x2, 0x80, 0x0, + 0x0, 0x0, 0xb, 0x40, 0x15, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5171 "共" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc0, 0x0, 0x0, 0x4, 0x55, 0xd5, + 0x55, 0xd5, 0x5c, 0x20, 0x0, 0x0, 0xc0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, 0x6, 0x20, + 0x36, 0x55, 0x75, 0x55, 0x65, 0x56, 0x50, 0x0, + 0x0, 0xa8, 0x0, 0x52, 0x0, 0x0, 0x0, 0x7, + 0xa0, 0x0, 0x7, 0xa1, 0x0, 0x0, 0x67, 0x0, + 0x0, 0x0, 0x5e, 0x20, 0x6, 0x30, 0x0, 0x0, + 0x0, 0x6, 0x50, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5176 "其" */ + 0x0, 0x0, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0x1d, 0x0, 0x0, 0x3, 0x55, + 0xd5, 0x55, 0x6c, 0x5b, 0x60, 0x0, 0x0, 0xc0, + 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x5b, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1b, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1b, 0x0, + 0x0, 0x0, 0x0, 0xc5, 0x55, 0x5b, 0x0, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x1b, 0x1, 0x60, 0x16, + 0x55, 0x76, 0x55, 0x57, 0x56, 0x72, 0x0, 0x0, + 0xab, 0x0, 0x48, 0x10, 0x0, 0x0, 0xa, 0x70, + 0x0, 0x2, 0xd7, 0x0, 0x3, 0x82, 0x0, 0x0, + 0x0, 0x2e, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+5177 "具" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0xc5, + 0x55, 0x56, 0x90, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0x1, 0x90, 0x0, 0x0, 0x0, 0xc5, 0x55, 0x56, + 0x90, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x1, 0x90, + 0x0, 0x0, 0x0, 0xc5, 0x55, 0x56, 0x90, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x1, 0x90, 0x40, 0x6, + 0x55, 0x85, 0x55, 0x55, 0x87, 0xa2, 0x0, 0x0, + 0x89, 0x0, 0x25, 0x10, 0x0, 0x0, 0x9, 0x70, + 0x0, 0x1, 0xa7, 0x0, 0x3, 0x72, 0x0, 0x0, + 0x0, 0xb, 0x40, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5185 "内" */ + 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x50, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, + 0x7, 0x55, 0x5d, 0x55, 0x55, 0xa0, 0xc0, 0x0, + 0xd0, 0x0, 0xc, 0xc, 0x0, 0xc, 0x0, 0x0, + 0xc0, 0xc0, 0x5, 0xa7, 0x0, 0xc, 0xc, 0x0, + 0xa1, 0x3c, 0x20, 0xc0, 0xc0, 0x73, 0x0, 0x6b, + 0xc, 0xc, 0x52, 0x0, 0x0, 0x60, 0xc0, 0xc0, + 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, 0x1, + 0x23, 0xb0, 0xc0, 0x0, 0x0, 0x4, 0xe7, 0x1, + 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+5186 "円" */ + 0x85, 0x55, 0x55, 0x55, 0x5a, 0x1c, 0x0, 0x2, + 0x90, 0x0, 0xc0, 0xc0, 0x0, 0x29, 0x0, 0xc, + 0xc, 0x0, 0x2, 0x90, 0x0, 0xc0, 0xc0, 0x0, + 0x29, 0x0, 0xc, 0xd, 0x55, 0x56, 0xa5, 0x55, + 0xd0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0xc0, 0x0, 0x0, 0x0, + 0xc, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xc0, + 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, 0x0, + 0x6c, 0xc0, 0x10, 0x0, 0x0, 0x0, 0x21, 0x0, + + /* U+518A "冊" */ + 0x0, 0x17, 0x55, 0x55, 0x55, 0x59, 0x0, 0x0, + 0x1a, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xa, + 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xa, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0x0, 0xa, 0xb, 0x0, + 0xb0, 0xb, 0x0, 0x4, 0x5c, 0x5c, 0x55, 0xc5, + 0x5d, 0xd3, 0x1, 0x1a, 0xb, 0x0, 0xb0, 0xb, + 0x0, 0x0, 0xa, 0xb, 0x0, 0xb0, 0xb, 0x0, + 0x0, 0xa, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, + 0xa, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xa, + 0xa, 0x0, 0xa0, 0xb, 0x0, 0x0, 0x19, 0x0, + 0x0, 0x4, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+518D "再" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x65, 0x55, 0x55, 0x55, 0x5d, 0x30, 0x0, 0x0, + 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x7, 0x55, + 0x6b, 0x55, 0x92, 0x0, 0x0, 0xc, 0x0, 0x29, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x29, 0x0, + 0xc0, 0x0, 0x0, 0xd, 0x55, 0x6b, 0x55, 0xd0, + 0x0, 0x0, 0xc, 0x0, 0x29, 0x0, 0xc0, 0x0, + 0x0, 0xc, 0x0, 0x29, 0x0, 0xc1, 0x70, 0x6, + 0x5d, 0x55, 0x55, 0x55, 0xd5, 0x61, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x5b, 0xd0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, + 0x10, 0x0, + + /* U+5199 "写" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x55, 0x55, 0x55, 0x55, 0x97, 0x1, 0xc0, 0x10, + 0x0, 0x0, 0xa, 0x20, 0x46, 0xd, 0x10, 0x0, + 0x1, 0x10, 0x0, 0x0, 0xd5, 0x55, 0x55, 0xa5, + 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x60, 0x0, 0x0, 0x3, 0x0, 0x0, 0x77, + 0x55, 0x55, 0x55, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x45, 0x55, 0x55, 0x5a, 0x81, + 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x48, 0x0, + 0x0, 0x0, 0x0, 0x13, 0x1a, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x3d, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, + + /* U+519B "军" */ + 0x0, 0x85, 0x55, 0x55, 0x55, 0x59, 0x70, 0x5, + 0x80, 0x2, 0x90, 0x0, 0x7, 0x10, 0x2, 0x10, + 0x8, 0x50, 0x0, 0x20, 0x0, 0x0, 0x35, 0x6c, + 0x55, 0x55, 0x72, 0x0, 0x0, 0x0, 0x93, 0x9, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x80, 0xb, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x55, 0x5c, 0x55, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0x4, 0x55, 0x55, 0x5c, 0x55, 0x56, 0xa0, 0x1, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+51AC "冬" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x99, 0x55, 0x5a, 0x70, 0x0, 0x0, 0x3, 0xa3, + 0x0, 0x3c, 0x10, 0x0, 0x0, 0x9, 0x6, 0x31, + 0xc2, 0x0, 0x0, 0x0, 0x60, 0x0, 0xac, 0x20, + 0x0, 0x0, 0x1, 0x0, 0x5, 0xaa, 0x91, 0x0, + 0x0, 0x0, 0x2, 0x96, 0x0, 0x4d, 0x94, 0x0, + 0x4, 0x65, 0x0, 0x6a, 0x20, 0x6d, 0xa1, 0x0, + 0x0, 0x0, 0x4, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x57, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5d, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+51B7 "冷" */ + 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x8, 0x60, + 0x0, 0xd, 0x52, 0x0, 0x0, 0x0, 0xf0, 0x40, + 0x58, 0x9, 0x0, 0x0, 0x0, 0x30, 0x50, 0xb3, + 0x3, 0xa0, 0x0, 0x0, 0x5, 0x18, 0x31, 0xc0, + 0x7c, 0x30, 0x0, 0x8, 0x53, 0x0, 0xa1, 0x6, + 0xa2, 0x0, 0x55, 0x13, 0x55, 0x55, 0x92, 0x0, + 0x18, 0xe0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x2, + 0xc0, 0x0, 0x10, 0xa, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0x9, 0x71, 0x0, 0x0, 0x4, 0xa0, 0x0, + 0x1, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+51CD "凍" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x2, 0xc1, + 0x45, 0x55, 0xd5, 0x57, 0xb0, 0x0, 0x75, 0x1, + 0x0, 0xb0, 0x1, 0x0, 0x0, 0x2, 0x2c, 0x55, + 0xc5, 0x5d, 0x10, 0x0, 0x5, 0xb, 0x0, 0xb0, + 0xb, 0x0, 0x0, 0x6, 0xb, 0x55, 0xc5, 0x5c, + 0x0, 0x0, 0x43, 0xb, 0x0, 0xb0, 0xb, 0x0, + 0x6, 0xd0, 0xa, 0x5d, 0xe8, 0x58, 0x0, 0x2, + 0xc0, 0x0, 0x39, 0xb6, 0x10, 0x0, 0x2, 0xb0, + 0x1, 0xa0, 0xb1, 0xa0, 0x0, 0x4, 0xb0, 0x9, + 0x10, 0xb0, 0x5b, 0x20, 0x1, 0x51, 0x60, 0x0, + 0xb0, 0x6, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x50, + 0x0, 0x0, + + /* U+51DD "凝" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x13, + 0x0, 0xc0, 0x80, 0x65, 0x5d, 0x20, 0xa, 0x60, + 0xb6, 0x21, 0x1, 0x35, 0x0, 0x2, 0x52, 0xa0, + 0x15, 0x7, 0x80, 0x0, 0x0, 0x3, 0x98, 0xa5, + 0x0, 0xb0, 0x0, 0x0, 0x50, 0xb0, 0x2, 0x65, + 0x85, 0xd0, 0x0, 0x72, 0xb5, 0x92, 0x0, 0xa3, + 0x20, 0x3, 0x76, 0xa, 0x0, 0xb1, 0xa0, 0x30, + 0x3e, 0x45, 0x5c, 0x78, 0xa0, 0xc5, 0x50, 0xb, + 0x1, 0xc, 0x0, 0xb0, 0xa0, 0x0, 0xf, 0x0, + 0x57, 0xa1, 0xa7, 0xa0, 0x0, 0x8, 0x0, 0x90, + 0x66, 0x41, 0xb6, 0x20, 0x0, 0x6, 0x0, 0x5, + 0x0, 0x7, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+51E6 "処" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0xa5, 0xb2, 0x0, 0x0, 0x3b, 0x56, + 0x90, 0xb0, 0xc0, 0x0, 0x0, 0x92, 0x4, 0x60, + 0xb0, 0xc0, 0x0, 0x0, 0xb1, 0x7, 0x31, 0x90, + 0xc0, 0x0, 0x7, 0x14, 0xb, 0x3, 0x70, 0xc0, + 0x0, 0x3, 0x6, 0x1a, 0x8, 0x10, 0xc0, 0x10, + 0x0, 0x2, 0xc4, 0x27, 0x0, 0xc0, 0x60, 0x0, + 0x1, 0xe3, 0x60, 0x0, 0xa9, 0xd2, 0x0, 0x9, + 0x2b, 0x40, 0x0, 0x1, 0x0, 0x0, 0x73, 0x1, + 0xbc, 0x63, 0x22, 0x31, 0x6, 0x20, 0x0, 0x3, + 0x8c, 0xde, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+51FA "出" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x0, 0x0, 0x3, 0x10, 0xa, 0x10, + 0x5, 0x10, 0x7, 0x60, 0xa, 0x10, 0xa, 0x20, + 0x6, 0x50, 0xa, 0x10, 0xa, 0x10, 0x6, 0x50, + 0xa, 0x10, 0xa, 0x10, 0x8, 0x75, 0x5c, 0x65, + 0x5c, 0x20, 0x0, 0x0, 0xa, 0x10, 0x2, 0x0, + 0xd, 0x10, 0xa, 0x10, 0x2, 0xa0, 0xc, 0x0, + 0xa, 0x10, 0x1, 0xa0, 0xc, 0x0, 0xa, 0x10, + 0x1, 0xa0, 0xc, 0x0, 0xa, 0x10, 0x1, 0xa0, + 0x8, 0x55, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+5206 "分" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x80, 0x0, 0x0, 0x0, 0x1, 0xc0, + 0x0, 0x27, 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, + 0x9, 0x40, 0x0, 0x0, 0x65, 0x0, 0x0, 0x1, + 0xb8, 0x10, 0x4, 0x54, 0x57, 0x85, 0x5c, 0x59, + 0xc1, 0x2, 0x0, 0x8, 0x40, 0xb, 0x10, 0x0, + 0x0, 0x0, 0xb, 0x10, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0x93, 0x0, 0xd, 0x0, 0x0, 0x0, 0x5, 0x60, + 0x0, 0x2b, 0x0, 0x0, 0x0, 0x63, 0x0, 0x18, + 0xf3, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+5207 "切" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0xc, + 0x0, 0x65, 0x69, 0x56, 0xd0, 0x0, 0xc, 0x0, + 0x10, 0x3a, 0x1, 0xb0, 0x0, 0xc, 0x46, 0xa1, + 0x48, 0x2, 0xb0, 0x5, 0x5c, 0x0, 0x0, 0x67, + 0x2, 0xa0, 0x0, 0xc, 0x0, 0x0, 0x84, 0x3, + 0x90, 0x0, 0xc, 0x0, 0x0, 0xc1, 0x4, 0x90, + 0x0, 0xc, 0x1, 0x51, 0xc0, 0x4, 0x80, 0x0, + 0xc, 0x57, 0x8, 0x50, 0x5, 0x70, 0x0, 0x1f, + 0x60, 0x2b, 0x0, 0x7, 0x50, 0x0, 0x3, 0x1, + 0xa1, 0x4, 0x3c, 0x30, 0x0, 0x0, 0x36, 0x0, + 0x1, 0xca, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+520A "刊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x3, + 0x55, 0x55, 0x96, 0x0, 0x1, 0xd0, 0x0, 0x10, + 0xc0, 0x0, 0x7, 0x1, 0xb0, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x0, + 0xb, 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x17, 0xb, + 0x1, 0xb0, 0x6, 0x55, 0xd5, 0x55, 0x1b, 0x1, + 0xb0, 0x0, 0x0, 0xc0, 0x0, 0xb, 0x1, 0xb0, + 0x0, 0x0, 0xc0, 0x0, 0xc, 0x1, 0xb0, 0x0, + 0x0, 0xc0, 0x0, 0x1b, 0x1, 0xb0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x13, 0xa0, 0x0, 0x0, 0xd0, 0x0, + 0x1, 0x6e, 0x60, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x2, 0x0, + + /* U+5217 "列" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x10, 0x1, 0xc0, 0x3, 0x65, + 0xe5, 0x55, 0x30, 0x1, 0xa0, 0x0, 0x3, 0xb0, + 0x0, 0xb, 0x1, 0xa0, 0x0, 0x8, 0x95, 0x75, + 0xb, 0x1, 0xa0, 0x0, 0xc, 0x0, 0x94, 0xb, + 0x1, 0xa0, 0x0, 0x79, 0x10, 0xc0, 0xb, 0x1, + 0xa0, 0x1, 0x62, 0xb3, 0x90, 0xb, 0x1, 0xa0, + 0x4, 0x0, 0x7b, 0x20, 0xb, 0x1, 0xa0, 0x0, + 0x0, 0x48, 0x0, 0xc, 0x1, 0xa0, 0x0, 0x2, + 0xa0, 0x0, 0x4, 0x1, 0xa0, 0x0, 0x38, 0x0, + 0x0, 0x3, 0x24, 0xa0, 0x4, 0x40, 0x0, 0x0, + 0x1, 0x6f, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+521D "初" */ + 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x40, 0x45, 0x65, 0x55, 0xb1, 0x17, 0x55, 0xb7, + 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x2, 0xb0, 0x0, + 0xc0, 0x0, 0xb0, 0x0, 0xc, 0x16, 0x50, 0xb0, + 0x1, 0xa0, 0x0, 0x7e, 0x19, 0x2, 0x90, 0x2, + 0x90, 0x6, 0x4b, 0x95, 0x5, 0x60, 0x4, 0x80, + 0x32, 0xb, 0xb, 0x38, 0x20, 0x5, 0x70, 0x0, + 0xb, 0x0, 0xa, 0x0, 0x6, 0x60, 0x0, 0xb, + 0x0, 0x64, 0x0, 0x8, 0x40, 0x0, 0xb, 0x2, + 0x70, 0x13, 0x1b, 0x10, 0x0, 0xb, 0x25, 0x0, + 0x4, 0xea, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5224 "判" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x2, 0xb0, 0x3, 0x50, + 0xb0, 0x3b, 0x2, 0x1, 0x90, 0x0, 0xc3, 0xb0, + 0x92, 0xc, 0x11, 0x90, 0x0, 0x62, 0xb3, 0x30, + 0xb, 0x1, 0x90, 0x2, 0x55, 0xc5, 0x6b, 0xb, + 0x1, 0x90, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x1, + 0x90, 0x0, 0x0, 0xb0, 0x3, 0xb, 0x1, 0x90, + 0x17, 0x55, 0xc5, 0x58, 0x3b, 0x1, 0x90, 0x0, + 0x4, 0x70, 0x0, 0xc, 0x1, 0x90, 0x0, 0xa, + 0x0, 0x0, 0x6, 0x1, 0x90, 0x0, 0x73, 0x0, + 0x0, 0x0, 0x2, 0x90, 0x6, 0x20, 0x0, 0x0, + 0x0, 0x7f, 0x50, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+5225 "別" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x55, 0x59, 0x0, 0x0, 0xc0, 0x0, 0xb0, + 0x0, 0x1a, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x0, + 0x1a, 0xa, 0x0, 0xb0, 0x0, 0xd5, 0x55, 0x6a, + 0xb, 0x0, 0xb0, 0x0, 0x68, 0x10, 0x4, 0xb, + 0x0, 0xb0, 0x0, 0xd, 0x0, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0xd, 0x55, 0x6a, 0xb, 0x0, 0xb0, + 0x0, 0x39, 0x0, 0x46, 0xb, 0x0, 0xb0, 0x0, + 0x75, 0x0, 0x74, 0xa, 0x0, 0xb0, 0x0, 0xb0, + 0x0, 0xa1, 0x0, 0x0, 0xb0, 0x4, 0x50, 0x22, + 0xc0, 0x0, 0x12, 0xb0, 0x7, 0x0, 0x1d, 0x50, + 0x0, 0x5e, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+5229 "利" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x4, 0x0, 0x2, + 0x59, 0xba, 0x40, 0x0, 0xb3, 0x3, 0x21, 0xc0, + 0x0, 0x6, 0xa, 0x10, 0x0, 0xc, 0x0, 0x0, + 0xb0, 0xa1, 0x25, 0x55, 0xd5, 0x6c, 0x1b, 0xa, + 0x10, 0x10, 0x1f, 0x0, 0x0, 0xb0, 0xa1, 0x0, + 0x7, 0xf5, 0x10, 0xb, 0xa, 0x10, 0x1, 0xac, + 0x1d, 0x40, 0xb0, 0xa1, 0x0, 0x91, 0xc0, 0x36, + 0xb, 0xa, 0x10, 0x62, 0xc, 0x0, 0x0, 0x90, + 0xa1, 0x31, 0x0, 0xc0, 0x0, 0x0, 0xa, 0x10, + 0x0, 0xc, 0x0, 0x0, 0x44, 0xd1, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x7d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5230 "到" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4, + 0x55, 0x55, 0x6b, 0x0, 0x0, 0xd0, 0x1, 0x0, + 0xd2, 0x0, 0x5, 0x0, 0xb0, 0x0, 0x8, 0x42, + 0x10, 0xc, 0x10, 0xb0, 0x0, 0x53, 0x0, 0x93, + 0xb, 0x0, 0xb0, 0x6, 0xd8, 0xa6, 0x5e, 0xb, + 0x0, 0xb0, 0x0, 0x0, 0xc1, 0x5, 0xb, 0x0, + 0xb0, 0x0, 0x0, 0xc0, 0x2, 0xb, 0x0, 0xb0, + 0x4, 0x55, 0xd5, 0x67, 0xb, 0x0, 0xb0, 0x0, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, + 0xc0, 0x14, 0x2, 0x0, 0xb0, 0x4, 0x68, 0xb7, + 0x40, 0x0, 0x1, 0xb0, 0xa, 0x72, 0x0, 0x0, + 0x1, 0x7f, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+5236 "制" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x3, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0xb1, 0x3, 0xa0, 0xa0, + 0x0, 0x2, 0xb, 0x0, 0x87, 0x5c, 0x6a, 0x0, + 0xc0, 0xb0, 0x7, 0x0, 0xa0, 0x0, 0xa, 0xb, + 0x3, 0x65, 0x5c, 0x57, 0x80, 0xa0, 0xb0, 0x0, + 0x0, 0xa0, 0x10, 0xa, 0xb, 0x0, 0x95, 0x5c, + 0x5c, 0x20, 0xa0, 0xb0, 0x9, 0x10, 0xa0, 0xa0, + 0xa, 0xb, 0x0, 0x91, 0xa, 0xa, 0x0, 0xa0, + 0xb0, 0x9, 0x10, 0xb5, 0xc0, 0x0, 0xb, 0x0, + 0x60, 0xa, 0x26, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xa0, 0x0, 0x3, 0xad, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x10, + + /* U+5238 "券" */ + 0x0, 0x0, 0x0, 0x60, 0x1, 0x0, 0x0, 0x0, + 0x1a, 0x10, 0xe1, 0xc, 0x20, 0x0, 0x0, 0x5, + 0x92, 0xa0, 0x63, 0x0, 0x0, 0x2, 0x55, 0x69, + 0x95, 0x75, 0xa8, 0x0, 0x0, 0x10, 0xb, 0x10, + 0x0, 0x0, 0x0, 0x15, 0x55, 0x5d, 0x55, 0x55, + 0x5b, 0x80, 0x1, 0x0, 0xa2, 0x0, 0x52, 0x0, + 0x0, 0x0, 0x8, 0x40, 0x0, 0x9, 0x71, 0x0, + 0x1, 0x84, 0x5b, 0x55, 0x5e, 0x7e, 0xb2, 0x14, + 0x0, 0xc, 0x0, 0xc, 0x0, 0x20, 0x0, 0x0, + 0x66, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x3, 0xa0, + 0x0, 0x48, 0x0, 0x0, 0x1, 0x67, 0x0, 0x18, + 0xf3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+523B "刻" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x1, 0xb0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x81, 0x5, 0x2, 0x0, 0xb0, 0x16, 0x57, 0xc5, + 0x56, 0x2a, 0x40, 0xb0, 0x0, 0xa, 0x30, 0x50, + 0x9, 0x20, 0xb0, 0x0, 0x64, 0x4, 0xb1, 0x9, + 0x20, 0xb0, 0x3, 0xd6, 0x5c, 0x11, 0x9, 0x20, + 0xb0, 0x0, 0x0, 0xa3, 0x6c, 0x9, 0x20, 0xb0, + 0x0, 0x9, 0x31, 0xc1, 0x9, 0x20, 0xb0, 0x2, + 0x81, 0xc, 0x20, 0x9, 0x20, 0xb0, 0x23, 0x1, + 0xa4, 0xa1, 0x1, 0x0, 0xb0, 0x0, 0x49, 0x10, + 0x5a, 0x0, 0x1, 0xa0, 0x16, 0x30, 0x0, 0x3, + 0x0, 0x6d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+5247 "則" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x95, 0x55, 0xa2, 0x0, 0x0, 0xd0, 0x0, 0xb0, + 0x0, 0xb0, 0x1, 0x0, 0xb0, 0x0, 0xc5, 0x55, + 0xc0, 0xd, 0x0, 0xb0, 0x0, 0xb0, 0x0, 0xb0, + 0xb, 0x0, 0xb0, 0x0, 0xc5, 0x55, 0xc0, 0xb, + 0x0, 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0xb, 0x0, + 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0xb, 0x0, 0xb0, + 0x0, 0xc5, 0x55, 0xc0, 0xb, 0x0, 0xb0, 0x0, + 0x53, 0x2, 0x40, 0x8, 0x0, 0xb0, 0x0, 0x4b, + 0x7, 0x50, 0x0, 0x0, 0xb0, 0x0, 0x90, 0x0, + 0xc4, 0x0, 0x0, 0xb0, 0x6, 0x0, 0x0, 0x38, + 0x0, 0x6e, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+524A "削" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0xc2, 0x6, 0x0, 0x0, 0xc0, 0x1b, 0xb, 0x3, + 0xa0, 0x0, 0xb, 0x0, 0x84, 0xb0, 0x70, 0xa, + 0x10, 0xb0, 0x8, 0x5d, 0x65, 0x90, 0xb0, 0xb, + 0x0, 0xb0, 0x0, 0xc, 0xb, 0x0, 0xb0, 0xd, + 0x55, 0x55, 0xc0, 0xb0, 0xb, 0x0, 0xb0, 0x0, + 0xc, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xc0, + 0xb0, 0xb, 0x0, 0xd5, 0x55, 0x5c, 0xc, 0x0, + 0xb0, 0xb, 0x0, 0x0, 0xc0, 0x60, 0xb, 0x0, + 0xb0, 0x1, 0x2c, 0x0, 0x12, 0xa0, 0x1b, 0x0, + 0x3d, 0x70, 0x5, 0xe7, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+524D "前" */ + 0x0, 0x0, 0x10, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x85, 0x0, 0x3e, 0x20, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x91, 0x0, 0x40, 0x6, 0x55, 0x55, + 0x55, 0x65, 0x56, 0x92, 0x0, 0x30, 0x3, 0x10, + 0x0, 0x19, 0x0, 0x0, 0xb5, 0x5b, 0x30, 0xa2, + 0x1a, 0x0, 0x0, 0xb0, 0x9, 0x10, 0xb0, 0x1a, + 0x0, 0x0, 0xb5, 0x5b, 0x10, 0xb0, 0x1a, 0x0, + 0x0, 0xb0, 0x9, 0x10, 0xb0, 0x1a, 0x0, 0x0, + 0xb5, 0x5b, 0x10, 0xb0, 0x1a, 0x0, 0x0, 0xb0, + 0x9, 0x10, 0xb0, 0x1a, 0x0, 0x0, 0xb0, 0x9, + 0x10, 0x11, 0x3a, 0x0, 0x0, 0xb0, 0x6d, 0x0, + 0x6, 0xf5, 0x0, 0x0, 0x10, 0x1, 0x0, 0x0, + 0x10, 0x0, + + /* U+525B "剛" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa, 0x55, + 0x55, 0x5c, 0x20, 0x0, 0xc0, 0xb1, 0x40, 0x61, + 0xb0, 0x10, 0xb, 0xb, 0xa, 0x1a, 0xb, 0xa, + 0x10, 0xb0, 0xb2, 0x66, 0x76, 0xb0, 0xa0, 0xb, + 0xb, 0x12, 0xa1, 0x1b, 0xa, 0x0, 0xb0, 0xb1, + 0x19, 0x22, 0xb0, 0xa0, 0xb, 0xb, 0x55, 0x94, + 0x5b, 0xa, 0x0, 0xb0, 0xb5, 0x49, 0x45, 0xb0, + 0xa0, 0xb, 0xb, 0x68, 0xa8, 0x5b, 0x8, 0x0, + 0xb0, 0xb0, 0x0, 0x11, 0xb0, 0x0, 0xb, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x2, 0xa0, 0xa0, 0x0, + 0x2a, 0xd0, 0x27, 0xe7, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x1, 0x0, + + /* U+5272 "割" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xb0, 0x0, 0x0, 0x0, 0xc0, 0x6, 0x55, + 0x75, 0x5a, 0x21, 0x0, 0xb0, 0x1b, 0x0, 0xb1, + 0x4, 0xb, 0x30, 0xb0, 0x3, 0x55, 0xc5, 0x67, + 0xa, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0xa, + 0x0, 0xb0, 0x1, 0x55, 0xc5, 0x73, 0xa, 0x0, + 0xb0, 0x0, 0x0, 0xb0, 0x4, 0x2a, 0x0, 0xb0, + 0x6, 0x55, 0xd5, 0x55, 0x3b, 0x0, 0xb0, 0x0, + 0x95, 0x65, 0xa1, 0xa, 0x10, 0xb0, 0x0, 0xb0, + 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x0, + 0xb0, 0x0, 0x0, 0xb0, 0x0, 0xd5, 0x55, 0xc0, + 0x0, 0x6c, 0xa0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+5275 "創" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0xd5, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x6, + 0x73, 0xa3, 0x0, 0x0, 0xa0, 0x0, 0x29, 0x45, + 0x1c, 0xb, 0x0, 0xa0, 0x1, 0x80, 0xa, 0x1, + 0xa, 0x0, 0xa0, 0x15, 0x86, 0x55, 0x5a, 0xa, + 0x0, 0xa0, 0x0, 0x86, 0x55, 0x59, 0xa, 0x0, + 0xa0, 0x0, 0x82, 0x0, 0x9, 0xa, 0x0, 0xa0, + 0x0, 0x96, 0x55, 0x58, 0xb, 0x0, 0xa0, 0x0, + 0xb7, 0x55, 0x57, 0x6, 0x0, 0xa0, 0x1, 0xa9, + 0x0, 0xa, 0x0, 0x0, 0xa0, 0x6, 0x39, 0x0, + 0xa, 0x0, 0x0, 0xa0, 0x15, 0x1b, 0x55, 0x5a, + 0x1, 0x7d, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+5283 "劃" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0xa2, 0x2, 0x0, 0x0, 0xc0, 0x0, 0x55, + 0xb5, 0x5c, 0x0, 0x0, 0xa0, 0x6, 0x55, 0xb5, + 0x5c, 0x92, 0x90, 0xa0, 0x0, 0x33, 0xb4, 0x3b, + 0x0, 0xa0, 0xa0, 0x0, 0x22, 0xa2, 0x35, 0x0, + 0xa0, 0xa0, 0x0, 0x55, 0xb5, 0x54, 0x40, 0xa0, + 0xa0, 0x5, 0x75, 0x55, 0x57, 0x51, 0xa0, 0xa0, + 0x0, 0xc5, 0xc5, 0x5c, 0x0, 0xa0, 0xa0, 0x0, + 0xc5, 0xc5, 0x5a, 0x0, 0x60, 0xa0, 0x0, 0xc5, + 0xc5, 0x5a, 0x0, 0x0, 0xa0, 0x0, 0x40, 0x0, + 0x27, 0x20, 0x11, 0xb0, 0x7, 0xb9, 0x75, 0x31, + 0x0, 0x4d, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+529B "力" */ + 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, + 0x0, 0x10, 0x1, 0x75, 0x55, 0xd5, 0x55, 0x5d, + 0x40, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x3, 0x90, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x84, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0x2b, 0x0, 0x0, 0x9, 0x40, 0x0, 0x4, + 0xa0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x67, 0x0, + 0x4, 0x80, 0x0, 0x36, 0x4d, 0x30, 0x5, 0x50, + 0x0, 0x0, 0x4f, 0x80, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, + + /* U+529F "功" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x4, + 0x0, 0xa1, 0x0, 0x0, 0x65, 0xc5, 0x52, 0xa, + 0x0, 0x0, 0x0, 0xa, 0x0, 0x55, 0xc5, 0x5a, + 0x50, 0x0, 0xa0, 0x0, 0xb, 0x0, 0x92, 0x0, + 0xa, 0x0, 0x0, 0xb0, 0xa, 0x10, 0x0, 0xa0, + 0x0, 0x1a, 0x0, 0xb0, 0x0, 0xa, 0x3, 0x25, + 0x60, 0xc, 0x0, 0x26, 0xc6, 0x10, 0xb0, 0x0, + 0xc0, 0x2c, 0x50, 0x0, 0x65, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x47, 0x4, 0x23, 0xb0, 0x0, 0x0, + 0x54, 0x0, 0x18, 0xf4, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x1, 0x0, + + /* U+52A0 "加" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5d, 0x55, + 0x91, 0xb5, 0x55, 0xc0, 0x0, 0xb, 0x0, 0xb0, + 0xb0, 0x0, 0xb0, 0x0, 0xc, 0x0, 0xb0, 0xb0, + 0x0, 0xb0, 0x0, 0xc, 0x0, 0xb0, 0xb0, 0x0, + 0xb0, 0x0, 0xb, 0x0, 0xa0, 0xb0, 0x0, 0xb0, + 0x0, 0x29, 0x1, 0x90, 0xb0, 0x0, 0xb0, 0x0, + 0x64, 0x2, 0x80, 0xb0, 0x0, 0xb0, 0x0, 0xa0, + 0x5, 0x60, 0xb0, 0x0, 0xb0, 0x5, 0x44, 0x7c, + 0x30, 0xc5, 0x55, 0xb0, 0x15, 0x0, 0x66, 0x0, + 0xb0, 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52A8 "动" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x3, 0x65, + 0x5a, 0x50, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x0, 0x10, 0x0, 0x0, 0x0, 0x15, + 0x5c, 0x55, 0xd0, 0x5, 0x57, 0x65, 0x92, 0xb, + 0x0, 0xb0, 0x0, 0xb, 0x60, 0x0, 0x19, 0x0, + 0xb0, 0x0, 0x29, 0x2, 0x0, 0x46, 0x0, 0xb0, + 0x0, 0x80, 0x8, 0x20, 0x82, 0x1, 0xa0, 0x5, + 0x32, 0x36, 0xd0, 0xa0, 0x1, 0xa0, 0xd, 0xb6, + 0x20, 0x96, 0x30, 0x3, 0x90, 0x0, 0x0, 0x0, + 0x36, 0x3, 0x17, 0x60, 0x0, 0x0, 0x4, 0x40, + 0x2, 0xcd, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+52A9 "助" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x30, 0x4, 0x0, 0xe, 0x0, 0x0, 0x0, 0xd5, + 0x5c, 0x20, 0xc, 0x0, 0x0, 0x0, 0xb0, 0xb, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xb0, 0xb, 0x26, + 0x5d, 0x55, 0xc0, 0x0, 0xc5, 0x5c, 0x0, 0xc, + 0x0, 0xb0, 0x0, 0xb0, 0xb, 0x0, 0xc, 0x0, + 0xb0, 0x0, 0xc5, 0x5c, 0x0, 0x2a, 0x0, 0xb0, + 0x0, 0xb0, 0xb, 0x0, 0x56, 0x0, 0xb0, 0x0, + 0xb0, 0xb, 0x0, 0xb1, 0x0, 0xb0, 0x0, 0xb4, + 0x78, 0x46, 0x60, 0x2, 0x90, 0x1d, 0xa4, 0x0, + 0x36, 0x3, 0x59, 0x60, 0x1, 0x0, 0x5, 0x40, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+52AA "努" */ + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x50, 0x1, 0x11, 0x14, 0x0, 0x5, 0x5c, + 0x57, 0x67, 0x44, 0x6d, 0x10, 0x1, 0x28, 0x9, + 0x30, 0x60, 0x93, 0x0, 0x0, 0x92, 0xb, 0x0, + 0x58, 0x80, 0x0, 0x0, 0x16, 0xca, 0x10, 0x2d, + 0x80, 0x0, 0x0, 0x18, 0x44, 0x76, 0x70, 0x5c, + 0x82, 0x14, 0x50, 0x1, 0xa4, 0x0, 0x0, 0x20, + 0x0, 0x35, 0x55, 0xc8, 0x55, 0x75, 0x0, 0x0, + 0x10, 0x1, 0xc0, 0x0, 0x85, 0x0, 0x0, 0x0, + 0x9, 0x50, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x87, + 0x1, 0x31, 0xd0, 0x0, 0x2, 0x57, 0x20, 0x0, + 0x6f, 0x60, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52B3 "劳" */ + 0x0, 0x0, 0x40, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xd, 0x0, 0x0, 0x35, 0x55, 0xc5, + 0x55, 0xc5, 0x6d, 0x20, 0x0, 0xb, 0x0, 0xb, + 0x0, 0x0, 0x2, 0x0, 0x60, 0x0, 0x50, 0x2, + 0x0, 0x95, 0x55, 0x65, 0x55, 0x56, 0xe1, 0x3b, + 0x0, 0xb, 0x40, 0x0, 0x51, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x21, 0x0, 0x4, 0x65, 0x5e, 0x55, + 0x5b, 0x60, 0x0, 0x0, 0x2, 0xb0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0xa4, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x78, 0x1, 0x1, 0xd0, 0x0, 0x3, 0x84, + 0x0, 0x7, 0xf7, 0x0, 0x3, 0x20, 0x0, 0x0, + 0x2, 0x0, 0x0, + + /* U+52C9 "勉" */ + 0x0, 0x4, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x97, + 0x5d, 0x20, 0xa, 0x0, 0x0, 0x2, 0x80, 0x35, + 0x0, 0xa, 0x2, 0x0, 0x7, 0xa5, 0xa5, 0xb5, + 0x5c, 0x5a, 0x40, 0x10, 0xb0, 0xb0, 0xa0, 0xa, + 0x8, 0x10, 0x0, 0xb0, 0xb0, 0xa0, 0xa, 0x8, + 0x10, 0x0, 0xc5, 0xd8, 0xc0, 0x46, 0x9, 0x10, + 0x0, 0x23, 0x98, 0x10, 0x91, 0xa, 0x0, 0x0, + 0x8, 0x48, 0x2, 0x81, 0x1b, 0x0, 0x0, 0x19, + 0x28, 0x7, 0x0, 0xa7, 0x40, 0x0, 0x81, 0x18, + 0x30, 0x0, 0x0, 0x80, 0x6, 0x20, 0xb, 0x88, + 0x88, 0x8a, 0xa0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52D5 "動" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x6b, 0x80, 0xc, 0x10, 0x0, 0x3, 0x4b, + 0x30, 0x0, 0xc, 0x0, 0x0, 0x26, 0x5b, 0x65, + 0xa2, 0xb, 0x0, 0x30, 0x1, 0x9, 0x10, 0x24, + 0x6c, 0x55, 0xd0, 0xb, 0x5b, 0x65, 0xc0, 0xb, + 0x0, 0xb0, 0xa, 0x5b, 0x65, 0xa0, 0xb, 0x0, + 0xa0, 0xa, 0x9, 0x10, 0xa0, 0x19, 0x0, 0xa0, + 0xa, 0x5b, 0x65, 0x90, 0x55, 0x0, 0xa0, 0x0, + 0x9, 0x10, 0x40, 0xa0, 0x2, 0x80, 0x6, 0x5b, + 0x65, 0x52, 0x80, 0x4, 0x60, 0x0, 0x1a, 0x65, + 0x48, 0x3, 0x1a, 0x30, 0x1d, 0x94, 0x0, 0x52, + 0x2, 0xca, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x10, 0x0, + + /* U+52D9 "務" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x44, 0x46, 0x10, 0xd1, 0x0, 0x0, 0x1, 0x20, + 0x2a, 0x45, 0xa5, 0x5d, 0x20, 0x0, 0x19, 0x70, + 0x7, 0x60, 0x38, 0x0, 0x0, 0x1, 0xd0, 0x20, + 0x28, 0xb0, 0x0, 0x5, 0x57, 0x97, 0x70, 0x1a, + 0xb1, 0x0, 0x0, 0xc, 0xa5, 0x14, 0x91, 0x2c, + 0xa4, 0x0, 0x29, 0xa1, 0x63, 0x76, 0x0, 0x40, + 0x0, 0x92, 0xa0, 0x46, 0xc6, 0x5c, 0x30, 0x3, + 0x51, 0xa0, 0x0, 0xb0, 0xb, 0x0, 0x5, 0x1, + 0xa0, 0x5, 0x60, 0xb, 0x0, 0x0, 0x23, 0xa0, + 0x29, 0x0, 0x1b, 0x0, 0x0, 0x4d, 0x63, 0x60, + 0x7, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x10, 0x0, + + /* U+52DD "勝" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x8, + 0x55, 0xb0, 0x81, 0xc1, 0x76, 0x0, 0x9, 0x10, + 0xa0, 0x3a, 0xb2, 0x70, 0x0, 0x9, 0x10, 0xa2, + 0x57, 0xc6, 0x78, 0x0, 0x9, 0x65, 0xa0, 0x12, + 0x80, 0x2, 0x0, 0x9, 0x10, 0xb6, 0x5a, 0x77, + 0x58, 0x50, 0x9, 0x10, 0xa0, 0x2a, 0x25, 0x30, + 0x0, 0x9, 0x65, 0xa1, 0x83, 0xa0, 0x7b, 0x60, + 0xa, 0x0, 0xb6, 0x77, 0xa5, 0x95, 0x30, 0xa, + 0x0, 0xa0, 0x7, 0x20, 0xa0, 0x0, 0x9, 0x0, + 0xa0, 0xa, 0x0, 0xa0, 0x0, 0x15, 0x0, 0xa0, + 0x82, 0x0, 0xb0, 0x0, 0x40, 0x3c, 0x66, 0x20, + 0x5c, 0x80, 0x0, 0x10, 0x1, 0x10, 0x0, 0x2, + 0x0, 0x0, + + /* U+52E4 "勤" */ + 0x0, 0x12, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x38, 0x8, 0x13, 0xa, 0x30, 0x0, 0x6, 0x7a, + 0x5b, 0x67, 0xa, 0x0, 0x0, 0x0, 0x3a, 0x5b, + 0x0, 0xb, 0x0, 0x0, 0x0, 0x22, 0xa2, 0x22, + 0x6c, 0x55, 0xc2, 0x1, 0xb5, 0xc5, 0xb3, 0xb, + 0x0, 0xb0, 0x1, 0xa0, 0xa0, 0x91, 0xb, 0x0, + 0xb0, 0x1, 0xa5, 0xc5, 0x91, 0xb, 0x0, 0xb0, + 0x2, 0x65, 0xc5, 0x86, 0xa, 0x0, 0xb0, 0x0, + 0x0, 0xa0, 0x40, 0x47, 0x0, 0xb0, 0x0, 0x65, + 0xc5, 0x52, 0x91, 0x0, 0xc0, 0x0, 0x2, 0xb5, + 0x47, 0x63, 0x36, 0xa0, 0xb, 0xa6, 0x30, 0x35, + 0x0, 0x7d, 0x10, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+52F5 "勵" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x6, + 0x55, 0x55, 0x5a, 0xb, 0x20, 0x0, 0x9, 0x0, + 0x60, 0x60, 0xa, 0x0, 0x0, 0x9, 0x56, 0xa5, + 0xb7, 0xa, 0x0, 0x10, 0x8, 0x0, 0x30, 0x42, + 0x6c, 0x55, 0xb2, 0x8, 0xb, 0x59, 0x75, 0xa, + 0x0, 0xa0, 0x9, 0xc, 0x5a, 0x74, 0xa, 0x0, + 0xa0, 0x9, 0xc, 0x5a, 0x74, 0xa, 0x0, 0xa0, + 0x9, 0x2, 0x17, 0x11, 0x9, 0x0, 0xa0, 0x8, + 0x77, 0x5a, 0x5a, 0x46, 0x0, 0xa0, 0x7, 0x74, + 0x3a, 0x59, 0x81, 0x0, 0xa0, 0x32, 0x75, 0x61, + 0x59, 0x81, 0x14, 0x80, 0x20, 0x73, 0x0, 0x8b, + 0x10, 0x7d, 0x10, 0x0, 0x10, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+5305 "包" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x0, 0x30, 0x0, 0x0, 0xc, 0x55, + 0x55, 0x55, 0xc4, 0x0, 0x0, 0x84, 0x0, 0x1, + 0x0, 0xa1, 0x0, 0x4, 0x6c, 0x55, 0x5c, 0x30, + 0xb0, 0x0, 0x25, 0xb, 0x0, 0xb, 0x0, 0xb0, + 0x0, 0x0, 0xb, 0x0, 0xb, 0x0, 0xc0, 0x0, + 0x0, 0xb, 0x55, 0x5b, 0x20, 0xc0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x4a, 0xa0, 0x30, 0x0, 0xb, + 0x0, 0x0, 0x3, 0x0, 0x60, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x1, 0xc0, 0x0, 0x5, 0xba, 0xaa, + 0xaa, 0xbd, 0xb1, + + /* U+5316 "化" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x6, + 0x80, 0xa, 0x10, 0x0, 0x0, 0x0, 0xc, 0x10, + 0xa, 0x10, 0x12, 0x0, 0x0, 0x4b, 0x0, 0xa, + 0x10, 0xa8, 0x0, 0x0, 0xbd, 0x0, 0xa, 0x17, + 0x80, 0x0, 0x4, 0x4c, 0x0, 0xa, 0x79, 0x0, + 0x0, 0x6, 0xc, 0x0, 0xb, 0x80, 0x0, 0x0, + 0x10, 0xc, 0x0, 0x8d, 0x10, 0x0, 0x0, 0x0, + 0xc, 0x26, 0x1a, 0x10, 0x0, 0x30, 0x0, 0xc, + 0x10, 0xa, 0x10, 0x0, 0x60, 0x0, 0xc, 0x0, + 0xa, 0x20, 0x1, 0xb0, 0x0, 0xd, 0x0, 0x6, + 0xdb, 0xbc, 0xa0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5317 "北" */ + 0x0, 0x0, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0x20, 0x3, 0x55, 0x5c, 0x0, + 0xc0, 0xb, 0xa0, 0x0, 0x0, 0xc, 0x0, 0xc3, + 0x83, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0xc0, 0x0, 0x40, 0x1, 0x58, + 0x5c, 0x0, 0xc0, 0x0, 0x60, 0xa, 0x60, 0xc, + 0x0, 0xc0, 0x0, 0xb1, 0x0, 0x0, 0xc, 0x0, + 0x9c, 0xbc, 0xd3, 0x0, 0x0, 0x4, 0x0, 0x0, + 0x0, 0x0, + + /* U+533B "医" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x55, 0x55, 0x55, 0x55, 0x7c, 0x10, 0xb, 0x10, + 0xa, 0x10, 0x0, 0x0, 0x0, 0xb, 0x10, 0x1b, + 0x0, 0x0, 0x20, 0x0, 0xb, 0x10, 0x78, 0x59, + 0x57, 0x80, 0x0, 0xb, 0x10, 0x80, 0xb, 0x0, + 0x0, 0x0, 0xb, 0x14, 0x0, 0x1a, 0x0, 0x3, + 0x0, 0xb, 0x26, 0x55, 0x7b, 0x55, 0x58, 0x30, + 0xb, 0x10, 0x0, 0x79, 0x10, 0x0, 0x0, 0xb, + 0x10, 0x2, 0xb0, 0x7a, 0x30, 0x0, 0xb, 0x10, + 0x39, 0x0, 0x3, 0xe3, 0x0, 0xb, 0x15, 0x40, + 0x0, 0x0, 0x36, 0x10, 0xb, 0x55, 0x55, 0x55, + 0x55, 0x58, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5340 "區" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0x55, + 0x55, 0x55, 0x58, 0x80, 0x92, 0x1, 0x0, 0x0, + 0x30, 0x0, 0x92, 0x5, 0x95, 0x55, 0xc0, 0x0, + 0x92, 0x5, 0x60, 0x0, 0xa0, 0x0, 0x92, 0x5, + 0x95, 0x55, 0xa0, 0x0, 0x92, 0x1, 0x10, 0x0, + 0x20, 0x0, 0x92, 0x85, 0x58, 0x85, 0x5a, 0x10, + 0x92, 0xa0, 0x19, 0xa0, 0xa, 0x0, 0x92, 0xa0, + 0x19, 0xa0, 0xa, 0x0, 0x92, 0xb5, 0x69, 0xa5, + 0x5c, 0x0, 0x92, 0x30, 0x1, 0x20, 0x1, 0x0, + 0xa6, 0x55, 0x55, 0x55, 0x55, 0xe3, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+5341 "十" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, + 0x0, 0x0, 0x0, 0x25, 0x55, 0x55, 0xc6, 0x55, + 0x5a, 0x90, 0x1, 0x0, 0x0, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5343 "千" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x25, 0x9e, 0xa0, 0x0, 0x0, 0x45, + 0x67, 0xd6, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x5, 0x40, 0x36, 0x55, 0x55, 0xc7, 0x55, 0x55, + 0x50, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+5348 "午" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x80, 0x0, 0x0, 0x62, 0x0, 0x0, 0xb, 0x55, + 0x6b, 0x55, 0x54, 0x0, 0x0, 0x73, 0x0, 0x2a, + 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, 0x2a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, + 0x40, 0x6, 0x55, 0x55, 0x6c, 0x55, 0x56, 0x81, + 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, + 0x0, 0x0, + + /* U+534A "半" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x20, 0x0, 0x0, 0x26, + 0x0, 0xc0, 0x5, 0xd1, 0x0, 0x0, 0x6, 0xb0, + 0xc0, 0xa, 0x10, 0x0, 0x0, 0x0, 0xb0, 0xc0, + 0x60, 0x0, 0x0, 0x2, 0x55, 0x55, 0xd5, 0x55, + 0x8a, 0x0, 0x0, 0x10, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x16, 0x55, 0x55, 0xd5, 0x55, 0x5a, 0x90, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+5352 "卒" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3a, 0x0, 0x1, 0x0, 0x0, 0x65, + 0x55, 0x59, 0x55, 0x6b, 0x20, 0x0, 0x0, 0x86, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x6, 0x6a, 0x11, 0xa6, + 0x60, 0x0, 0x0, 0x18, 0x5, 0x78, 0x10, 0xa6, + 0x0, 0x0, 0x50, 0x0, 0x5a, 0x0, 0x13, 0x0, + 0x4, 0x55, 0x55, 0x5d, 0x55, 0x56, 0xd2, 0x1, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+5354 "協" */ + 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa1, + 0x3, 0x67, 0xa5, 0x5b, 0x20, 0x0, 0xa1, 0x0, + 0x9, 0x20, 0xa, 0x0, 0x26, 0xc5, 0x91, 0x56, + 0x0, 0x37, 0x0, 0x0, 0xa1, 0x15, 0x40, 0x18, + 0xc1, 0x0, 0x0, 0xa1, 0x24, 0x30, 0x0, 0x60, + 0x0, 0x0, 0xa1, 0x6a, 0x96, 0x75, 0xd5, 0x90, + 0x0, 0xa1, 0x9, 0x14, 0x50, 0xa0, 0x90, 0x0, + 0xa1, 0xa, 0x6, 0x32, 0x90, 0xa0, 0x0, 0xa1, + 0x27, 0x8, 0x17, 0x40, 0xa0, 0x0, 0xa1, 0x72, + 0x3b, 0x9, 0x0, 0xa0, 0x0, 0xa5, 0x30, 0x76, + 0x70, 0x5b, 0x60, 0x0, 0x21, 0x0, 0x2, 0x0, + 0x3, 0x0, + + /* U+5357 "南" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x5, 0x55, + 0x55, 0xc6, 0x55, 0x5a, 0xc0, 0x1, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x75, 0x55, 0xd5, + 0x55, 0x59, 0x10, 0x0, 0xb0, 0x22, 0x0, 0x91, + 0xb, 0x0, 0x0, 0xb0, 0xc, 0x14, 0x80, 0xb, + 0x0, 0x0, 0xb0, 0x58, 0x5a, 0x5b, 0x1b, 0x0, + 0x0, 0xb0, 0x10, 0xa1, 0x0, 0xb, 0x0, 0x0, + 0xb4, 0x65, 0xc5, 0x59, 0x4b, 0x0, 0x0, 0xb0, + 0x0, 0xa1, 0x0, 0xb, 0x0, 0x0, 0xb0, 0x0, + 0xa1, 0x13, 0x2c, 0x0, 0x0, 0xb0, 0x0, 0x70, + 0x4, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+5358 "単" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x50, 0xa1, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0xb5, 0x68, 0xa, 0x20, 0x0, 0x0, 0x2, 0x23, + 0x12, 0x43, 0x30, 0x0, 0x0, 0xc, 0x55, 0xb6, + 0x55, 0xc2, 0x0, 0x0, 0xb, 0x0, 0x91, 0x0, + 0xb0, 0x0, 0x0, 0xc, 0x55, 0xb6, 0x55, 0xc0, + 0x0, 0x0, 0xb, 0x0, 0x91, 0x0, 0xb0, 0x0, + 0x0, 0xb, 0x55, 0xb6, 0x55, 0xa0, 0x0, 0x4, + 0x55, 0x55, 0xb6, 0x55, 0x59, 0xc0, 0x1, 0x0, + 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5371 "危" */ + 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb5, 0x0, 0x3, 0x0, 0x0, 0x0, 0x5, + 0xa5, 0x55, 0xab, 0x0, 0x0, 0x0, 0x2a, 0x0, + 0x1, 0x80, 0x0, 0x0, 0x2, 0x89, 0x55, 0x58, + 0x55, 0x5a, 0x60, 0x3, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x9, 0x65, 0x55, 0xc0, + 0x0, 0x0, 0xc, 0x9, 0x20, 0x0, 0xa0, 0x0, + 0x0, 0xc, 0x9, 0x20, 0x0, 0xa0, 0x0, 0x0, + 0xb, 0x9, 0x20, 0x57, 0xa0, 0x20, 0x0, 0x47, + 0x9, 0x20, 0x7, 0x20, 0x60, 0x0, 0xa1, 0x9, + 0x20, 0x0, 0x0, 0xb0, 0x5, 0x30, 0x4, 0xca, + 0xaa, 0xab, 0xb1, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5373 "即" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, + 0xa4, 0x7, 0x55, 0x93, 0xb, 0x0, 0x92, 0xb, + 0x0, 0xa1, 0xb, 0x0, 0x92, 0xb, 0x0, 0xa1, + 0xc, 0x55, 0xb2, 0xb, 0x0, 0xa1, 0xb, 0x0, + 0x92, 0xb, 0x0, 0xa1, 0xc, 0x55, 0xb2, 0xb, + 0x0, 0xa1, 0xb, 0x1, 0x30, 0xb, 0x0, 0xa1, + 0xb, 0x5, 0x60, 0xb, 0x0, 0xa1, 0xb, 0x0, + 0xc7, 0xb, 0x27, 0xc0, 0x1d, 0x86, 0x1b, 0xb, + 0x3, 0x50, 0x6, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, 0x0, + + /* U+537B "卻" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4a, 0x4, 0x80, 0x20, 0x0, 0x20, 0x1, 0xa1, + 0x0, 0x79, 0xc5, 0x55, 0xd0, 0x15, 0x1, 0x90, + 0x4, 0xb0, 0x0, 0xb0, 0x0, 0x9, 0x85, 0x0, + 0xb0, 0x0, 0xb0, 0x0, 0x47, 0x5, 0xb0, 0xb0, + 0x0, 0xb0, 0x2, 0x80, 0x0, 0x77, 0xb0, 0x0, + 0xb0, 0x16, 0x75, 0x55, 0xa2, 0xb0, 0x0, 0xb0, + 0x10, 0xb0, 0x0, 0xb0, 0xb0, 0x0, 0xb0, 0x0, + 0xb0, 0x0, 0xb0, 0xb1, 0x54, 0xb0, 0x0, 0xb0, + 0x0, 0xb0, 0xb0, 0x1a, 0x40, 0x0, 0xb5, 0x55, + 0xb0, 0xb0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x40, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+539A "厚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x95, 0x55, 0x55, 0x55, 0x5a, 0x50, 0x0, 0xa1, + 0x7, 0x55, 0x55, 0x80, 0x0, 0x0, 0xa1, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0xa1, 0xc, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0xa1, 0xc, 0x55, 0x55, + 0xc0, 0x0, 0x0, 0xa0, 0x6, 0x0, 0x0, 0x60, + 0x0, 0x0, 0xb0, 0x56, 0x55, 0x57, 0xd2, 0x0, + 0x0, 0xb0, 0x0, 0x1, 0x75, 0x0, 0x0, 0x0, + 0xb4, 0x65, 0x55, 0xc5, 0x58, 0x80, 0x3, 0x70, + 0x0, 0x1, 0xa0, 0x0, 0x0, 0x7, 0x10, 0x0, + 0x11, 0xa0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x4e, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+539F "原" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x9, + 0x55, 0x55, 0x65, 0x58, 0x90, 0x0, 0xb1, 0x0, + 0x9, 0x30, 0x0, 0x0, 0xb, 0x11, 0x75, 0x95, + 0x59, 0x20, 0x0, 0xb1, 0x1a, 0x0, 0x0, 0x91, + 0x0, 0xb, 0x11, 0xc5, 0x55, 0x5b, 0x10, 0x0, + 0xb0, 0x1a, 0x0, 0x0, 0x91, 0x0, 0xb, 0x1, + 0xc5, 0x57, 0x5b, 0x20, 0x0, 0xb0, 0x3, 0x1, + 0xa0, 0x30, 0x0, 0xb, 0x0, 0x7a, 0x1a, 0x35, + 0x0, 0x2, 0x80, 0x5a, 0x1, 0xa0, 0x4c, 0x30, + 0x71, 0x65, 0x3, 0x5a, 0x0, 0x3c, 0x14, 0x11, + 0x0, 0x1b, 0x50, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53B3 "厳" */ + 0x0, 0x1, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, + 0x2b, 0x4, 0x80, 0x67, 0x0, 0x0, 0x10, 0x80, + 0x8, 0x15, 0x6, 0x0, 0xc, 0x55, 0x55, 0x56, + 0x75, 0x73, 0x0, 0xc1, 0x77, 0x80, 0x59, 0x0, + 0x0, 0xc, 0x0, 0x72, 0x39, 0x10, 0x60, 0x0, + 0xc3, 0xc5, 0xc5, 0xc5, 0x99, 0x10, 0xc, 0xa, + 0x5c, 0x56, 0x8, 0x30, 0x0, 0xb0, 0xa0, 0xa0, + 0x33, 0xb0, 0x0, 0xa, 0xa, 0x5c, 0x0, 0x99, + 0x0, 0x2, 0x70, 0xb4, 0xc5, 0x1b, 0x60, 0x0, + 0x61, 0xa8, 0x3a, 0x5, 0x6b, 0x60, 0x6, 0x0, + 0x0, 0x94, 0x30, 0xb, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53BB "去" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, + 0x8, 0x0, 0x0, 0x55, 0x55, 0xc7, 0x55, 0x52, + 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x8, 0x21, 0x65, 0x55, + 0x5e, 0x65, 0x55, 0x53, 0x0, 0x0, 0x7, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x90, 0x4, 0x10, + 0x0, 0x0, 0x2, 0x80, 0x0, 0xa, 0x50, 0x0, + 0x6, 0xc6, 0x66, 0x66, 0x5e, 0x60, 0x0, 0x49, + 0x53, 0x10, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53C2 "参" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x73, 0x0, 0x28, 0x50, 0x0, 0x0, 0x4e, 0x88, + 0xa5, 0x54, 0xb6, 0x0, 0x0, 0x0, 0x8, 0x50, + 0x0, 0x3, 0x50, 0x5, 0x55, 0x7c, 0x55, 0x85, + 0x55, 0x60, 0x0, 0x1, 0xa1, 0x48, 0x47, 0x0, + 0x0, 0x0, 0x28, 0x5, 0xb2, 0x13, 0xb8, 0x30, + 0x5, 0x41, 0x75, 0x5, 0xd2, 0x6, 0x81, 0x0, + 0x34, 0x1, 0x87, 0x1, 0x80, 0x0, 0x0, 0x3, + 0x66, 0x10, 0x5c, 0x60, 0x0, 0x0, 0x22, 0x1, + 0x6a, 0x60, 0x0, 0x0, 0x1, 0x46, 0x68, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53C3 "參" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x80, 0x51, 0x0, 0x0, 0x0, 0x1, + 0xa6, 0x54, 0x5d, 0x20, 0x0, 0x0, 0x6, 0x52, + 0x0, 0x8, 0x20, 0x0, 0x0, 0x66, 0x11, 0x0, + 0x86, 0x6, 0x0, 0x4, 0xb6, 0x49, 0xc8, 0x61, + 0x8, 0x40, 0x0, 0x0, 0xa, 0x66, 0x20, 0x1, + 0x0, 0x0, 0x4, 0x92, 0x3, 0x6a, 0x62, 0x10, + 0x4, 0x64, 0x3, 0xb8, 0x1, 0x8d, 0x91, 0x0, + 0x5, 0x75, 0x4, 0xc1, 0x0, 0x0, 0x0, 0x30, + 0x5, 0x97, 0x13, 0x10, 0x0, 0x0, 0x35, 0x52, + 0x4, 0xab, 0x60, 0x0, 0x1, 0x34, 0x55, 0x64, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53C8 "又" */ + 0x0, 0x45, 0x55, 0x55, 0x55, 0x91, 0x0, 0x0, + 0x10, 0x40, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, + 0x50, 0x0, 0x5, 0x70, 0x0, 0x0, 0x0, 0x50, + 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x15, 0x0, + 0x29, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x84, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8c, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xbb, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x20, 0xa9, 0x10, 0x0, 0x0, 0x6, + 0x70, 0x0, 0x6, 0xea, 0x51, 0x4, 0x51, 0x0, + 0x0, 0x0, 0x18, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53CA "及" */ + 0x0, 0x25, 0x56, 0x55, 0x59, 0x40, 0x0, 0x0, + 0x0, 0xc, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, 0x68, 0x20, + 0xb5, 0x7c, 0x0, 0x0, 0x0, 0xa1, 0x60, 0x0, + 0x94, 0x0, 0x0, 0x0, 0xb0, 0x61, 0x2, 0xb0, + 0x0, 0x0, 0x6, 0x50, 0xa, 0xb, 0x20, 0x0, + 0x0, 0xb, 0x0, 0x5, 0xd5, 0x0, 0x0, 0x0, + 0x83, 0x0, 0x8, 0xb7, 0x0, 0x0, 0x4, 0x40, + 0x4, 0x93, 0x8, 0xc5, 0x0, 0x23, 0x15, 0x63, + 0x0, 0x0, 0x3b, 0xa0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53CB "友" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x2, 0x30, 0x6, 0x55, 0x5e, + 0x55, 0x55, 0x58, 0x80, 0x0, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, + 0x40, 0x0, 0x0, 0x0, 0xa7, 0x75, 0x57, 0xd0, + 0x0, 0x0, 0x1, 0xc0, 0x60, 0x9, 0x50, 0x0, + 0x0, 0x6, 0x60, 0x53, 0x1c, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x9, 0xb4, 0x0, 0x0, 0x0, 0x74, + 0x0, 0x9, 0xe4, 0x0, 0x0, 0x2, 0x70, 0x1, + 0x96, 0x1a, 0xa4, 0x0, 0x6, 0x2, 0x66, 0x0, + 0x0, 0x5d, 0xb1, 0x10, 0x11, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53CD "反" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x25, 0x8b, 0xe9, 0x0, 0x0, 0x1c, + 0x55, 0x43, 0x10, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0xc, 0x58, 0x55, 0x55, + 0xaa, 0x0, 0x0, 0x1b, 0x5, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x2a, 0x0, 0x70, 0x7, 0x80, 0x0, + 0x0, 0x38, 0x0, 0x64, 0x2c, 0x0, 0x0, 0x0, + 0x74, 0x0, 0x9, 0xc2, 0x0, 0x0, 0x0, 0xa0, + 0x0, 0x1b, 0xc6, 0x0, 0x0, 0x4, 0x50, 0x7, + 0x81, 0x9, 0xd6, 0x10, 0x6, 0x15, 0x61, 0x0, + 0x0, 0x3c, 0xd2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53D6 "取" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x75, 0x57, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xb, 0x12, 0x22, 0x27, 0x0, 0x0, 0xb0, 0xb, + 0x16, 0x33, 0x3e, 0x10, 0x0, 0xc5, 0x5c, 0x1, + 0x30, 0x3a, 0x0, 0x0, 0xb0, 0xb, 0x0, 0x60, + 0x76, 0x0, 0x0, 0xc5, 0x5c, 0x0, 0x70, 0xc1, + 0x0, 0x0, 0xb0, 0xb, 0x0, 0x64, 0xa0, 0x0, + 0x0, 0xb0, 0xb, 0x52, 0x1e, 0x30, 0x0, 0x4, + 0xd9, 0x8d, 0x0, 0x2e, 0x40, 0x0, 0xa, 0x40, + 0xb, 0x0, 0xa1, 0xc5, 0x0, 0x0, 0x0, 0xb, + 0x8, 0x20, 0x1c, 0xb1, 0x0, 0x0, 0xa, 0x51, + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53D7 "受" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x13, 0x57, 0xac, 0xd5, 0x0, 0x0, 0x45, + 0x44, 0x31, 0x0, 0x80, 0x0, 0x0, 0x9, 0x10, + 0xb1, 0x6, 0x80, 0x0, 0x0, 0x27, 0x70, 0x86, + 0x9, 0x0, 0x10, 0x1, 0xa6, 0x55, 0x65, 0x56, + 0x58, 0xd0, 0x9, 0x60, 0x0, 0x0, 0x1, 0x7, + 0x10, 0x2, 0x5, 0x75, 0x55, 0x5f, 0x31, 0x0, + 0x0, 0x0, 0x15, 0x0, 0x87, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x45, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, + 0x56, 0xb7, 0x20, 0x0, 0x2, 0x57, 0x50, 0x0, + 0x6, 0xcf, 0xb1, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53E3 "口" */ + 0x18, 0x55, 0x55, 0x55, 0x5a, 0x1, 0xb0, 0x0, + 0x0, 0x0, 0xc0, 0xb, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0xc0, 0xb, 0x0, + 0x0, 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0xc0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x0, 0xb0, + 0x0, 0x0, 0x0, 0xc0, 0x1c, 0x55, 0x55, 0x55, + 0x5c, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53E4 "古" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, + 0xc6, 0x55, 0x59, 0x90, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x55, 0x85, 0x55, 0xd2, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, + 0x55, 0x55, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53E5 "句" */ + 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x95, 0x55, 0x55, 0x55, 0x90, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0x2, 0xa0, 0x0, 0xa0, 0x0, 0x0, + 0x0, 0x1, 0xa0, 0x7, 0x17, 0x55, 0x55, 0x90, + 0x1, 0xa0, 0x10, 0xc, 0x0, 0x2, 0xa0, 0x2, + 0xa0, 0x0, 0xc, 0x0, 0x2, 0xa0, 0x2, 0xa0, + 0x0, 0xc, 0x0, 0x2, 0xa0, 0x2, 0x90, 0x0, + 0xd, 0x55, 0x56, 0x90, 0x3, 0x90, 0x0, 0x4, + 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x20, 0x8, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40, 0x0, + + /* U+53E6 "另" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xb5, 0x55, 0x55, 0x5e, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xb, 0x55, 0x55, 0x55, 0xc0, + 0x0, 0x0, 0x90, 0xa, 0x10, 0x7, 0x0, 0x0, + 0x0, 0x1, 0xc0, 0x0, 0x3, 0x0, 0x26, 0x55, + 0x7c, 0x55, 0x56, 0xc0, 0x0, 0x0, 0x5, 0x70, + 0x0, 0x29, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x3, + 0x90, 0x0, 0x0, 0x29, 0x0, 0x0, 0x48, 0x0, + 0x0, 0x49, 0x0, 0x3, 0x18, 0x60, 0x3, 0x64, + 0x0, 0x0, 0x2b, 0xe1, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53EA "只" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, + 0x55, 0x55, 0x5d, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xc5, 0x55, 0x55, + 0x5c, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x9, 0x0, + 0x0, 0x2, 0xd1, 0x5, 0x10, 0x0, 0x0, 0xc, + 0x40, 0x0, 0xa4, 0x0, 0x0, 0x76, 0x0, 0x0, + 0x1e, 0x50, 0x5, 0x60, 0x0, 0x0, 0x5, 0xe0, + 0x44, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+53EB "叫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc2, 0x27, 0x55, 0xa0, 0x29, + 0x0, 0xb0, 0x2a, 0x0, 0xc0, 0x2a, 0x0, 0xb0, + 0x2a, 0x0, 0xc0, 0x2a, 0x0, 0xb0, 0x2a, 0x0, + 0xc0, 0x2a, 0x0, 0xb0, 0x2a, 0x0, 0xc0, 0x2a, + 0x0, 0xb0, 0x2a, 0x0, 0xc0, 0x2a, 0x2, 0xc0, + 0x2b, 0x55, 0xc0, 0x3d, 0x83, 0xb0, 0x2a, 0x0, + 0xc0, 0x5, 0x0, 0xb0, 0x25, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+53EF "可" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90, 0x6, + 0x55, 0x55, 0x55, 0x55, 0xd5, 0x52, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x18, 0x55, + 0x5a, 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0x0, 0x1a, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0x0, 0x1a, 0x0, 0xc, 0x0, 0xc0, + 0x0, 0x0, 0x1c, 0x55, 0x5c, 0x0, 0xc0, 0x0, + 0x0, 0x2a, 0x0, 0xa, 0x0, 0xc0, 0x0, 0x0, + 0x13, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x54, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53F0 "台" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x30, 0x0, 0x0, 0x0, 0x1, 0xc2, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x60, 0x0, + 0x0, 0x92, 0x0, 0x0, 0x1b, 0x50, 0x2d, 0x87, + 0x77, 0x76, 0x57, 0xe5, 0xa, 0x74, 0x10, 0x0, + 0x0, 0x45, 0x0, 0x30, 0x0, 0x0, 0x5, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x5d, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x1, 0x0, + + /* U+53F2 "史" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0xc, 0x55, 0x5d, 0x55, + 0x5d, 0x20, 0x0, 0xd0, 0x0, 0xc0, 0x0, 0xc0, + 0x0, 0xd, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, + 0xe5, 0x55, 0xd5, 0x55, 0xd0, 0x0, 0x6, 0x10, + 0xb, 0x0, 0x4, 0x0, 0x0, 0x3, 0x20, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x77, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x45, 0xca, 0x63, 0x20, 0x4, 0x87, + 0x10, 0x0, 0x49, 0xcc, 0x23, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53F3 "右" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x80, 0x0, 0x3, 0x1, 0x65, 0x55, 0xb7, 0x55, + 0x55, 0x96, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xc0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x9c, + 0x65, 0x55, 0x5d, 0x20, 0x0, 0x54, 0xa2, 0x0, + 0x0, 0xc0, 0x0, 0x35, 0xa, 0x20, 0x0, 0xc, + 0x0, 0x23, 0x0, 0xa2, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0xa, 0x65, 0x55, 0x5d, 0x0, 0x0, 0x0, + 0x81, 0x0, 0x0, 0x90, 0x0, + + /* U+53F7 "号" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xb5, 0x55, 0x55, 0xc3, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xb, 0x10, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0xb, 0x55, 0x55, 0x5c, 0x10, + 0x0, 0x0, 0x40, 0x0, 0x0, 0x10, 0x50, 0x5, + 0x55, 0x99, 0x55, 0x55, 0x56, 0x30, 0x0, 0xb, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd5, 0x55, + 0x59, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x84, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, + 0x0, 0x0, 0x3, 0x2, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x0, + + /* U+53F8 "司" */ + 0x2, 0x65, 0x55, 0x55, 0x55, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x1, + 0x20, 0xc0, 0x35, 0x55, 0x55, 0x57, 0x70, 0xc0, + 0x0, 0x10, 0x0, 0x20, 0x0, 0xc0, 0x0, 0xd5, + 0x55, 0xd4, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xb0, + 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xb0, 0x0, 0xc0, + 0x0, 0xd5, 0x55, 0xd1, 0x0, 0xc0, 0x0, 0x80, + 0x0, 0x50, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x21, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+5403 "吃" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x0, 0x0, 0x42, 0x26, 0x0, + 0xc0, 0x0, 0x0, 0xd, 0x33, 0xd0, 0x69, 0x55, + 0x58, 0x80, 0xc0, 0xc, 0x9, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc5, 0x10, 0x0, 0x40, 0x0, 0xc0, + 0xc, 0x15, 0x55, 0x9c, 0x10, 0xc, 0x0, 0xc0, + 0x0, 0x2c, 0x10, 0x0, 0xc5, 0x5d, 0x0, 0xc, + 0x20, 0x0, 0xd, 0x0, 0xb0, 0xa, 0x30, 0x0, + 0x30, 0x50, 0x0, 0x7, 0x70, 0x0, 0x6, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x1, 0xa0, 0x0, 0x0, + 0x8, 0xba, 0xaa, 0xcc, 0x0, + + /* U+5404 "各" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, + 0xc7, 0x55, 0x6e, 0x20, 0x0, 0x0, 0x7, 0x56, + 0x0, 0x96, 0x0, 0x0, 0x0, 0x44, 0x4, 0x53, + 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x9c, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xa8, 0xa3, 0x0, + 0x0, 0x0, 0x0, 0x86, 0x0, 0x3b, 0xd8, 0x51, + 0x0, 0x58, 0xb5, 0x55, 0x5c, 0x48, 0x60, 0x4, + 0x1, 0xa0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, + 0xa0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, 0xa0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x2, 0xc5, 0x55, + 0x5d, 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x3, + 0x0, 0x0, + + /* U+5408 "合" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x2, 0x90, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, + 0x4b, 0x20, 0x0, 0x0, 0x68, 0x0, 0x0, 0x17, + 0xda, 0x50, 0x26, 0x24, 0x55, 0x55, 0x56, 0x7, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x55, 0x55, 0x5c, 0x20, 0x0, 0x0, + 0xa, 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, + 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, 0x65, + 0x55, 0x5d, 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, + 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+540C "同" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, + 0x55, 0x55, 0x55, 0xa3, 0xc, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0xc, 0x0, 0x0, 0x0, 0x61, 0xa2, + 0xc, 0x6, 0x55, 0x55, 0x52, 0xa2, 0xc, 0x0, + 0x10, 0x0, 0x30, 0xa2, 0xc, 0x1, 0xc5, 0x55, + 0xc0, 0xa2, 0xc, 0x0, 0xa0, 0x0, 0xb0, 0xa2, + 0xc, 0x0, 0xa0, 0x0, 0xb0, 0xa2, 0xc, 0x1, + 0xc5, 0x55, 0xb0, 0xa2, 0xc, 0x0, 0x20, 0x0, + 0x10, 0xa2, 0xc, 0x0, 0x0, 0x0, 0x20, 0xc1, + 0xd, 0x0, 0x0, 0x0, 0x4c, 0xd0, 0x2, 0x0, + 0x0, 0x0, 0x1, 0x0, + + /* U+540D "名" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x75, 0x55, 0x78, 0x0, 0x0, 0x7, 0x50, 0x0, + 0xc, 0x40, 0x0, 0x4, 0xc2, 0x0, 0x9, 0x70, + 0x0, 0x3, 0x60, 0xd3, 0x9, 0x80, 0x0, 0x0, + 0x20, 0x3, 0x1a, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x50, 0x0, 0x10, 0x0, 0x0, 0x7e, 0x65, + 0x55, 0x5d, 0x20, 0x15, 0x72, 0xc0, 0x0, 0x0, + 0xc0, 0x2, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xd5, 0x55, 0x55, 0xd0, 0x0, 0x0, + 0x9, 0x0, 0x0, 0x7, 0x0, + + /* U+5411 "向" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x0, 0x0, 0x10, 0x5, 0x20, 0x0, 0x2, + 0xd, 0x55, 0x65, 0x55, 0x55, 0xd2, 0xc0, 0x0, + 0x0, 0x0, 0xc, 0xc, 0x1, 0x20, 0x4, 0x0, + 0xc0, 0xc0, 0x1c, 0x55, 0xc3, 0xc, 0xc, 0x1, + 0xa0, 0xb, 0x10, 0xc0, 0xc0, 0x1a, 0x0, 0xb1, + 0xc, 0xc, 0x2, 0xc5, 0x5c, 0x10, 0xc0, 0xc0, + 0x13, 0x0, 0x10, 0xc, 0xc, 0x0, 0x0, 0x0, + 0x22, 0xd0, 0xc0, 0x0, 0x0, 0x3, 0xbb, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5426 "否" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, + 0x55, 0x56, 0x55, 0x55, 0xd4, 0x0, 0x0, 0x3, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xbd, 0x12, + 0x0, 0x0, 0x0, 0x1, 0xb2, 0xc0, 0x27, 0x60, + 0x0, 0x3, 0xa1, 0xc, 0x0, 0x4, 0xd4, 0x5, + 0x50, 0x0, 0xd0, 0x0, 0x2, 0xa0, 0x0, 0x30, + 0x4, 0x0, 0x5, 0x0, 0x0, 0xc, 0x65, 0x55, + 0x55, 0xe0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0xd, + 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0xb6, 0x55, 0x55, 0x5d, 0x0, 0x0, 0xc, + 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, 0x0, + + /* U+5427 "吧" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x30, 0x7, 0x55, + 0x90, 0xd5, 0xc5, 0x6d, 0x0, 0xc0, 0x1b, 0xc, + 0xc, 0x1, 0xb0, 0xc, 0x1, 0xb0, 0xc0, 0xc0, + 0x1b, 0x0, 0xc0, 0x1b, 0xc, 0xc, 0x1, 0xb0, + 0xc, 0x1, 0xb0, 0xd5, 0xd5, 0x6b, 0x0, 0xc0, + 0x1b, 0xc, 0x0, 0x1, 0x70, 0xc, 0x56, 0xb0, + 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x1b, 0xc, 0x0, + 0x0, 0x1, 0xc, 0x0, 0x50, 0xc0, 0x0, 0x0, + 0x60, 0x0, 0x0, 0xc, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x0, 0xab, 0xaa, 0xab, 0xc0, + + /* U+5440 "呀" */ + 0x0, 0x0, 0x2, 0x22, 0x22, 0x65, 0x9, 0x55, + 0xb2, 0x42, 0x22, 0xc2, 0x20, 0xc0, 0xc, 0x6, + 0x90, 0xc, 0x0, 0xc, 0x0, 0xc0, 0xb3, 0x0, + 0xc0, 0x0, 0xc0, 0xc, 0x1c, 0x0, 0xc, 0x7, + 0xc, 0x0, 0xc2, 0x75, 0x7d, 0xd5, 0x51, 0xc0, + 0xc, 0x0, 0xa, 0x4c, 0x0, 0xc, 0x55, 0xd0, + 0x4, 0x90, 0xc0, 0x0, 0xa0, 0x1, 0x2, 0xa0, + 0xc, 0x0, 0x0, 0x0, 0x2, 0x90, 0x0, 0xc0, + 0x0, 0x0, 0x3, 0x60, 0x12, 0x3b, 0x0, 0x0, + 0x1, 0x20, 0x0, 0x5e, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+544A "告" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x64, 0xb, 0x30, 0x0, 0x0, 0x0, 0xb, 0x10, + 0xb1, 0x2, 0x10, 0x0, 0x5, 0x85, 0x5c, 0x65, + 0x76, 0x0, 0x1, 0x70, 0x0, 0xb1, 0x0, 0x0, + 0x0, 0x20, 0x0, 0xb, 0x10, 0x1, 0x50, 0x6, + 0x55, 0x55, 0x65, 0x55, 0x67, 0x10, 0x0, 0x20, + 0x0, 0x0, 0x20, 0x0, 0x0, 0xc, 0x55, 0x55, + 0x5c, 0x30, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb1, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x10, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0xc1, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, 0x0, + + /* U+5462 "呢" */ + 0x10, 0x1, 0x8, 0x55, 0x55, 0x91, 0xc5, 0x5d, + 0xc, 0x0, 0x0, 0xc0, 0xc0, 0xc, 0xc, 0x0, + 0x0, 0xc0, 0xc0, 0xc, 0xc, 0x55, 0x55, 0xd0, + 0xc0, 0xc, 0xc, 0x12, 0x0, 0x20, 0xc0, 0xc, + 0xc, 0x3a, 0x0, 0x70, 0xc0, 0xc, 0xb, 0x38, + 0x9, 0x80, 0xc5, 0x5c, 0x38, 0x38, 0x74, 0x0, + 0xc0, 0x6, 0x73, 0x3b, 0x10, 0x2, 0x40, 0x0, + 0xa0, 0x38, 0x0, 0x14, 0x0, 0x4, 0x40, 0x2b, + 0x11, 0x6a, 0x0, 0x6, 0x0, 0x7, 0x99, 0x93, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+5468 "周" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x65, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x92, 0x0, + 0x92, 0x0, 0xb, 0x0, 0x9, 0x20, 0xa, 0x14, + 0x10, 0xb0, 0x0, 0x92, 0x36, 0xc5, 0x53, 0xb, + 0x0, 0x9, 0x20, 0xa, 0x10, 0x60, 0xb0, 0x0, + 0xa4, 0x65, 0x55, 0x55, 0x2b, 0x0, 0xa, 0x0, + 0x85, 0x5a, 0x30, 0xb0, 0x0, 0xb0, 0xb, 0x0, + 0xb0, 0xb, 0x0, 0xa, 0x0, 0xb0, 0xb, 0x0, + 0xb0, 0x4, 0x50, 0xc, 0x55, 0xc0, 0xb, 0x0, + 0x80, 0x0, 0x40, 0x3, 0x22, 0xb0, 0x32, 0x0, + 0x0, 0x0, 0x5, 0xe5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5473 "味" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x74, 0x49, 0x0, + 0xc, 0x0, 0x20, 0xc, 0x0, 0xc1, 0x65, 0xd5, + 0x67, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0xc0, 0x2, 0x50, 0xc0, + 0xc, 0x65, 0xae, 0x85, 0x55, 0xc, 0x0, 0xc0, + 0xc, 0xc5, 0x10, 0x0, 0xd5, 0x5c, 0x6, 0x5c, + 0x8, 0x0, 0xa, 0x0, 0x32, 0x90, 0xc0, 0x76, + 0x0, 0x0, 0x1, 0x90, 0xc, 0x0, 0xc9, 0x10, + 0x1, 0x70, 0x0, 0xc0, 0x1, 0x50, 0x0, 0x20, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x0, + + /* U+547C "呼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x8e, 0x20, 0x85, 0x5c, 0x14, + 0x58, 0xc2, 0x0, 0xb, 0x0, 0xc1, 0x10, 0x1a, + 0x1, 0x90, 0xb0, 0xc, 0xa, 0x11, 0xa0, 0x94, + 0xb, 0x0, 0xc0, 0x67, 0x1a, 0x25, 0x0, 0xb0, + 0xc, 0x1, 0x11, 0xa2, 0x5, 0xb, 0x0, 0xc5, + 0x55, 0x6c, 0x55, 0x71, 0xb5, 0x5c, 0x0, 0x1, + 0xa0, 0x0, 0xb, 0x0, 0xc0, 0x0, 0x1a, 0x0, + 0x0, 0x50, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x3a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6e, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x0, + + /* U+547D "命" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, + 0x2, 0x80, 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, + 0x7c, 0x71, 0x0, 0x3, 0x82, 0x65, 0x55, 0x61, + 0x8f, 0x80, 0x33, 0x20, 0x3, 0x4, 0x11, 0x52, + 0x0, 0x0, 0xb5, 0x5d, 0xb, 0x33, 0xc1, 0x0, + 0x0, 0xb0, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x0, + 0xb0, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb5, + 0x5c, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x9, + 0xb, 0x29, 0xc0, 0x0, 0x0, 0x30, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+548C "和" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0xd0, 0x0, 0x0, 0x0, 0x2, 0x55, + 0xd1, 0x0, 0x85, 0x55, 0x90, 0x0, 0x0, 0xc0, + 0x0, 0xc0, 0x2, 0xa0, 0x3, 0x55, 0xd5, 0x94, + 0xc0, 0x2, 0xa0, 0x0, 0x4, 0xe0, 0x0, 0xc0, + 0x2, 0xa0, 0x0, 0xb, 0xe7, 0x20, 0xc0, 0x2, + 0xa0, 0x0, 0x37, 0xc1, 0xd3, 0xc0, 0x2, 0xa0, + 0x0, 0x90, 0xc0, 0x11, 0xc0, 0x2, 0xa0, 0x6, + 0x10, 0xc0, 0x0, 0xd5, 0x56, 0xa0, 0x11, 0x0, + 0xc0, 0x0, 0xc0, 0x2, 0xa0, 0x0, 0x0, 0xd0, + 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+54B2 "咲" */ + 0x0, 0x0, 0x1, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x94, 0x0, 0x7a, 0x0, 0xb5, 0x5c, 0x1, + 0xf0, 0xa, 0x0, 0xc, 0x0, 0xc0, 0x4, 0x3, + 0x21, 0x30, 0xc0, 0xc, 0x26, 0x59, 0x85, 0x66, + 0xc, 0x0, 0xc0, 0x0, 0x93, 0x0, 0x0, 0xc0, + 0xc, 0x0, 0xa, 0x20, 0x4, 0xc, 0x0, 0xc6, + 0x55, 0xd8, 0x55, 0x73, 0xd5, 0x5c, 0x0, 0xc, + 0x41, 0x0, 0xc, 0x0, 0x80, 0x3, 0x91, 0x70, + 0x0, 0x10, 0x0, 0x0, 0xa2, 0xa, 0x10, 0x0, + 0x0, 0x0, 0x56, 0x0, 0x3c, 0x0, 0x0, 0x0, + 0x64, 0x0, 0x0, 0x8e, 0x40, 0x0, 0x30, 0x0, + 0x0, 0x0, 0x30, + + /* U+54C1 "品" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x55, 0x55, 0xa4, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x82, 0x0, 0x0, 0xc, 0x0, 0x0, 0x82, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x82, 0x0, 0x0, 0xd, + 0x55, 0x55, 0xb2, 0x0, 0x0, 0x4, 0x0, 0x0, + 0x10, 0x0, 0x1a, 0x55, 0xa5, 0xb, 0x55, 0xb4, + 0xb, 0x0, 0x93, 0xc, 0x0, 0xa2, 0xb, 0x0, + 0x93, 0xc, 0x0, 0xa2, 0xb, 0x0, 0x93, 0xc, + 0x0, 0xa2, 0xd, 0x55, 0xb3, 0xd, 0x55, 0xb2, + 0x1a, 0x0, 0x51, 0x9, 0x0, 0x61, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+54E1 "員" */ + 0x0, 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1c, + 0x55, 0x55, 0x5d, 0x0, 0x0, 0x1b, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x1c, 0x55, 0x55, 0x5a, 0x0, + 0x1, 0x86, 0x55, 0x55, 0x56, 0x80, 0x1, 0xb0, + 0x0, 0x0, 0x2, 0x90, 0x1, 0xc5, 0x55, 0x55, + 0x56, 0x90, 0x0, 0xb0, 0x0, 0x0, 0x2, 0x90, + 0x1, 0xc5, 0x55, 0x55, 0x56, 0x90, 0x1, 0xc5, + 0x55, 0x55, 0x56, 0xa0, 0x0, 0x50, 0x54, 0x5, + 0x10, 0x20, 0x0, 0x7, 0xa3, 0x1, 0x9b, 0x30, + 0x3, 0x72, 0x0, 0x0, 0x3, 0xe0, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+54EA "哪" */ + 0x0, 0x3, 0x33, 0x37, 0x24, 0x37, 0x8, 0x5a, + 0x22, 0xb1, 0xb4, 0x72, 0xc1, 0xa0, 0xa0, 0xa, + 0xb, 0x46, 0x53, 0xa, 0xa, 0x25, 0xc5, 0xb4, + 0x66, 0x0, 0xa0, 0xa0, 0xa, 0xb, 0x46, 0x50, + 0xa, 0xa, 0x0, 0x90, 0xb4, 0x64, 0x30, 0xa0, + 0xa2, 0x5b, 0x4b, 0x46, 0xa, 0xc, 0x5b, 0x5, + 0x61, 0xa4, 0x60, 0x91, 0xb0, 0x20, 0x91, 0x1a, + 0x47, 0x2b, 0x12, 0x0, 0x28, 0x3, 0x84, 0x6a, + 0x90, 0x0, 0x8, 0x17, 0xb4, 0x46, 0x0, 0x0, + 0x6, 0x0, 0x25, 0x4, 0x50, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5546 "商" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x67, 0x0, 0x2, 0x20, 0x6, 0x55, + 0x75, 0x56, 0x67, 0x57, 0x60, 0x0, 0x0, 0x67, + 0x0, 0x67, 0x0, 0x0, 0x0, 0x75, 0x5c, 0x55, + 0x95, 0x59, 0x10, 0x0, 0xb0, 0x5, 0x0, 0x20, + 0xb, 0x0, 0x0, 0xb0, 0x3c, 0x10, 0x5c, 0x1b, + 0x0, 0x0, 0xb1, 0x71, 0x0, 0x25, 0x2b, 0x0, + 0x0, 0xb2, 0xc, 0x55, 0xc2, 0xb, 0x0, 0x0, + 0xb0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xb0, + 0xc, 0x55, 0xc0, 0xb, 0x0, 0x0, 0xb0, 0xa, + 0x0, 0x60, 0xb, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x3, 0xbb, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+554A "啊" */ + 0x0, 0x4, 0x67, 0x74, 0x55, 0x5a, 0x2c, 0x5c, + 0x65, 0x73, 0x0, 0x5, 0x60, 0xa0, 0xa5, 0x58, + 0x0, 0x0, 0x56, 0xa, 0xa, 0x55, 0x50, 0xa5, + 0xb5, 0x60, 0xa0, 0xa5, 0x64, 0xa, 0xa, 0x56, + 0xa, 0xa, 0x55, 0x70, 0xa0, 0xa5, 0x60, 0xa0, + 0xa5, 0x55, 0x6a, 0xa, 0x56, 0xc, 0x5b, 0x55, + 0x47, 0xc5, 0xa5, 0x60, 0xa0, 0x35, 0x8d, 0x23, + 0x1, 0x56, 0x0, 0x0, 0x55, 0x0, 0x0, 0x5, + 0x60, 0x0, 0x5, 0x50, 0x0, 0x10, 0x56, 0x0, + 0x0, 0x64, 0x0, 0x1, 0x8f, 0x30, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+554F "問" */ + 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0xc5, + 0x55, 0xc0, 0xc5, 0x55, 0xd0, 0x1b, 0x0, 0xa, + 0xb, 0x0, 0xc, 0x1, 0xc5, 0x55, 0xa0, 0xc5, + 0x55, 0xc0, 0x1b, 0x0, 0xa, 0xb, 0x0, 0xc, + 0x1, 0xc5, 0x55, 0x80, 0xb5, 0x55, 0xc0, 0x1b, + 0x0, 0x0, 0x0, 0x10, 0xc, 0x1, 0xb0, 0xc, + 0x55, 0x5d, 0x0, 0xc0, 0x1b, 0x0, 0xb0, 0x0, + 0xb0, 0xc, 0x1, 0xb0, 0xb, 0x0, 0xb, 0x0, + 0xc0, 0x1b, 0x0, 0xd5, 0x55, 0xb0, 0xc, 0x1, + 0xb0, 0x3, 0x0, 0x2, 0x0, 0xc0, 0x1a, 0x0, + 0x0, 0x0, 0x6, 0xd8, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+5566 "啦" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x4, 0x30, 0x0, 0x0, 0x0, 0xb, + 0x0, 0xd, 0x0, 0xb, 0x5c, 0x10, 0xb4, 0x0, + 0x71, 0x50, 0xb0, 0xb4, 0x6c, 0x54, 0x65, 0x55, + 0xb, 0xb, 0x0, 0xb0, 0x0, 0x5, 0x30, 0xb0, + 0xb0, 0xb, 0x45, 0x20, 0xa5, 0xb, 0xb, 0x5, + 0xd2, 0x9, 0xb, 0x0, 0xb0, 0xba, 0x6b, 0x0, + 0xc0, 0xa0, 0xc, 0x5c, 0x0, 0xb0, 0xa, 0x27, + 0x0, 0xa0, 0x20, 0xb, 0x0, 0x24, 0x30, 0x0, + 0x0, 0x11, 0xb0, 0x0, 0x50, 0x60, 0x0, 0x4, + 0xd7, 0x36, 0x55, 0x56, 0x20, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x0, + + /* U+5584 "善" */ + 0x0, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x6, 0x70, 0x1b, 0x0, 0x0, 0x3, 0x55, 0x6b, + 0x59, 0x55, 0xc5, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x21, 0x0, 0x0, 0x36, 0x55, 0xd5, 0x56, 0x50, + 0x0, 0x65, 0x55, 0x5d, 0x55, 0x56, 0xb0, 0x0, + 0x4, 0x60, 0xc0, 0x1b, 0x0, 0x0, 0x0, 0xb, + 0xc, 0x5, 0x20, 0x60, 0x16, 0x55, 0x55, 0x65, + 0x55, 0x57, 0x40, 0x0, 0x75, 0x55, 0x55, 0xa1, + 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x5d, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x20, 0x0, + + /* U+5589 "喉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc2, 0x55, 0x82, 0x0, 0x54, 0x72, 0x1a, + 0x0, 0xa, 0x0, 0xa, 0x1a, 0x6, 0x30, 0x0, + 0xa0, 0x40, 0xa0, 0xa0, 0xc2, 0x7b, 0x55, 0x55, + 0xa, 0xa, 0x3e, 0x4, 0xa0, 0x2, 0x0, 0xa0, + 0xa4, 0xa0, 0x95, 0xb5, 0x62, 0xa, 0xa, 0xa, + 0x32, 0xb, 0x0, 0x0, 0xa5, 0xc0, 0xa4, 0x55, + 0xc6, 0x59, 0xb, 0x9, 0xa, 0x0, 0xa, 0x60, + 0x0, 0x60, 0x0, 0xa0, 0x6, 0x56, 0x30, 0x0, + 0x0, 0xa, 0x1, 0x90, 0xb, 0x10, 0x0, 0x0, + 0xb2, 0x60, 0x0, 0x3b, 0x0, 0x0, 0x1, 0x10, + 0x0, 0x0, 0x0, + + /* U+559C "喜" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x10, 0x4, 0x10, 0x2, 0x65, 0x55, + 0xc5, 0x55, 0x75, 0x0, 0x0, 0x22, 0x2c, 0x22, + 0x91, 0x0, 0x0, 0x6, 0x32, 0x22, 0x26, 0x10, + 0x0, 0x0, 0xb5, 0x55, 0x55, 0xc1, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x63, + 0x30, 0x8, 0x40, 0x0, 0x1, 0x11, 0x1b, 0x13, + 0x51, 0x18, 0x21, 0x64, 0x54, 0x44, 0x44, 0x54, + 0x42, 0x0, 0xa, 0x55, 0x55, 0x5b, 0x40, 0x0, + 0x0, 0xa0, 0x0, 0x0, 0x82, 0x0, 0x0, 0xb, + 0x55, 0x55, 0x5b, 0x30, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x20, 0x0, + + /* U+559D "喝" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x10, 0xc5, 0x55, 0x5e, 0x0, 0xb5, 0x6c, 0xc, + 0x0, 0x0, 0xc0, 0xc, 0x1, 0xa0, 0xd5, 0x55, + 0x5c, 0x0, 0xc0, 0x1a, 0xd, 0x55, 0x55, 0xc0, + 0xc, 0x1, 0xa0, 0x8a, 0x0, 0x4, 0x0, 0xc0, + 0x1a, 0xa, 0x73, 0x33, 0x37, 0xc, 0x56, 0xb6, + 0x52, 0x86, 0x22, 0xb0, 0xc0, 0x8, 0xa5, 0x1c, + 0x60, 0x18, 0x9, 0x0, 0x26, 0x38, 0x13, 0xa3, + 0x70, 0x0, 0x0, 0x65, 0x0, 0x16, 0x46, 0x0, + 0x0, 0x6, 0x65, 0x55, 0x47, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x0, + + /* U+55AE "單" */ + 0x0, 0x10, 0x3, 0x2, 0x0, 0x11, 0x0, 0x0, + 0xb5, 0x5c, 0x1b, 0x55, 0x87, 0x0, 0x0, 0xb0, + 0xb, 0xa, 0x0, 0x55, 0x0, 0x0, 0xb5, 0x5a, + 0xb, 0x55, 0x85, 0x0, 0x0, 0x27, 0x55, 0x65, + 0x55, 0xa0, 0x0, 0x0, 0x38, 0x0, 0x90, 0x0, + 0xb0, 0x0, 0x0, 0x2b, 0x55, 0xb5, 0x55, 0xb0, + 0x0, 0x0, 0x28, 0x0, 0x90, 0x0, 0xb0, 0x0, + 0x0, 0x3b, 0x55, 0xb5, 0x55, 0xb0, 0x0, 0x0, + 0x11, 0x0, 0x90, 0x0, 0x13, 0x20, 0x16, 0x55, + 0x55, 0xb5, 0x55, 0x56, 0x60, 0x0, 0x0, 0x0, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+55B6 "営" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x91, 0x9, 0x10, 0x87, 0x0, 0x0, 0x5, 0x90, + 0x57, 0x18, 0x0, 0x0, 0x20, 0x2, 0x0, 0x4, + 0x0, 0x11, 0x8, 0x55, 0x55, 0x55, 0x55, 0x5b, + 0x91, 0xd0, 0x47, 0x55, 0x55, 0xb0, 0x70, 0x11, + 0x5, 0x60, 0x0, 0xb, 0x0, 0x0, 0x0, 0x59, + 0x55, 0x55, 0xb0, 0x0, 0x0, 0x3, 0x20, 0x0, + 0x3, 0x0, 0x0, 0x5, 0x55, 0x55, 0x55, 0x59, + 0x10, 0x0, 0xa1, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0xa, 0x10, 0x0, 0x0, 0xb, 0x0, 0x0, 0xa5, + 0x55, 0x55, 0x55, 0xc0, 0x0, 0x5, 0x0, 0x0, + 0x0, 0x4, 0x0, + + /* U+55CE "嗎" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x55, + 0x95, 0x85, 0x59, 0x57, 0x60, 0xb0, 0xa, 0x56, + 0x0, 0xb0, 0x10, 0xb, 0x0, 0xa5, 0x95, 0x5c, + 0x58, 0x20, 0xb0, 0xa, 0x56, 0x0, 0xb0, 0x10, + 0xb, 0x0, 0xa5, 0x95, 0x5c, 0x57, 0x30, 0xb0, + 0xa, 0x56, 0x0, 0xb0, 0x2, 0xc, 0x55, 0xb5, + 0x95, 0x47, 0x45, 0xc2, 0xb0, 0x6, 0x0, 0x0, + 0x4, 0xb, 0x5, 0x0, 0x4, 0x24, 0x26, 0x3a, + 0xb0, 0x0, 0x0, 0x90, 0xc0, 0xc0, 0xab, 0x0, + 0x0, 0x67, 0x7, 0x2, 0x2, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x39, 0xf5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, + + /* U+55EF "嗯" */ + 0x20, 0x3, 0x18, 0x55, 0x55, 0xa3, 0xb, 0x56, + 0xb1, 0xa0, 0x73, 0xa, 0x10, 0xb0, 0x1a, 0x1a, + 0x5b, 0x79, 0xa1, 0xb, 0x1, 0xa1, 0xa0, 0xb0, + 0xa, 0x10, 0xb0, 0x1a, 0x1a, 0x18, 0x94, 0xa1, + 0xb, 0x1, 0xa1, 0xa7, 0x0, 0x7a, 0x10, 0xb5, + 0x6a, 0x1c, 0x55, 0x55, 0xb1, 0xb, 0x1, 0x70, + 0x30, 0x71, 0x2, 0x0, 0x80, 0x0, 0x22, 0x63, + 0xa0, 0x63, 0x0, 0x0, 0x36, 0x28, 0x2, 0x3, + 0xd2, 0x0, 0xd, 0x22, 0x70, 0x1, 0x64, 0x0, + 0x0, 0x0, 0xc, 0x99, 0xb9, 0x0, + + /* U+561B "嘛" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb2, 0x0, 0x0, 0x85, 0x94, 0x75, + 0x58, 0x55, 0x98, 0xb, 0xb, 0x47, 0xb, 0x0, + 0xa1, 0x0, 0xb0, 0xb4, 0x70, 0xa0, 0xa, 0x0, + 0xb, 0xb, 0x4a, 0x5c, 0x94, 0xc6, 0x80, 0xb0, + 0xb5, 0x63, 0xc0, 0xe, 0x40, 0xb, 0xb, 0x64, + 0x8c, 0xb4, 0xe6, 0x0, 0xc5, 0xc9, 0x1a, 0xa2, + 0x8a, 0x70, 0x9, 0x0, 0xa6, 0x2a, 0x25, 0xa2, + 0x90, 0x0, 0x36, 0x50, 0xa5, 0xa, 0xa, 0x30, + 0x7, 0x20, 0xa, 0x0, 0xb0, 0x0, 0x3, 0x10, + 0x0, 0xa0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+56B4 "嚴" */ + 0x0, 0x1, 0x0, 0x30, 0x10, 0x2, 0x0, 0x0, + 0x1b, 0x55, 0xc0, 0xb5, 0x5c, 0x0, 0x0, 0x1b, + 0x55, 0xb0, 0xb5, 0x5b, 0x0, 0x0, 0x33, 0x0, + 0x30, 0x40, 0x7, 0x30, 0x0, 0xd5, 0x55, 0x65, + 0x57, 0x56, 0x50, 0x0, 0xb0, 0x65, 0xc1, 0x2b, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x93, 0x66, 0x25, + 0x40, 0x0, 0xb5, 0xc5, 0x79, 0xb2, 0x49, 0x10, + 0x1, 0xa0, 0xb5, 0x77, 0x73, 0x55, 0x0, 0x2, + 0x80, 0xa0, 0x39, 0x7, 0x91, 0x0, 0x5, 0x40, + 0xb5, 0x77, 0x5, 0xb0, 0x0, 0x7, 0x2, 0xc7, + 0x89, 0x38, 0xa5, 0x0, 0x5, 0x9, 0x40, 0x37, + 0x52, 0xb, 0x90, 0x10, 0x0, 0x0, 0x12, 0x0, + 0x0, 0x0, + + /* U+56DB "四" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, 0x75, + 0x57, 0x55, 0xc2, 0xc0, 0xc, 0x0, 0xc0, 0xc, + 0xc, 0x0, 0xc0, 0xc, 0x0, 0xc0, 0xc0, 0xc, + 0x0, 0xc0, 0xc, 0xc, 0x0, 0xb0, 0xc, 0x0, + 0xc0, 0xc0, 0xb, 0x0, 0xc0, 0xc, 0xc, 0x4, + 0x70, 0xc, 0x0, 0xc0, 0xc0, 0xa1, 0x0, 0xab, + 0xcd, 0xc, 0x73, 0x0, 0x0, 0x0, 0xc0, 0xd1, + 0x0, 0x0, 0x0, 0xc, 0xd, 0x55, 0x55, 0x55, + 0x55, 0xd0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+56DE "回" */ + 0x85, 0x55, 0x55, 0x55, 0x59, 0x2c, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0xc0, 0x0, 0x0, 0x0, 0xb, + 0xc, 0x1, 0x75, 0x55, 0x80, 0xb0, 0xc0, 0x1a, + 0x0, 0x1a, 0xb, 0xc, 0x0, 0xa0, 0x1, 0xa0, + 0xb0, 0xc0, 0x1a, 0x0, 0x1a, 0xb, 0xc, 0x1, + 0xc5, 0x56, 0xa0, 0xb0, 0xc0, 0x4, 0x0, 0x2, + 0xb, 0xc, 0x0, 0x0, 0x0, 0x0, 0xb0, 0xd5, + 0x55, 0x55, 0x55, 0x5c, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+56E0 "因" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x95, + 0x55, 0x55, 0x55, 0x56, 0xa0, 0x1b, 0x0, 0x1, + 0x60, 0x0, 0x2a, 0x1, 0xb0, 0x0, 0x1b, 0x0, + 0x2, 0xa0, 0x1b, 0x0, 0x1, 0xa0, 0x4, 0x2a, + 0x1, 0xb3, 0x65, 0x6c, 0x56, 0x72, 0xa0, 0x1b, + 0x0, 0x4, 0x90, 0x0, 0x2a, 0x1, 0xb0, 0x0, + 0x88, 0x70, 0x2, 0xa0, 0x1b, 0x0, 0xc, 0x4, + 0xc0, 0x2a, 0x1, 0xb0, 0x9, 0x30, 0x9, 0x72, + 0xa0, 0x1b, 0x16, 0x20, 0x0, 0x14, 0x2a, 0x1, + 0xb0, 0x0, 0x0, 0x0, 0x2, 0xa0, 0x1c, 0x55, + 0x55, 0x55, 0x55, 0x6a, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+56F0 "困" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x55, + 0x55, 0x65, 0x55, 0xc4, 0xc, 0x0, 0x0, 0xd0, + 0x0, 0xa2, 0xc, 0x0, 0x0, 0xc0, 0x0, 0xa2, + 0xc, 0x36, 0x56, 0xd5, 0x79, 0xa2, 0xc, 0x0, + 0xc, 0xc0, 0x0, 0xa2, 0xc, 0x0, 0x47, 0xd5, + 0x0, 0xa2, 0xc, 0x0, 0xa0, 0xc2, 0xc4, 0xa2, + 0xc, 0x8, 0x20, 0xc0, 0x2c, 0xa2, 0xc, 0x52, + 0x0, 0xc0, 0x2, 0xa2, 0xc, 0x0, 0x0, 0xd0, + 0x0, 0xa2, 0xc, 0x0, 0x0, 0x40, 0x0, 0xa2, + 0xd, 0x55, 0x55, 0x55, 0x55, 0xb2, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+56F3 "図" */ + 0x30, 0x0, 0x0, 0x0, 0x0, 0x30, 0xb6, 0x55, + 0x55, 0x55, 0x55, 0xd2, 0xb1, 0x0, 0x1, 0x30, + 0x0, 0xb0, 0xb1, 0x0, 0x71, 0xb2, 0x71, 0xb0, + 0xb1, 0x4, 0x2b, 0x56, 0xd1, 0xb0, 0xb1, 0x5, + 0x14, 0x9, 0x40, 0xb0, 0xb1, 0x0, 0x80, 0x3a, + 0x0, 0xb0, 0xb1, 0x0, 0x29, 0xb1, 0x0, 0xb0, + 0xb1, 0x0, 0xb, 0xb0, 0x0, 0xb0, 0xb1, 0x1, + 0x81, 0x3c, 0x72, 0xb0, 0xb1, 0x45, 0x0, 0x1, + 0x89, 0xc0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xb6, 0x55, 0x55, 0x55, 0x55, 0xd1, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x20, + + /* U+56FD "国" */ + 0x10, 0x0, 0x0, 0x0, 0x1, 0xd, 0x55, 0x55, + 0x55, 0x55, 0xd2, 0xc0, 0x0, 0x0, 0x3, 0x3c, + 0xc, 0x16, 0x56, 0xb5, 0x53, 0xc0, 0xc0, 0x0, + 0x2a, 0x0, 0xc, 0xc, 0x4, 0x56, 0xb5, 0xa1, + 0xc0, 0xc0, 0x10, 0x2a, 0x20, 0xc, 0xc, 0x0, + 0x2, 0xa9, 0x70, 0xc0, 0xc0, 0x0, 0x2a, 0x9, + 0xc, 0xc, 0x35, 0x56, 0xb5, 0x98, 0xc0, 0xc1, + 0x0, 0x0, 0x0, 0xc, 0xd, 0x55, 0x55, 0x55, + 0x55, 0xd0, 0xc0, 0x0, 0x0, 0x0, 0x9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+570B "國" */ + 0x20, 0x0, 0x0, 0x0, 0x0, 0x30, 0xa6, 0x55, + 0x55, 0x87, 0x55, 0xc2, 0xa1, 0x0, 0x0, 0xc1, + 0xc0, 0xb0, 0xa2, 0x65, 0x55, 0xc5, 0x8a, 0xb0, + 0xa1, 0x0, 0x0, 0xa0, 0x0, 0xb0, 0xa1, 0x95, + 0xb2, 0xa0, 0x65, 0xb0, 0xa1, 0xa0, 0xa0, 0x90, + 0xa1, 0xb0, 0xa1, 0xa5, 0xc0, 0x67, 0x80, 0xb0, + 0xa1, 0x70, 0x40, 0xf, 0x11, 0xc0, 0xa1, 0x36, + 0x63, 0x7a, 0x86, 0xb0, 0xa2, 0x91, 0x6, 0x40, + 0x6f, 0xb0, 0xa1, 0x0, 0x40, 0x0, 0x3, 0xc0, + 0xa6, 0x55, 0x55, 0x55, 0x55, 0xc0, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x20, + + /* U+570D "圍" */ + 0x11, 0x0, 0x0, 0x0, 0x0, 0x3, 0x2, 0xb5, + 0x55, 0x75, 0x55, 0x55, 0xd0, 0x2a, 0x0, 0xa, + 0x10, 0x20, 0xc, 0x2, 0xa0, 0x46, 0xb5, 0x5d, + 0x0, 0xc0, 0x2a, 0x45, 0x5b, 0x55, 0xca, 0x3c, + 0x2, 0xa1, 0x16, 0x55, 0x58, 0x0, 0xc0, 0x2a, + 0x1, 0x90, 0x0, 0xb0, 0xc, 0x2, 0xa0, 0x18, + 0x5c, 0x57, 0x0, 0xc0, 0x2a, 0x6, 0x85, 0xc5, + 0x84, 0xc, 0x2, 0xa0, 0xa8, 0x5c, 0x57, 0x70, + 0xc0, 0x2a, 0x1, 0x0, 0xb0, 0x0, 0xc, 0x2, + 0xa0, 0x0, 0x8, 0x0, 0x0, 0xc0, 0x2b, 0x55, + 0x55, 0x55, 0x55, 0x5c, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x20, + + /* U+5712 "園" */ + 0x30, 0x0, 0x0, 0x0, 0x0, 0x30, 0xa6, 0x55, + 0x5a, 0x55, 0x55, 0xd1, 0xa2, 0x0, 0xc, 0x3, + 0x0, 0xc0, 0xa2, 0x6, 0x5c, 0x56, 0x20, 0xc0, + 0xa2, 0x65, 0x5a, 0x55, 0xa3, 0xc0, 0xa2, 0x7, + 0x55, 0x58, 0x20, 0xc0, 0xa2, 0xb, 0x0, 0xa, + 0x10, 0xc0, 0xa2, 0xd, 0x66, 0x5b, 0x10, 0xc0, + 0xa2, 0x3, 0xd1, 0x1, 0xc1, 0xc0, 0xa2, 0x18, + 0xa1, 0x69, 0x10, 0xc0, 0xa4, 0x50, 0x80, 0x9, + 0xa0, 0xc0, 0xa2, 0x0, 0x60, 0x0, 0x70, 0xc0, + 0xa6, 0x55, 0x55, 0x55, 0x55, 0xd0, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+5718 "團" */ + 0x30, 0x0, 0x0, 0x0, 0x0, 0x30, 0xb6, 0x55, + 0x5a, 0x65, 0x55, 0xd1, 0xb3, 0x65, 0x5d, 0x55, + 0x76, 0xc0, 0xb1, 0x55, 0x5c, 0x55, 0x80, 0xc0, + 0xb1, 0x86, 0x5c, 0x55, 0xa0, 0xc0, 0xb1, 0x86, + 0x5c, 0x55, 0xa0, 0xc0, 0xb1, 0x50, 0xb, 0x3, + 0x70, 0xc0, 0xb1, 0x9a, 0x88, 0x48, 0x86, 0xc0, + 0xb2, 0x55, 0x55, 0x5c, 0x82, 0xc0, 0xb1, 0x15, + 0x40, 0xa, 0x0, 0xc0, 0xb1, 0x0, 0x72, 0x5a, + 0x0, 0xc0, 0xb1, 0x0, 0x0, 0x74, 0x0, 0xc0, + 0xb6, 0x55, 0x55, 0x55, 0x55, 0xd0, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+571F "土" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, + 0x0, 0x0, 0x0, 0x2, 0x55, 0x55, 0xc6, 0x55, + 0x9a, 0x0, 0x0, 0x10, 0x0, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0x1, 0x0, 0x26, 0x55, 0x55, + 0xb6, 0x55, 0x5b, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5723 "圣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x16, 0x65, 0x55, 0x58, 0xd0, 0x0, 0x0, 0x0, + 0x32, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x6, + 0x40, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb8, 0xb7, + 0x20, 0x0, 0x0, 0x3, 0x87, 0x19, 0x15, 0xbf, + 0xd3, 0x4, 0x53, 0x0, 0xd, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x26, 0x0, 0x0, + 0x26, 0x55, 0x5e, 0x55, 0x55, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x1, 0x80, 0x5, 0x55, 0x55, 0x56, + 0x55, 0x55, 0x62, + + /* U+5728 "在" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x80, 0x0, 0x6, 0x40, 0x5, 0x65, 0x5d, + 0x55, 0x65, 0x55, 0x40, 0x0, 0x0, 0x58, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0xc0, 0x7, + 0x0, 0x0, 0x8c, 0x6, 0x55, 0xd5, 0x55, 0x20, + 0x6, 0x2c, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x10, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x45, + 0x55, 0xc5, 0x56, 0xc1, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5730 "地" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x29, + 0x0, 0x51, 0x1a, 0x0, 0x0, 0x0, 0x29, 0x0, + 0xb0, 0x1a, 0x3, 0x0, 0x0, 0x29, 0x10, 0xb0, + 0x1b, 0x5d, 0x20, 0x6, 0x7b, 0x83, 0xb5, 0x6a, + 0xb, 0x0, 0x0, 0x29, 0x35, 0xc0, 0x1a, 0xb, + 0x0, 0x0, 0x29, 0x0, 0xb0, 0x1a, 0xb, 0x0, + 0x0, 0x29, 0x0, 0xb0, 0x1a, 0xb, 0x0, 0x0, + 0x29, 0x0, 0xb0, 0x1b, 0x9b, 0x10, 0x0, 0x2c, + 0x64, 0xb0, 0x17, 0x0, 0x50, 0xb, 0xb3, 0x0, + 0xb0, 0x0, 0x0, 0x91, 0x3, 0x0, 0x0, 0x7b, + 0xaa, 0xaa, 0xe4, + + /* U+5747 "均" */ + 0x0, 0x2, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xb, 0x10, 0x0, 0x10, 0x0, 0xc, 0x0, + 0x2b, 0x55, 0x55, 0xd1, 0x5, 0x5d, 0x86, 0x81, + 0x0, 0x0, 0xc0, 0x0, 0xc, 0x2, 0x53, 0x60, + 0x0, 0xc0, 0x0, 0xc, 0x2, 0x0, 0xb6, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x35, 0x0, 0xb0, + 0x0, 0xc, 0x2, 0x10, 0x5, 0x41, 0xb0, 0x0, + 0x2e, 0x83, 0x6, 0x91, 0x2, 0xa0, 0x1d, 0xc3, + 0x2, 0xe6, 0x0, 0x4, 0x80, 0x3, 0x0, 0x0, + 0x20, 0x22, 0x1a, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+574A "坊" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x10, 0x1, 0xb1, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x11, 0x22, 0x11, 0x80, 0x0, 0xc, 0x16, 0x36, + 0xb3, 0x33, 0x31, 0x4, 0x5d, 0x54, 0x4, 0x90, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x5, 0xa5, 0x5b, + 0x60, 0x0, 0xc, 0x0, 0x7, 0x60, 0xa, 0x30, + 0x0, 0xc, 0x0, 0xb, 0x20, 0xb, 0x10, 0x0, + 0x1d, 0x86, 0x2b, 0x0, 0xd, 0x0, 0xc, 0xc4, + 0x0, 0x93, 0x0, 0xd, 0x0, 0x2, 0x0, 0x5, + 0x40, 0x21, 0x3b, 0x0, 0x0, 0x0, 0x53, 0x0, + 0x1a, 0xf4, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+5750 "坐" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x20, 0x92, 0x0, 0xd2, 0x0, 0x0, 0x2c, 0x0, + 0x92, 0x3, 0xb0, 0x0, 0x0, 0x88, 0x0, 0x92, + 0x9, 0x80, 0x0, 0x0, 0xc5, 0xa0, 0x92, 0x1a, + 0x2b, 0x0, 0x6, 0x40, 0xb4, 0x92, 0x71, 0x9, + 0x60, 0x16, 0x0, 0x20, 0x95, 0x30, 0x1, 0x10, + 0x10, 0x35, 0x55, 0xb7, 0x55, 0xd3, 0x0, 0x0, + 0x10, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x5, 0x40, 0x26, 0x55, 0x55, 0x65, + 0x55, 0x57, 0x70, + + /* U+578B "型" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x15, + 0x55, 0x58, 0x80, 0x0, 0xb1, 0x0, 0xa, 0x9, + 0x20, 0xb, 0xb, 0x0, 0x0, 0xa0, 0x92, 0x30, + 0xb0, 0xb0, 0x5, 0x5c, 0x5b, 0x78, 0x3b, 0xb, + 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb0, 0xb0, 0x0, + 0x28, 0x9, 0x20, 0x3, 0xb, 0x0, 0x9, 0x0, + 0x92, 0x0, 0x38, 0xd0, 0x5, 0x10, 0x1, 0xa5, + 0x0, 0x23, 0x0, 0x1, 0x55, 0x5c, 0x75, 0x5c, + 0x30, 0x0, 0x1, 0x0, 0xa3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x30, 0x0, 0x10, 0x4, 0x55, + 0x55, 0xb7, 0x55, 0x5e, 0x80, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+57DF "域" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x94, 0x0, 0x0, 0xc, 0x2b, 0x20, 0x0, 0x92, + 0x0, 0x0, 0xb, 0x4, 0x40, 0x0, 0x92, 0x36, + 0x55, 0x5c, 0x56, 0xa1, 0x25, 0xb8, 0x80, 0x0, + 0xb, 0x0, 0x0, 0x1, 0x92, 0xa, 0x5c, 0x3b, + 0xa, 0x30, 0x0, 0x92, 0xa, 0xa, 0xb, 0xd, + 0x0, 0x0, 0x92, 0xa, 0xa, 0xb, 0x57, 0x0, + 0x0, 0x92, 0xa, 0x59, 0xa, 0xc1, 0x0, 0x15, + 0xc7, 0x40, 0x0, 0x28, 0xa0, 0x2, 0x49, 0x10, + 0x68, 0x74, 0x3b, 0xc2, 0x32, 0x0, 0x0, 0x61, + 0x2, 0x90, 0x3d, 0xa1, 0x0, 0x0, 0x0, 0x56, + 0x0, 0x4, 0xe2, 0x0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, + + /* U+57F7 "執" */ + 0x0, 0x3, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0xc2, 0x0, 0x0, 0x4, 0x5d, + 0x59, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x3, 0x0, 0x0, 0xc, 0x3, 0x26, + 0xd5, 0x8b, 0x0, 0x27, 0x85, 0x59, 0x30, 0xb0, + 0x57, 0x0, 0x0, 0x93, 0x56, 0x5, 0xb0, 0x65, + 0x0, 0x5, 0x77, 0x99, 0x12, 0xe4, 0x74, 0x0, + 0x0, 0xc, 0x0, 0x4, 0x8d, 0x74, 0x0, 0x25, + 0x5d, 0x5a, 0x49, 0x20, 0x75, 0x10, 0x1, 0xc, + 0x0, 0x19, 0x0, 0x58, 0x60, 0x0, 0xc, 0x0, + 0x91, 0x0, 0xd, 0xa0, 0x0, 0xb, 0x16, 0x10, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+57FA "基" */ + 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0xd, 0x1, 0x0, 0x3, 0x55, + 0xd5, 0x55, 0x5d, 0x5a, 0x30, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, 0x5c, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x5, + 0x40, 0x6, 0x55, 0xc7, 0x75, 0x87, 0x57, 0x60, + 0x0, 0x4, 0x90, 0xb2, 0x9, 0x30, 0x0, 0x0, + 0x57, 0x0, 0xb0, 0x5, 0x9c, 0x71, 0x16, 0x32, + 0x55, 0xc5, 0x56, 0x3, 0x40, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x3, 0x55, 0x55, 0xc5, + 0x55, 0x6e, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5831 "報" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x20, 0xa, 0x55, 0x59, 0x50, 0x5, 0x5c, + 0x59, 0x1b, 0x0, 0x8, 0x30, 0x0, 0xa, 0x0, + 0xb, 0x0, 0xa, 0x10, 0x25, 0x5c, 0x57, 0x7b, + 0x2, 0xac, 0x0, 0x1, 0x60, 0x35, 0xb, 0x0, + 0x11, 0x0, 0x0, 0x85, 0x72, 0xc, 0x75, 0x5a, + 0x80, 0x6, 0x68, 0x79, 0x3b, 0x40, 0xb, 0x0, + 0x0, 0xa, 0x0, 0xb, 0x7, 0x74, 0x0, 0x25, + 0x5c, 0x57, 0x6b, 0x7, 0xa0, 0x0, 0x1, 0xa, + 0x0, 0xb, 0xa, 0xb3, 0x0, 0x0, 0xa, 0x0, + 0xb, 0x71, 0x1d, 0x80, 0x0, 0xa, 0x10, 0xb, + 0x0, 0x2, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5834 "場" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xa4, 0x0, 0xc5, 0x55, 0x5d, 0x0, 0x0, 0xa2, + 0x0, 0xb0, 0x0, 0xc, 0x0, 0x0, 0xa2, 0x0, + 0xc5, 0x55, 0x5c, 0x0, 0x36, 0xc6, 0x92, 0xd5, + 0x55, 0x5c, 0x0, 0x0, 0xa2, 0x0, 0x60, 0x0, + 0x5, 0x10, 0x0, 0xa2, 0x16, 0x5a, 0x55, 0x56, + 0x90, 0x0, 0xa2, 0x0, 0x7a, 0x55, 0x56, 0x50, + 0x0, 0xa5, 0x67, 0x65, 0x76, 0x66, 0x50, 0x27, + 0xb4, 0x42, 0x28, 0xb, 0x8, 0x20, 0x47, 0x0, + 0x4, 0x60, 0x92, 0xb, 0x0, 0x0, 0x0, 0x12, + 0x8, 0x30, 0xc, 0x0, 0x0, 0x0, 0x3, 0x61, + 0x6, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+584A "塊" */ + 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, 0xa2, + 0xa, 0x57, 0x85, 0x5c, 0x0, 0x0, 0xa2, 0xb, + 0x0, 0xc0, 0xc, 0x0, 0x25, 0xc7, 0x8b, 0x55, + 0xd5, 0x5c, 0x0, 0x1, 0xa2, 0xb, 0x0, 0xc0, + 0xc, 0x0, 0x0, 0xa2, 0xb, 0x1, 0xb0, 0xc, + 0x0, 0x0, 0xa2, 0x9, 0x48, 0xe8, 0x47, 0x0, + 0x0, 0xa2, 0x40, 0xa, 0x84, 0x82, 0x0, 0x1, + 0xb8, 0x10, 0x39, 0x65, 0x74, 0x0, 0x5d, 0x30, + 0x1, 0xa0, 0x6c, 0x79, 0x50, 0x1, 0x0, 0x19, + 0x10, 0x66, 0x2, 0x80, 0x0, 0x3, 0x50, 0x0, + 0x3b, 0x89, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5869 "塩" */ + 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0xc5, 0x55, 0x5c, 0x40, 0x0, 0xb0, 0x6, + 0x20, 0x0, 0x0, 0x0, 0x36, 0xd7, 0x56, 0x85, + 0x55, 0x5a, 0x0, 0x0, 0xb0, 0x10, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x0, 0xb, + 0x0, 0x0, 0xb0, 0x1, 0xa5, 0x55, 0x58, 0x0, + 0x0, 0xb1, 0x45, 0x55, 0x55, 0x58, 0x20, 0x3, + 0xc6, 0xb, 0xa, 0xa, 0xa, 0x10, 0x4b, 0x10, + 0xb, 0xa, 0xa, 0xa, 0x10, 0x0, 0x0, 0xb, + 0xa, 0xa, 0xa, 0x10, 0x0, 0x0, 0x4c, 0x5c, + 0x5c, 0x5b, 0xc1, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+5883 "境" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x2b, 0x0, 0x0, 0x92, 0x1, 0x0, 0x0, 0x29, + 0x1, 0x65, 0x65, 0x68, 0x50, 0x0, 0x29, 0x0, + 0x9, 0x20, 0xc2, 0x0, 0x5, 0x6b, 0xa3, 0x15, + 0x44, 0x51, 0x70, 0x0, 0x29, 0x5, 0x54, 0x44, + 0x45, 0x41, 0x0, 0x29, 0x0, 0xb5, 0x55, 0x5e, + 0x10, 0x0, 0x29, 0x0, 0xb5, 0x55, 0x5c, 0x0, + 0x0, 0x29, 0x13, 0xb0, 0x0, 0xc, 0x0, 0x6, + 0xa9, 0x30, 0xc7, 0x78, 0x5c, 0x0, 0x6, 0x10, + 0x0, 0x9, 0x4b, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x2c, 0xb, 0x0, 0x71, 0x0, 0x0, 0x37, 0x81, + 0x6, 0xb9, 0xd4, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+5897 "増" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x49, 0x0, 0x7a, 0x0, 0x0, 0xb1, + 0x0, 0x9, 0x61, 0x80, 0x0, 0x0, 0xb1, 0x8, + 0x56, 0x77, 0x55, 0x90, 0x13, 0xc5, 0x6c, 0x0, + 0xb0, 0x2, 0xa0, 0x13, 0xb2, 0x1c, 0x55, 0xc5, + 0x56, 0xa0, 0x0, 0xb1, 0xc, 0x0, 0xb0, 0x2, + 0xa0, 0x0, 0xb1, 0xa, 0x55, 0x55, 0x56, 0x70, + 0x0, 0xb1, 0x1, 0x85, 0x55, 0x5a, 0x0, 0x0, + 0xb8, 0x61, 0xa0, 0x0, 0xc, 0x0, 0x4c, 0xa1, + 0x0, 0xc5, 0x55, 0x5c, 0x0, 0x15, 0x0, 0x0, + 0xa0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, 0xc5, + 0x55, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x2, 0x0, + + /* U+589E "增" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, + 0x2b, 0x0, 0x9, 0x30, 0x67, 0x0, 0x0, 0x19, + 0x0, 0x22, 0x50, 0x70, 0x30, 0x0, 0x19, 0x0, + 0xc5, 0x5c, 0x55, 0xc0, 0x6, 0x6b, 0xa4, 0xe5, + 0xa, 0x28, 0xa0, 0x0, 0x19, 0x0, 0xad, 0xa, + 0x61, 0xa0, 0x0, 0x19, 0x0, 0xa2, 0xa, 0x10, + 0xa0, 0x0, 0x19, 0x0, 0x95, 0x55, 0x55, 0x80, + 0x0, 0x19, 0x0, 0x56, 0x55, 0x5b, 0x10, 0x0, + 0x3d, 0x63, 0x55, 0x0, 0xb, 0x0, 0xc, 0x91, + 0x0, 0x58, 0x55, 0x5c, 0x0, 0x1, 0x0, 0x0, + 0x55, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x58, + 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+58CA "壊" */ + 0x0, 0x10, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0xd1, 0x2, 0x20, 0x0, 0xb0, + 0x26, 0x55, 0xd5, 0x56, 0x50, 0x0, 0xb0, 0x5, + 0x55, 0xd5, 0x58, 0x20, 0x25, 0xc6, 0x8a, 0xa, + 0xa, 0xa, 0x0, 0x1, 0xb0, 0xa, 0xa, 0xa, + 0xa, 0x0, 0x0, 0xb0, 0xb, 0x59, 0x59, 0x5c, + 0x0, 0x0, 0xb0, 0x1, 0x0, 0xa1, 0x3, 0x0, + 0x0, 0xb0, 0x26, 0x5b, 0x95, 0x58, 0x20, 0x0, + 0xb6, 0x50, 0x86, 0x24, 0x1b, 0x0, 0x2a, 0x91, + 0x7, 0xc3, 0x9, 0x71, 0x0, 0x5, 0x2, 0x62, + 0x73, 0x42, 0xd4, 0x0, 0x0, 0x1, 0x0, 0x8a, + 0x10, 0x3e, 0x91, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+58D3 "壓" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0xc, + 0x55, 0x55, 0x55, 0x65, 0x83, 0x0, 0xb3, 0x95, + 0x5b, 0xa, 0x27, 0x0, 0xb, 0x39, 0x55, 0xa0, + 0xa0, 0x52, 0x0, 0xb3, 0x75, 0x57, 0x5c, 0x59, + 0x0, 0x9, 0x67, 0x55, 0xb0, 0xa4, 0x0, 0x3, + 0x76, 0x85, 0x5a, 0x9, 0x60, 0x0, 0x62, 0x68, + 0x55, 0xa5, 0x45, 0x50, 0x8, 0x6, 0x40, 0x5a, + 0x60, 0xc, 0x42, 0x30, 0x31, 0x1, 0x70, 0x0, + 0x10, 0x0, 0x25, 0x55, 0x6b, 0x55, 0xa0, 0x0, + 0x0, 0x10, 0x1, 0x80, 0x0, 0x0, 0x4, 0x55, + 0x55, 0x6b, 0x55, 0x5c, 0x80, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+58EB "士" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x15, 0x55, 0x55, 0xc7, 0x55, + 0x5c, 0x90, 0x1, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x55, 0x55, + 0xc7, 0x55, 0xaa, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+58F0 "声" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x25, 0x55, 0x55, + 0xd5, 0x55, 0x7b, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x65, 0x55, 0xb5, 0x58, 0x80, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, + 0xd5, 0x55, 0xd5, 0x55, 0xd0, 0x0, 0xc, 0x0, + 0xc, 0x0, 0xc, 0x0, 0x0, 0xd5, 0x55, 0xa5, + 0x55, 0xd0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+58F2 "売" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x20, 0x2, 0x10, 0x2, 0x65, 0x55, + 0xc6, 0x55, 0x86, 0x0, 0x0, 0x0, 0xa, 0x10, + 0x21, 0x0, 0x0, 0x16, 0x55, 0x75, 0x57, 0x40, + 0x0, 0x55, 0x55, 0x55, 0x55, 0x55, 0x82, 0xa, + 0x10, 0x0, 0x0, 0x0, 0xa, 0x20, 0x80, 0x6, + 0x60, 0x36, 0x1, 0x10, 0x0, 0x0, 0x86, 0x4, + 0x80, 0x0, 0x0, 0x0, 0x9, 0x30, 0x48, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x4, 0x80, 0x4, 0x0, + 0x0, 0x58, 0x0, 0x38, 0x0, 0x52, 0x0, 0x66, + 0x0, 0x2, 0xea, 0xac, 0x51, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5909 "変" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x30, 0x4, 0x65, + 0x58, 0x59, 0x68, 0x56, 0xb3, 0x0, 0x2, 0x1c, + 0x0, 0x3b, 0x0, 0x0, 0x0, 0x1c, 0x4c, 0x0, + 0x3c, 0x86, 0x0, 0x0, 0x91, 0x1c, 0x0, 0x3b, + 0x8, 0xb0, 0x5, 0x0, 0xa, 0x10, 0x11, 0x0, + 0x50, 0x0, 0x0, 0x4e, 0x65, 0x55, 0x91, 0x0, + 0x0, 0x2, 0x95, 0x0, 0x7, 0xc2, 0x0, 0x0, + 0x35, 0x4, 0x60, 0x7a, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x6d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x17, + 0x94, 0xa9, 0x40, 0x0, 0x1, 0x56, 0x61, 0x0, + 0x3, 0x9e, 0xe5, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+590F "夏" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, + 0x65, 0x55, 0xa5, 0x55, 0x5a, 0x20, 0x0, 0x7, + 0x56, 0x85, 0x55, 0x90, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x55, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, + 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x6e, 0x55, 0x55, 0x80, 0x0, + 0x0, 0x0, 0x99, 0x55, 0x5c, 0x20, 0x0, 0x0, + 0x6, 0x55, 0x10, 0xa6, 0x0, 0x0, 0x0, 0x64, + 0x0, 0x9a, 0x50, 0x0, 0x0, 0x3, 0x10, 0x5, + 0x97, 0xa6, 0x20, 0x0, 0x1, 0x56, 0x72, 0x0, + 0x6, 0xbe, 0x92, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5915 "夕" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x30, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x55, + 0x57, 0xd1, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x8a, + 0x0, 0x0, 0xc, 0x10, 0x0, 0xe, 0x20, 0x0, + 0x7, 0x88, 0x0, 0x7, 0x90, 0x0, 0x3, 0x70, + 0x5d, 0x1, 0xe1, 0x0, 0x1, 0x60, 0x0, 0xc2, + 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xa5, 0x0, 0x0, 0x0, 0x1, 0x57, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5916 "外" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe2, 0x0, 0xd, 0x10, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x8, 0x60, 0x23, 0xc, + 0x0, 0x0, 0x0, 0xc5, 0x5a, 0xb0, 0xc0, 0x0, + 0x0, 0x48, 0x0, 0xc2, 0xd, 0x10, 0x0, 0xa, + 0x84, 0x1c, 0x0, 0xc6, 0xa2, 0x4, 0x40, 0xd7, + 0x50, 0xc, 0x3, 0xe1, 0x30, 0x1, 0xc0, 0x0, + 0xc0, 0x4, 0x0, 0x0, 0x65, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x29, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x27, 0x0, 0x0, 0xc, 0x0, 0x0, 0x34, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, + + /* U+591A "多" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x50, 0x0, 0x0, 0x0, 0x1, 0xb8, 0x55, + 0x59, 0xb0, 0x0, 0x48, 0x72, 0x0, 0x5c, 0x10, + 0x15, 0x20, 0x1b, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x6, 0xa3, 0x0, 0x0, 0x0, 0x37, 0x86, 0xc1, + 0x0, 0x0, 0x24, 0x20, 0x2d, 0x95, 0x55, 0x93, + 0x0, 0x5, 0xb2, 0x0, 0x4, 0xc2, 0x2, 0x75, + 0x38, 0x0, 0x4b, 0x10, 0x2, 0x0, 0xd, 0x7, + 0x90, 0x0, 0x0, 0x0, 0x17, 0x93, 0x0, 0x0, + 0x3, 0x56, 0x62, 0x0, 0x0, 0x0, 0x21, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+591C "夜" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x5, 0x55, + 0x55, 0x58, 0x55, 0x57, 0xb0, 0x1, 0x2, 0xc0, + 0x1d, 0x0, 0x0, 0x0, 0x0, 0x9, 0x60, 0x68, + 0x0, 0x14, 0x0, 0x0, 0x1c, 0x0, 0xb5, 0x55, + 0x99, 0x0, 0x0, 0x8e, 0x3, 0x93, 0x60, 0xb2, + 0x0, 0x2, 0x7c, 0x9, 0x60, 0xb1, 0xb0, 0x0, + 0x6, 0xc, 0x52, 0x16, 0x8, 0x50, 0x0, 0x0, + 0xc, 0x0, 0x6, 0x5b, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xf6, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x19, 0x4a, 0x92, 0x0, 0x0, 0xc, 0x5, 0x70, + 0x0, 0x6e, 0xc2, 0x0, 0x4, 0x30, 0x0, 0x0, + 0x0, 0x10, + + /* U+5920 "夠" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x77, + 0x58, 0xc4, 0x90, 0x0, 0x10, 0x5, 0x84, 0xc, + 0x2a, 0x55, 0x55, 0xd0, 0x11, 0x6, 0xa3, 0x53, + 0x0, 0x0, 0xb0, 0x0, 0x9, 0x52, 0x42, 0x0, + 0x40, 0xb0, 0x4, 0x77, 0xa0, 0x1b, 0x55, 0xc0, + 0xb0, 0x11, 0x2b, 0x57, 0xeb, 0x0, 0xb0, 0xb0, + 0x1, 0xb1, 0x9, 0x5a, 0x0, 0xb0, 0xb0, 0x16, + 0x1b, 0x2b, 0xb, 0x55, 0xb1, 0xa0, 0x0, 0x3, + 0xb2, 0x0, 0x0, 0x3, 0x80, 0x0, 0x19, 0x30, + 0x0, 0x12, 0x17, 0x60, 0x4, 0x60, 0x0, 0x0, + 0x5, 0xde, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+5927 "大" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x2, 0x10, 0x6, 0x55, 0x55, 0xe5, + 0x55, 0x59, 0x80, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x87, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x31, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0xa, 0x40, 0x0, 0x0, 0x1a, 0x30, + 0x0, 0x1, 0xda, 0x30, 0x5, 0x70, 0x0, 0x0, + 0x0, 0xa, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5929 "天" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x45, 0x55, 0x55, 0x55, 0xd4, 0x0, 0x0, 0x10, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0x1b, 0x10, 0x6, 0x55, 0x56, 0xc8, 0x55, 0x55, + 0x30, 0x0, 0x0, 0x6, 0x75, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x21, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x3a, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x1c, 0x30, 0x0, 0x0, 0x9, 0x10, + 0x0, 0x3, 0xe8, 0x20, 0x3, 0x70, 0x0, 0x0, + 0x0, 0x2c, 0xa1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+592A "太" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x3, 0x10, 0x5, 0x65, 0x55, 0xd7, + 0x55, 0x5a, 0x70, 0x0, 0x0, 0x0, 0xd6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xa2, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x50, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x65, 0x0, 0x0, 0x0, + 0x0, 0x87, 0x10, 0xc, 0x10, 0x0, 0x0, 0x4, + 0x80, 0xb5, 0x3, 0xc1, 0x0, 0x0, 0x47, 0x0, + 0x1e, 0x0, 0x6e, 0x60, 0x5, 0x30, 0x0, 0x2, + 0x0, 0x6, 0x71, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+592B "夫" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x93, 0x0, 0x1, 0x0, 0x0, 0x55, 0x55, + 0xb7, 0x55, 0x87, 0x0, 0x0, 0x0, 0x0, 0xa3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x2, 0x0, 0x6, 0x55, 0x55, 0xd6, 0x55, 0x5b, + 0x80, 0x0, 0x0, 0x1, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x70, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0xb, 0x20, 0x0, 0x0, 0x19, 0x20, + 0x0, 0x2, 0xe7, 0x10, 0x4, 0x50, 0x0, 0x0, + 0x0, 0x2c, 0x80, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+592E "央" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, + 0x7c, 0x55, 0xc2, 0x0, 0x0, 0xd, 0x0, 0x39, + 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x39, 0x0, + 0xd0, 0x0, 0x0, 0xd, 0x0, 0x48, 0x0, 0xd0, + 0x10, 0x4, 0x6b, 0x55, 0x9a, 0x55, 0xb8, 0xb0, + 0x0, 0x0, 0x0, 0x94, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xc0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x1b, 0x10, 0x0, 0x0, 0x2, 0x93, + 0x0, 0x2, 0xd7, 0x20, 0x2, 0x65, 0x0, 0x0, + 0x0, 0x1a, 0xb1, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5931 "失" */ + 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x20, 0x93, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x55, + 0xb7, 0x55, 0xd4, 0x0, 0x0, 0x72, 0x0, 0xa3, + 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x9, + 0x30, 0x6, 0x55, 0x55, 0xd8, 0x55, 0x55, 0x40, + 0x0, 0x0, 0x4, 0x83, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x10, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x6, 0x70, + 0x0, 0x4, 0xc4, 0x0, 0x2, 0x73, 0x0, 0x0, + 0x0, 0x4e, 0x90, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+5947 "奇" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x0, 0x55, + 0x55, 0xd6, 0x55, 0x7b, 0x0, 0x0, 0x10, 0x5, + 0x96, 0x30, 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, + 0x5c, 0x80, 0x0, 0x0, 0x46, 0x30, 0x0, 0x0, + 0x92, 0x80, 0x6, 0x55, 0x55, 0x55, 0x55, 0xc5, + 0x62, 0x0, 0x3, 0x0, 0x4, 0x0, 0xc0, 0x0, + 0x0, 0xd, 0x55, 0x5d, 0x10, 0xc0, 0x0, 0x0, + 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xd, + 0x55, 0x5d, 0x0, 0xc0, 0x0, 0x0, 0xa, 0x0, + 0x5, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5d, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+5951 "契" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x10, 0x0, 0x0, 0x20, 0x3, 0x65, + 0xc5, 0x93, 0x6b, 0x56, 0xd0, 0x0, 0x0, 0xb1, + 0x30, 0xc, 0x2, 0xa0, 0x0, 0x65, 0xc5, 0x40, + 0x48, 0x4, 0x80, 0x3, 0x55, 0xc5, 0xa2, 0xb1, + 0x6, 0x60, 0x0, 0x0, 0xb0, 0x8, 0x33, 0x6c, + 0x20, 0x0, 0x0, 0xc1, 0x70, 0x0, 0x55, 0x0, + 0x0, 0x0, 0x0, 0x95, 0x0, 0x5, 0x40, 0x5, + 0x65, 0x55, 0xd8, 0x55, 0x55, 0x50, 0x0, 0x0, + 0x7, 0x50, 0x80, 0x0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x1a, 0x60, 0x0, 0x0, 0x58, 0x30, 0x0, + 0x0, 0x8e, 0xb2, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x10, + + /* U+5957 "套" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xd1, 0x0, 0x2, 0x0, 0x2, 0x65, + 0x5c, 0x85, 0x65, 0x5b, 0x20, 0x0, 0x0, 0x59, + 0x0, 0x53, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, + 0x1a, 0x60, 0x0, 0x0, 0x56, 0xc5, 0x55, 0x66, + 0x7e, 0x91, 0x15, 0x20, 0xc5, 0x55, 0x79, 0x2, + 0x20, 0x0, 0x0, 0xc0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x55, 0x58, 0x30, 0x0, 0x5, + 0x55, 0xd5, 0x55, 0x55, 0x5c, 0x90, 0x1, 0x0, + 0xa, 0x60, 0x30, 0x0, 0x0, 0x0, 0x0, 0x73, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x9, 0xc9, 0x76, + 0x54, 0x87, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+5973 "女" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xa0, 0x0, 0x0, 0x10, 0x5, 0x55, 0x5a, 0x85, + 0x55, 0x59, 0xc0, 0x0, 0x0, 0xc, 0x0, 0xb, + 0x40, 0x0, 0x0, 0x0, 0x48, 0x0, 0xe, 0x0, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x69, 0x0, 0x0, + 0x0, 0x1, 0xd1, 0x0, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0x16, 0x89, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0xab, 0x50, 0x0, 0x0, 0x0, 0x8, + 0x80, 0x3, 0xdb, 0x0, 0x0, 0x36, 0x71, 0x0, + 0x0, 0xa, 0x10, 0x3, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5979 "她" */ + 0x0, 0x3, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x14, 0xb, 0x0, 0x0, 0x0, 0x38, 0x3, + 0x2a, 0xb, 0x1, 0x0, 0x6, 0x98, 0x6b, 0x19, + 0xc, 0x5d, 0x20, 0x0, 0x73, 0x38, 0x7b, 0x5b, + 0xb, 0x0, 0x0, 0xa0, 0x65, 0x19, 0xb, 0xc, + 0x0, 0x0, 0xa0, 0x82, 0x19, 0xb, 0xc, 0x0, + 0x0, 0x90, 0xb0, 0x19, 0xb, 0x5c, 0x0, 0x2, + 0x93, 0xa0, 0x19, 0xc, 0x24, 0x10, 0x0, 0xa, + 0xc3, 0x19, 0xb, 0x0, 0x50, 0x0, 0x27, 0x1d, + 0x2a, 0x0, 0x0, 0x90, 0x2, 0x70, 0x1, 0xd, + 0xa9, 0x9a, 0xd1, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+597D "好" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0xc, + 0x0, 0x25, 0x55, 0x6e, 0x30, 0x0, 0x29, 0x3, + 0x0, 0x0, 0x81, 0x0, 0x15, 0x99, 0x5d, 0x10, + 0x8, 0x30, 0x0, 0x0, 0x92, 0xb, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xa0, 0x38, 0x0, 0xc, 0x0, + 0x70, 0x0, 0x90, 0x75, 0x55, 0x5d, 0x55, 0x51, + 0x4, 0x50, 0xb0, 0x0, 0xc, 0x0, 0x0, 0x2, + 0x67, 0xb0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x9, + 0xba, 0x0, 0xc, 0x0, 0x0, 0x0, 0x65, 0x8, + 0x40, 0xc, 0x0, 0x0, 0x6, 0x30, 0x0, 0x6, + 0xbc, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x31, + 0x0, 0x0, + + /* U+5982 "如" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x50, 0x95, 0x55, 0xc0, 0x6, 0x5d, 0x55, 0xd0, + 0xb0, 0x0, 0xb0, 0x0, 0x29, 0x2, 0xa0, 0xb0, + 0x0, 0xb0, 0x0, 0x65, 0x5, 0x70, 0xb0, 0x0, + 0xb0, 0x0, 0x91, 0x8, 0x40, 0xb0, 0x0, 0xb0, + 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, 0xb0, 0x0, + 0x57, 0x7b, 0x0, 0xb0, 0x0, 0xb0, 0x0, 0x0, + 0x9b, 0xa0, 0xc5, 0x55, 0xb0, 0x0, 0x7, 0x40, + 0x73, 0xb0, 0x0, 0xb0, 0x2, 0x72, 0x0, 0x0, + 0x40, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5987 "妇" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x12, 0x22, 0x22, 0x60, 0x0, 0x2a, 0x2, + 0x44, 0x33, 0x34, 0xb0, 0x5, 0x89, 0x5b, 0x50, + 0x0, 0x2, 0xa0, 0x0, 0x83, 0xb, 0x0, 0x0, + 0x2, 0xa0, 0x0, 0xb0, 0xb, 0x6, 0x55, 0x56, + 0xa0, 0x0, 0xb0, 0x1a, 0x0, 0x0, 0x2, 0xa0, + 0x1, 0x92, 0x65, 0x0, 0x0, 0x2, 0xa0, 0x0, + 0x6, 0xe4, 0x0, 0x0, 0x2, 0xa0, 0x0, 0x3, + 0x9c, 0x30, 0x0, 0x2, 0xa0, 0x0, 0x19, 0x1, + 0x46, 0x55, 0x56, 0xa0, 0x1, 0x70, 0x0, 0x0, + 0x0, 0x1, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+59B3 "妳" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x58, + 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x83, 0x3, + 0xd, 0x44, 0x44, 0x70, 0x36, 0xd5, 0x7b, 0x37, + 0x0, 0x5, 0x90, 0x0, 0xb0, 0x56, 0x70, 0x6, + 0x15, 0x0, 0x5, 0x60, 0x93, 0x20, 0xc, 0x0, + 0x0, 0x9, 0x10, 0xc0, 0x7, 0x1c, 0x3, 0x0, + 0xb, 0x1, 0xa0, 0x1c, 0xc, 0x7, 0x50, 0x1, + 0x7b, 0x60, 0x63, 0xc, 0x0, 0xd1, 0x0, 0x1b, + 0xc6, 0x50, 0xc, 0x0, 0x50, 0x0, 0x91, 0x5, + 0x0, 0xc, 0x0, 0x0, 0x7, 0x10, 0x0, 0x3, + 0xad, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x12, + 0x0, 0x0, + + /* U+59B9 "妹" */ + 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x38, 0x4, + 0x26, 0x5c, 0x58, 0x40, 0x6, 0xa7, 0x5d, 0x0, + 0xb, 0x0, 0x0, 0x0, 0xa0, 0x29, 0x0, 0xb, + 0x0, 0x50, 0x0, 0xa0, 0x56, 0x65, 0xbd, 0x75, + 0x52, 0x3, 0x60, 0x92, 0x0, 0xcb, 0x60, 0x0, + 0x7, 0x40, 0xb0, 0x6, 0x5b, 0x61, 0x0, 0x0, + 0x5a, 0x90, 0xa, 0xb, 0x19, 0x0, 0x0, 0x9, + 0x96, 0x72, 0xb, 0x8, 0x80, 0x0, 0x62, 0x6, + 0x30, 0xb, 0x0, 0xb5, 0x4, 0x30, 0x2, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+59BB "妻" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc1, 0x0, 0x9, 0x20, 0x6, 0x55, + 0x55, 0xd5, 0x55, 0x55, 0x30, 0x0, 0x25, 0x55, + 0xd5, 0x55, 0x90, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x1, 0xa0, 0x40, 0x7, 0x55, 0x55, 0xd5, 0x56, + 0xc6, 0x81, 0x0, 0x0, 0x0, 0xc0, 0x1, 0xb0, + 0x0, 0x0, 0x36, 0x5c, 0x65, 0x55, 0x70, 0x0, + 0x25, 0x55, 0x6d, 0x55, 0x55, 0x57, 0xc1, 0x1, + 0x0, 0x92, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x1, + 0x85, 0x56, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x99, 0x9c, 0x92, 0x0, 0x3, 0x55, 0x66, 0x10, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+59C9 "姉" */ + 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3, + 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x66, 0x0, + 0x0, 0xb, 0x0, 0x0, 0xa, 0x20, 0x25, 0x55, + 0xc5, 0x95, 0x36, 0xd5, 0x89, 0x10, 0xb, 0x0, + 0x0, 0x29, 0x7, 0x52, 0x0, 0xb0, 0x30, 0x6, + 0x50, 0xa1, 0xb5, 0x5c, 0x5b, 0x20, 0xa0, 0xb, + 0xb, 0x0, 0xb0, 0xa1, 0xb, 0x3, 0x80, 0xb0, + 0xb, 0xa, 0x10, 0x38, 0xc4, 0xb, 0x0, 0xb0, + 0xa1, 0x0, 0x2a, 0xc5, 0xb0, 0xb, 0x4c, 0x10, + 0x9, 0x0, 0x54, 0x0, 0xb3, 0x70, 0x7, 0x10, + 0x0, 0x0, 0xc, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x20, 0x0, + + /* U+59CB "始" */ + 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x0, 0x97, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x47, 0x3, + 0x5, 0x50, 0x43, 0x0, 0x16, 0xb7, 0x5e, 0x19, + 0x0, 0xb, 0x40, 0x0, 0xb0, 0x1a, 0x8c, 0x86, + 0x56, 0xc0, 0x1, 0x90, 0x57, 0x13, 0x0, 0x0, + 0x30, 0x6, 0x50, 0x92, 0x7, 0x55, 0x59, 0x20, + 0x9, 0x20, 0xc0, 0xc, 0x0, 0xb, 0x0, 0x0, + 0x5b, 0xa0, 0xc, 0x0, 0xb, 0x0, 0x0, 0xb, + 0x9b, 0xc, 0x0, 0xb, 0x0, 0x0, 0x82, 0x8, + 0xd, 0x55, 0x5d, 0x0, 0x6, 0x20, 0x0, 0xc, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+59D0 "姐" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x8, 0x55, 0x59, 0x10, 0x0, 0x1c, + 0x0, 0xc, 0x0, 0xc, 0x0, 0x2, 0x69, 0x26, + 0xc, 0x0, 0xc, 0x0, 0x3, 0xa5, 0x3d, 0x1c, + 0x0, 0xc, 0x0, 0x0, 0xb0, 0xb, 0xd, 0x55, + 0x5d, 0x0, 0x1, 0x90, 0x48, 0xc, 0x0, 0xc, + 0x0, 0x6, 0x40, 0x83, 0xc, 0x0, 0xc, 0x0, + 0x9, 0x20, 0xb0, 0xd, 0x55, 0x5d, 0x0, 0x0, + 0x4a, 0xb0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xb, + 0x6c, 0x1c, 0x0, 0xc, 0x0, 0x0, 0x82, 0x4, + 0x2c, 0x0, 0xc, 0x20, 0x6, 0x10, 0x5, 0x68, + 0x55, 0x58, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+59D4 "委" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, + 0x3, 0x46, 0x79, 0x99, 0x81, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x10, 0x5, 0x65, 0x55, + 0x9c, 0x65, 0x57, 0xc1, 0x0, 0x0, 0xa, 0x7a, + 0x62, 0x0, 0x0, 0x0, 0x1, 0xa4, 0x1a, 0x8, + 0x92, 0x0, 0x0, 0x57, 0x10, 0x57, 0x0, 0x4d, + 0xd3, 0x4, 0x10, 0x5, 0xc0, 0x0, 0x0, 0x50, + 0x7, 0x55, 0x6c, 0x65, 0x5a, 0x56, 0xa2, 0x0, + 0x0, 0xa3, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, + 0x55, 0x77, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6a, 0x7d, 0xa3, 0x0, 0x0, 0x25, 0x68, 0x30, + 0x0, 0x6e, 0x20, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x1, 0x10, + + /* U+5A18 "娘" */ + 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xb, 0x50, 0x0, 0x1c, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x8, 0x5b, 0x59, 0x10, 0x2, 0x4b, 0x36, + 0xb, 0x0, 0xb, 0x0, 0x3, 0x77, 0x2c, 0x1c, + 0x55, 0x5c, 0x0, 0x0, 0x92, 0xb, 0xb, 0x0, + 0xb, 0x0, 0x0, 0xb0, 0x28, 0xb, 0x0, 0xb, + 0x0, 0x1, 0x90, 0x64, 0xc, 0x58, 0x59, 0x10, + 0x4, 0x70, 0xa0, 0xb, 0x7, 0x6, 0xa0, 0x0, + 0x39, 0xc0, 0xb, 0x7, 0x65, 0x0, 0x0, 0x9, + 0x8c, 0xb, 0x2, 0xc1, 0x0, 0x0, 0x56, 0x4, + 0xc, 0x83, 0x4d, 0x71, 0x5, 0x50, 0x0, 0xc, + 0x10, 0x2, 0x81, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5A5A "婚" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x1d, 0x0, 0x22, 0x58, 0xb8, 0x0, 0x0, 0x48, + 0x0, 0xb3, 0x1b, 0x0, 0x0, 0x0, 0x74, 0x2, + 0xa1, 0x1b, 0x11, 0x50, 0x15, 0xc5, 0x88, 0xa4, + 0x4a, 0x64, 0x40, 0x0, 0xb0, 0x74, 0xa0, 0x23, + 0xa0, 0x40, 0x3, 0x70, 0xa1, 0xd9, 0x30, 0x5b, + 0xb0, 0x7, 0x30, 0xb0, 0x40, 0x0, 0x6, 0xa1, + 0xa, 0x12, 0x80, 0x97, 0x55, 0x5d, 0x10, 0x0, + 0x6c, 0x50, 0x93, 0x0, 0xb, 0x0, 0x0, 0x29, + 0xc4, 0x87, 0x55, 0x5c, 0x0, 0x0, 0x80, 0x16, + 0x93, 0x0, 0xb, 0x0, 0x6, 0x0, 0x0, 0x97, + 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+5A66 "婦" */ + 0x0, 0x11, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x5a, 0x0, 0x55, 0x55, 0x5d, 0x10, 0x0, 0x84, + 0x0, 0x15, 0x55, 0x5c, 0x0, 0x12, 0xb2, 0x42, + 0x1, 0x0, 0xb, 0x0, 0x15, 0xc3, 0xa6, 0x46, + 0x55, 0x5c, 0x0, 0x2, 0x80, 0xb4, 0x0, 0x0, + 0x0, 0x30, 0x7, 0x40, 0xb8, 0x55, 0x6b, 0x56, + 0xc1, 0xa, 0x1, 0x99, 0x20, 0x1a, 0x5, 0x0, + 0xa, 0x6, 0x50, 0xb5, 0x6b, 0x5d, 0x10, 0x0, + 0x7e, 0x30, 0xb0, 0x1a, 0xb, 0x0, 0x0, 0x38, + 0xc3, 0xb0, 0x1a, 0xb, 0x0, 0x1, 0x80, 0x13, + 0xb0, 0x1a, 0x6c, 0x0, 0x15, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+5A92 "媒" */ + 0x0, 0x3, 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, + 0xe, 0x10, 0x1c, 0x0, 0xd, 0x0, 0x0, 0x2a, + 0x3, 0x5c, 0x55, 0x5c, 0x91, 0x1, 0x67, 0x15, + 0xa, 0x0, 0xb, 0x0, 0x5, 0xb5, 0x5b, 0xc, + 0x55, 0x5b, 0x0, 0x0, 0xb0, 0x47, 0xa, 0x0, + 0xb, 0x0, 0x1, 0xa0, 0x73, 0x1c, 0x55, 0x5b, + 0x0, 0x4, 0x50, 0xa0, 0x2, 0x1c, 0x0, 0x0, + 0x7, 0x30, 0xa3, 0x65, 0x8d, 0x55, 0xa0, 0x0, + 0x4b, 0x80, 0x3, 0xbb, 0x50, 0x0, 0x0, 0x1a, + 0x97, 0x1b, 0x2a, 0x63, 0x0, 0x0, 0x81, 0x4, + 0x91, 0x1a, 0xa, 0x81, 0x6, 0x20, 0x36, 0x0, + 0x1b, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+5ABD "媽" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0xa5, 0x58, 0x58, 0x60, 0x0, 0x67, + 0x0, 0xb0, 0xb, 0x0, 0x0, 0x0, 0x93, 0x2, + 0xb5, 0x5c, 0x59, 0x20, 0x26, 0xd5, 0x88, 0xb0, + 0xb, 0x0, 0x0, 0x1, 0xa0, 0x74, 0xb5, 0x5c, + 0x58, 0x40, 0x5, 0x60, 0xa1, 0xb0, 0xb, 0x0, + 0x0, 0x9, 0x20, 0xb0, 0xb5, 0x5b, 0x55, 0xa2, + 0xb, 0x3, 0x80, 0x40, 0x0, 0x20, 0xc0, 0x2, + 0x7c, 0x50, 0x24, 0x8, 0x29, 0xc0, 0x0, 0x1a, + 0xb4, 0x84, 0x78, 0x3a, 0xc0, 0x0, 0x80, 0x7, + 0x72, 0x51, 0x1, 0xc0, 0x6, 0x10, 0x0, 0x0, + 0x3, 0x9e, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, + + /* U+5ACC "嫌" */ + 0x0, 0x42, 0x0, 0x10, 0x0, 0x40, 0x0, 0x0, + 0xa4, 0x0, 0xb, 0x4, 0x80, 0x0, 0x0, 0xb0, + 0x5, 0x5a, 0x59, 0x5a, 0x40, 0x13, 0xc3, 0x73, + 0xa, 0xa, 0x0, 0x0, 0x15, 0x92, 0xc1, 0x6c, + 0x5c, 0x5a, 0x0, 0x5, 0x50, 0xb0, 0xa, 0xa, + 0xa, 0x0, 0x8, 0x12, 0x85, 0x5c, 0x5c, 0x5c, + 0x80, 0xa, 0x5, 0x40, 0xa, 0xa, 0xa, 0x0, + 0xa, 0x19, 0x2, 0x7f, 0x5c, 0x79, 0x0, 0x0, + 0x7d, 0x20, 0x7d, 0xa, 0x60, 0x0, 0x0, 0x84, + 0xa3, 0x6a, 0xa, 0x27, 0x0, 0x4, 0x50, 0x16, + 0xa, 0xa, 0x9, 0x90, 0x24, 0x0, 0x30, 0xa, + 0xb, 0x0, 0x20, 0x0, 0x0, 0x0, 0x2, 0x1, + 0x0, 0x0, + + /* U+5B09 "嬉" */ + 0x0, 0x10, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0x68, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x92, + 0x3, 0x65, 0x6b, 0x57, 0x70, 0x0, 0xb0, 0x31, + 0x12, 0x4a, 0x27, 0x0, 0x36, 0xc5, 0xb3, 0x43, + 0x22, 0x25, 0x0, 0x4, 0x70, 0xb0, 0xa5, 0x55, + 0x5d, 0x0, 0x8, 0x30, 0xb0, 0xa5, 0x55, 0x5c, + 0x0, 0xb, 0x3, 0x80, 0x25, 0x10, 0x72, 0x0, + 0xa, 0x8, 0x32, 0x26, 0x82, 0x72, 0x60, 0x5, + 0x8d, 0x4, 0x53, 0x33, 0x36, 0x30, 0x0, 0x69, + 0xd0, 0xb5, 0x55, 0x5d, 0x10, 0x1, 0x90, 0x30, + 0xb0, 0x0, 0xb, 0x0, 0x17, 0x0, 0x0, 0xb5, + 0x55, 0x5c, 0x0, 0x10, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+5B50 "子" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0x55, 0x55, 0x55, 0x7c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xb5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, + 0x0, 0x50, 0x6, 0x55, 0x55, 0x6c, 0x55, 0x56, + 0x92, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+5B57 "字" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x7, 0x0, 0x2, 0x60, 0x0, 0xa5, 0x55, + 0x55, 0x55, 0x5a, 0x90, 0x3, 0xc3, 0x55, 0x55, + 0x56, 0x73, 0x0, 0x0, 0x0, 0x10, 0x0, 0x2b, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x3, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x70, + 0x6, 0x55, 0x55, 0x6c, 0x55, 0x55, 0x72, 0x0, + 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xe8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+5B58 "存" */ + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x3, 0x0, 0x6, 0x55, + 0x5d, 0x65, 0x55, 0x6b, 0x30, 0x0, 0x0, 0x39, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x55, + 0x55, 0x95, 0x0, 0x0, 0x9, 0x60, 0x0, 0x4, + 0x82, 0x0, 0x0, 0x2e, 0x10, 0x0, 0x85, 0x0, + 0x0, 0x0, 0x9b, 0x10, 0x0, 0xc0, 0x0, 0x0, + 0x8, 0x1a, 0x26, 0x55, 0xd5, 0x58, 0x80, 0x30, + 0xa, 0x10, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa, + 0x10, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa, 0x20, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x20, 0x3b, + 0xd0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x10, + 0x0, 0x0, + + /* U+5B63 "季" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x2, 0x47, 0xac, 0xc2, 0x0, 0x0, 0x3, + 0x43, 0x3a, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, + 0x5c, 0x55, 0x56, 0xd2, 0x0, 0x0, 0x8, 0x8a, + 0x71, 0x0, 0x0, 0x0, 0x0, 0x95, 0x1a, 0x9, + 0x71, 0x0, 0x0, 0x58, 0x10, 0x18, 0x0, 0x6d, + 0xd4, 0x4, 0x11, 0x65, 0x55, 0x5c, 0xa0, 0x20, + 0x0, 0x0, 0x0, 0x6, 0x61, 0x0, 0x0, 0x4, + 0x55, 0x55, 0x5d, 0x55, 0x58, 0xd1, 0x1, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+5B66 "学" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x8, + 0x0, 0xa0, 0x0, 0xe2, 0x0, 0x0, 0x6b, 0x9, + 0x70, 0x66, 0x0, 0x0, 0x20, 0x90, 0x32, 0x8, + 0x0, 0x20, 0xa, 0x55, 0x55, 0x55, 0x65, 0x6f, + 0x25, 0xa0, 0x0, 0x0, 0x1, 0x16, 0x20, 0x32, + 0x46, 0x55, 0x55, 0xd8, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x73, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x38, 0x5, 0x65, 0x55, 0x5d, 0x55, 0x55, + 0x51, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6e, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, + + /* U+5B69 "孩" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x11, 0x15, 0x0, 0x59, 0x0, 0x0, 0x2, 0x43, + 0x89, 0x0, 0x9, 0x0, 0x70, 0x0, 0x1, 0x62, + 0x55, 0xd6, 0x55, 0x52, 0x0, 0xc, 0x0, 0x4, + 0x80, 0x21, 0x0, 0x0, 0xb, 0x2, 0x8, 0x0, + 0xc6, 0x0, 0x0, 0xc, 0x73, 0x8a, 0x68, 0xa0, + 0x0, 0x5, 0xac, 0x0, 0x0, 0x1b, 0x8, 0x50, + 0x1a, 0x1b, 0x0, 0x1, 0xa1, 0x3b, 0x0, 0x0, + 0xb, 0x0, 0x38, 0x11, 0xb1, 0x0, 0x0, 0xb, + 0x4, 0x30, 0x2b, 0x74, 0x0, 0x0, 0xb, 0x0, + 0x6, 0x80, 0xa, 0x70, 0x2, 0xc7, 0x25, 0x61, + 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B6B "孫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x14, 0x2, 0x57, 0x9b, 0x50, 0x4, 0x55, + 0xa9, 0x22, 0x88, 0x0, 0x0, 0x0, 0x1, 0x60, + 0x1, 0xa0, 0x32, 0x0, 0x0, 0x2b, 0x0, 0x39, + 0x44, 0xc4, 0x0, 0x0, 0x19, 0x0, 0x46, 0x4a, + 0x30, 0x0, 0x0, 0x1b, 0x62, 0x1, 0x91, 0x15, + 0x0, 0x5, 0xab, 0x0, 0x7b, 0x55, 0x58, 0x90, + 0x9, 0x29, 0x0, 0x55, 0x2b, 0x0, 0xa0, 0x0, + 0x19, 0x0, 0x17, 0xb, 0x30, 0x0, 0x0, 0x19, + 0x0, 0x95, 0xb, 0xa, 0x20, 0x0, 0x29, 0x5, + 0x40, 0xb, 0x2, 0xe0, 0x2, 0xd6, 0x11, 0x6, + 0xe9, 0x0, 0x60, 0x0, 0x10, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+5B78 "學" */ + 0x0, 0x0, 0x3, 0x2, 0x20, 0x0, 0x0, 0x0, + 0x29, 0x64, 0x3c, 0x45, 0xb4, 0x0, 0x0, 0x1b, + 0x72, 0x44, 0x65, 0xc1, 0x0, 0x0, 0x9, 0x0, + 0x24, 0x30, 0xa0, 0x0, 0x0, 0xc, 0x65, 0x3e, + 0x15, 0xc0, 0x0, 0x4, 0xa, 0x0, 0x53, 0x40, + 0xb0, 0x30, 0xa, 0x55, 0x55, 0x55, 0x55, 0x58, + 0xb0, 0x1c, 0x3, 0x55, 0x55, 0x7b, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x4, + 0x55, 0x55, 0x6e, 0x55, 0x5b, 0x90, 0x1, 0x0, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+5B83 "它" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x28, 0x0, 0x1, 0x20, 0x3, 0x95, 0x55, + 0x55, 0x55, 0x5b, 0xb0, 0xc, 0x50, 0x0, 0x0, + 0x0, 0x7, 0x0, 0x2, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x2c, 0x20, + 0x0, 0x0, 0x0, 0xc0, 0x17, 0xa4, 0x10, 0x0, + 0x0, 0x0, 0xd5, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xab, 0xaa, + 0xaa, 0xbc, 0x20, + + /* U+5B85 "宅" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x36, 0x0, 0x1, 0x20, 0x0, 0xa5, 0x55, + 0x55, 0x55, 0x5a, 0x90, 0x3, 0xc0, 0x0, 0x3, + 0x9d, 0x27, 0x0, 0x0, 0x34, 0x57, 0xd6, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x2, 0x6e, 0x40, + 0x0, 0x14, 0x55, 0xd5, 0x53, 0x10, 0x0, 0x6, + 0x31, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0xbb, + 0xaa, 0xab, 0xc0, + + /* U+5B87 "宇" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x0, 0x0, 0x3, 0x0, 0x1, + 0x70, 0x0, 0x23, 0x0, 0xa5, 0x55, 0x55, 0x55, + 0x5b, 0x80, 0x2c, 0x0, 0x0, 0x0, 0x2, 0x50, + 0x0, 0x5, 0x55, 0x58, 0x56, 0xa1, 0x0, 0x0, + 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x3, 0x80, 0x55, 0x55, 0x56, 0xc5, + 0x55, 0x55, 0x10, 0x0, 0x0, 0x1a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x8f, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x0, + + /* U+5B88 "守" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x29, 0x0, 0x2, 0x0, 0xa, 0x55, 0x55, 0x55, + 0x55, 0xe7, 0x4, 0xb0, 0x0, 0x0, 0xa2, 0x35, + 0x0, 0x10, 0x0, 0x0, 0xd, 0x0, 0x20, 0x5, + 0x55, 0x55, 0x55, 0xe5, 0x5a, 0x70, 0x0, 0x40, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0xb, 0x40, 0xd, 0x0, + 0x0, 0x0, 0x0, 0x30, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x0, + + /* U+5B89 "安" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x8, 0x0, 0x3, 0x10, 0x0, 0x95, 0x55, + 0x55, 0x55, 0x5c, 0x60, 0x2, 0xb0, 0x3, 0x60, + 0x0, 0x14, 0x0, 0x0, 0x0, 0x8, 0x50, 0x0, + 0x0, 0x10, 0x5, 0x55, 0x5d, 0x55, 0x57, 0x59, + 0x90, 0x0, 0x0, 0x57, 0x0, 0x1d, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x86, 0x0, 0x0, 0x0, + 0x1, 0x86, 0x33, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5e, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xa2, 0x6, 0xd8, 0x0, 0x0, 0x36, 0x84, 0x0, + 0x0, 0x1a, 0x50, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B8C "完" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x40, + 0x0, 0x26, 0x0, 0x0, 0x30, 0x0, 0xb5, 0x55, + 0x55, 0x55, 0x58, 0xa0, 0x3, 0x80, 0x0, 0x0, + 0x4, 0x3, 0x0, 0x0, 0x5, 0x55, 0x55, 0x55, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x1, 0x55, 0x59, 0x55, 0x85, 0x5a, 0x40, + 0x0, 0x0, 0xc, 0x2, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x29, 0x2, 0xa0, 0x0, 0x10, 0x0, 0x0, + 0x84, 0x2, 0xa0, 0x0, 0x50, 0x0, 0x2, 0xa0, + 0x1, 0xa0, 0x0, 0x90, 0x0, 0x67, 0x0, 0x0, + 0xba, 0xaa, 0xd3, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B98 "官" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x20, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x64, 0x0, 0x3, 0x20, 0x68, 0x55, 0x55, 0x55, + 0x55, 0xc7, 0xd, 0x16, 0x55, 0x55, 0x59, 0x23, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xb5, + 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x98, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x6, 0x60, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x66, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x59, 0x50, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, 0x0, + + /* U+5B99 "宙" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x54, 0x0, 0x2, 0x10, 0x95, 0x55, 0x57, 0x55, + 0x55, 0xc7, 0x1d, 0x0, 0x0, 0xc2, 0x0, 0x14, + 0x0, 0x1, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, + 0x96, 0x55, 0xd5, 0x55, 0xe1, 0x0, 0x9, 0x20, + 0xc, 0x0, 0xc, 0x0, 0x0, 0x92, 0x0, 0xc0, + 0x0, 0xc0, 0x0, 0x9, 0x75, 0x5d, 0x55, 0x5c, + 0x0, 0x0, 0x92, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0x9, 0x20, 0xc, 0x0, 0xc, 0x0, 0x0, 0x97, + 0x55, 0x55, 0x55, 0xd0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+5B9A "定" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x85, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, + 0x60, 0x0, 0x13, 0x0, 0xa5, 0x55, 0x55, 0x55, + 0x5a, 0xa0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x50, + 0x0, 0x45, 0x55, 0x55, 0x55, 0x7c, 0x10, 0x1, + 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x5, 0x70, + 0x29, 0x0, 0x0, 0x0, 0x0, 0x87, 0x2, 0xb5, + 0x5b, 0x50, 0x0, 0xa, 0x50, 0x29, 0x0, 0x0, + 0x0, 0x1, 0xa4, 0x32, 0x90, 0x0, 0x0, 0x0, + 0x82, 0x6, 0xaa, 0x10, 0x0, 0x0, 0x44, 0x0, + 0x2, 0x8b, 0xde, 0xf9, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5B9E "实" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x9, 0x0, 0x1, 0x30, 0x0, 0xa5, 0x55, + 0x55, 0x55, 0x5a, 0xc0, 0x8, 0x80, 0x65, 0x7, + 0x70, 0x7, 0x0, 0x2, 0x0, 0xd, 0x18, 0x50, + 0x0, 0x0, 0x0, 0x18, 0x12, 0xa, 0x30, 0x0, + 0x0, 0x0, 0x5, 0xc0, 0xb, 0x10, 0x0, 0x0, + 0x4, 0x55, 0x95, 0x5e, 0x55, 0x58, 0xb0, 0x1, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x87, 0x10, 0x0, 0x0, 0x0, 0x2b, + 0x40, 0x5, 0xe7, 0x0, 0x1, 0x57, 0x60, 0x0, + 0x0, 0x2d, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B9F "実" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x2, 0x20, 0x0, + 0x26, 0x0, 0x5, 0x20, 0x78, 0x55, 0x56, 0x55, + 0x55, 0xd6, 0xd, 0x20, 0x0, 0xa3, 0x0, 0x22, + 0x0, 0x4, 0x55, 0x5c, 0x65, 0x5c, 0x10, 0x0, + 0x10, 0x0, 0xa1, 0x0, 0x20, 0x0, 0x1, 0x55, + 0x5c, 0x65, 0x78, 0x0, 0x4, 0x55, 0x55, 0xc6, + 0x55, 0x6d, 0x20, 0x10, 0x0, 0x1d, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x61, 0x70, 0x0, 0x0, + 0x0, 0x8, 0x90, 0x3, 0xb5, 0x0, 0x1, 0x58, + 0x30, 0x0, 0x2, 0xae, 0x40, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5BA2 "客" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x95, + 0x55, 0x59, 0x55, 0x55, 0xb0, 0x5, 0x80, 0xb, + 0x20, 0x0, 0x6, 0x60, 0x5, 0x10, 0x6c, 0x55, + 0x5b, 0x52, 0x0, 0x0, 0x2, 0x93, 0x30, 0x6a, + 0x0, 0x0, 0x0, 0x27, 0x0, 0x69, 0x90, 0x0, + 0x0, 0x0, 0x30, 0x0, 0x98, 0x94, 0x0, 0x0, + 0x0, 0x0, 0x68, 0x20, 0x7, 0xda, 0x84, 0x4, + 0x56, 0xc5, 0x55, 0x55, 0xc4, 0x70, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x55, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x10, 0x0, + + /* U+5BA4 "室" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x65, + 0x55, 0x79, 0x55, 0x56, 0x10, 0x7, 0x50, 0x0, + 0x0, 0x0, 0x9, 0x10, 0x6, 0x45, 0x55, 0x55, + 0x58, 0xa0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x11, + 0x0, 0x0, 0x0, 0x1, 0x82, 0x0, 0xa, 0x40, + 0x0, 0x0, 0x2f, 0xa8, 0x76, 0x56, 0xe0, 0x0, + 0x0, 0x3, 0x0, 0x84, 0x0, 0x40, 0x0, 0x0, + 0x25, 0x55, 0xb7, 0x56, 0xb0, 0x0, 0x0, 0x1, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x0, 0x0, 0x15, 0x55, 0x55, 0xb7, + 0x55, 0x5b, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5BB3 "害" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x2, 0x85, + 0x55, 0x67, 0x55, 0x59, 0x80, 0xb, 0x30, 0x0, + 0xb2, 0x0, 0x26, 0x0, 0x1, 0x25, 0x55, 0xd5, + 0x55, 0x92, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x50, 0x0, 0x0, 0x25, 0x55, 0xd5, 0x55, 0x51, + 0x0, 0x5, 0x55, 0x55, 0xd5, 0x55, 0x59, 0x90, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x55, 0x75, 0x55, 0xd0, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x55, 0x55, + 0x55, 0xb0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x50, 0x0, + + /* U+5BB5 "宵" */ + 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb4, 0x0, 0x0, 0x0, 0x7, 0x55, 0x57, + 0x75, 0x55, 0x68, 0x3, 0x92, 0x0, 0x64, 0x1, + 0x16, 0x40, 0x42, 0x2c, 0x2a, 0x20, 0xa5, 0x10, + 0x0, 0x0, 0x55, 0xa1, 0x53, 0x0, 0x0, 0x0, + 0xa5, 0x59, 0x55, 0x5c, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc5, 0x55, 0x55, + 0x5b, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0xc5, 0x55, 0x55, 0x5b, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb0, + 0x0, 0x6, 0xc9, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x3, 0x0, 0x0, + + /* U+5BB6 "家" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x95, + 0x55, 0x58, 0x55, 0x57, 0xa0, 0x6, 0x80, 0x0, + 0x0, 0x0, 0x7, 0x20, 0x1, 0x5, 0x55, 0x95, + 0x57, 0x70, 0x0, 0x0, 0x0, 0x1b, 0x60, 0x0, + 0x50, 0x0, 0x0, 0x4, 0x81, 0x92, 0x8, 0x71, + 0x0, 0x3, 0x53, 0x6, 0x7b, 0x54, 0x0, 0x0, + 0x0, 0x1, 0x84, 0x1e, 0x37, 0x0, 0x0, 0x1, + 0x56, 0x2, 0xb8, 0x75, 0x60, 0x0, 0x2, 0x0, + 0x49, 0x14, 0x80, 0x99, 0x20, 0x0, 0x37, 0x40, + 0x6, 0x60, 0x7, 0x80, 0x14, 0x20, 0x4, 0xbd, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+5BB9 "容" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x95, + 0x55, 0x58, 0x55, 0x57, 0x70, 0x5, 0x80, 0x40, + 0x0, 0x20, 0x8, 0x30, 0x5, 0x12, 0xc3, 0x42, + 0x3a, 0x51, 0x0, 0x0, 0x29, 0x10, 0xd7, 0x0, + 0xb7, 0x0, 0x2, 0x40, 0xa, 0x54, 0x40, 0x4, + 0x0, 0x0, 0x0, 0x97, 0x0, 0x58, 0x0, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x7, 0xda, 0x61, 0x4, + 0x71, 0xd5, 0x55, 0x5d, 0x36, 0x60, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, + 0x5d, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x1, + 0x0, 0x0, + + /* U+5BBF "宿" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0x0, 0x85, + 0x55, 0x59, 0x55, 0x56, 0x80, 0x3, 0x91, 0x90, + 0x0, 0x0, 0x7, 0x40, 0x5, 0x26, 0x94, 0x55, + 0x55, 0x56, 0xb1, 0x0, 0xb, 0x0, 0x0, 0xa3, + 0x0, 0x0, 0x0, 0x6d, 0x0, 0x20, 0x80, 0x3, + 0x0, 0x1, 0x8c, 0x0, 0xc5, 0x55, 0x5d, 0x0, + 0x6, 0xc, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, + 0xc, 0x0, 0xc5, 0x55, 0x5c, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, 0xc5, + 0x55, 0x5c, 0x0, 0x0, 0x3, 0x0, 0x20, 0x0, + 0x2, 0x0, + + /* U+5BC4 "寄" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x9, 0x55, 0x56, + 0x55, 0x55, 0x89, 0x6, 0x80, 0x0, 0x77, 0x0, + 0x15, 0x0, 0x1, 0x55, 0x6d, 0x65, 0x5a, 0x20, + 0x0, 0x0, 0x1a, 0x33, 0x85, 0x0, 0x0, 0x1, + 0x55, 0x0, 0x0, 0x90, 0x17, 0x5, 0x55, 0x55, + 0x55, 0x55, 0xc5, 0x61, 0x0, 0x95, 0x55, 0xa0, + 0xc, 0x0, 0x0, 0xc, 0x0, 0xb, 0x0, 0xc0, + 0x0, 0x0, 0xd5, 0x55, 0xb0, 0xc, 0x0, 0x0, + 0xb, 0x0, 0x7, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, + + /* U+5BC6 "密" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x95, + 0x55, 0x59, 0x55, 0x55, 0xd1, 0x6, 0x80, 0x0, + 0x71, 0x7, 0x15, 0x20, 0x2, 0x1, 0x49, 0x57, + 0x8a, 0x10, 0x0, 0x0, 0x27, 0x38, 0xa, 0x61, + 0x39, 0x0, 0x0, 0xb3, 0x3c, 0x92, 0x5, 0x9, + 0x60, 0x0, 0x26, 0x9d, 0x99, 0x9c, 0x31, 0x10, + 0x3, 0x20, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, + 0x19, 0x0, 0x1b, 0x0, 0x55, 0x0, 0x0, 0xa, + 0x0, 0xa, 0x0, 0x65, 0x0, 0x0, 0x1a, 0x0, + 0xa, 0x0, 0x65, 0x0, 0x0, 0x28, 0x55, 0x56, + 0x55, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5BCC "富" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0x8, 0x55, 0x55, 0x85, + 0x55, 0x97, 0x49, 0x0, 0x0, 0x0, 0x41, 0x81, + 0x10, 0x35, 0x55, 0x55, 0x53, 0x0, 0x0, 0xa, + 0x55, 0x55, 0xb2, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0xb, 0x55, 0x55, 0x90, 0x0, + 0x0, 0x85, 0x55, 0x55, 0x59, 0x20, 0x0, 0xc0, + 0x1, 0xa0, 0xb, 0x0, 0x0, 0xd5, 0x55, 0xc5, + 0x5d, 0x0, 0x0, 0xc0, 0x1, 0xa0, 0xb, 0x0, + 0x0, 0xd5, 0x55, 0x75, 0x5d, 0x10, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x0, + + /* U+5BD2 "寒" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x39, 0x0, 0x0, 0x10, 0x1, 0x95, + 0x55, 0x57, 0x55, 0x56, 0xd0, 0xa, 0x30, 0x1a, + 0x0, 0xb1, 0x14, 0x10, 0x0, 0x45, 0x6c, 0x55, + 0xc5, 0x93, 0x0, 0x0, 0x0, 0x1a, 0x0, 0xb0, + 0x51, 0x0, 0x0, 0x25, 0x6c, 0x55, 0xc5, 0x52, + 0x0, 0x4, 0x55, 0x6c, 0x55, 0xc5, 0x58, 0xc0, + 0x0, 0x0, 0x68, 0x0, 0x42, 0x0, 0x0, 0x0, + 0x3, 0xa0, 0x78, 0x8, 0x40, 0x0, 0x0, 0x38, + 0x0, 0x7, 0x0, 0x9d, 0x81, 0x4, 0x30, 0x15, + 0x87, 0x20, 0x2, 0x30, 0x0, 0x0, 0x0, 0x5, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5BDD "寝" */ + 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x50, 0x0, 0x0, 0x2, 0x85, 0x55, + 0x66, 0x55, 0x5a, 0x30, 0x84, 0x30, 0x0, 0x0, + 0x2, 0x50, 0x3, 0xb, 0x12, 0x65, 0x55, 0xc1, + 0x0, 0x71, 0xb0, 0x5, 0x55, 0x5c, 0x0, 0x4, + 0x8b, 0x2, 0x65, 0x55, 0xc0, 0x0, 0x1, 0xb0, + 0x53, 0x33, 0x34, 0x60, 0x2, 0x8c, 0x38, 0x11, + 0x12, 0x59, 0x13, 0xb0, 0xb3, 0x27, 0x65, 0x99, + 0x0, 0x0, 0xb, 0x0, 0x7, 0x2a, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x4f, 0x30, 0x0, 0x0, 0xb, + 0x1, 0x65, 0x17, 0xba, 0x60, 0x0, 0x32, 0x20, + 0x0, 0x0, 0x20, + + /* U+5BDF "察" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0xc, 0x0, 0x0, 0x20, 0x0, 0x95, + 0x65, 0x55, 0x55, 0x56, 0xd2, 0x6, 0x71, 0xd1, + 0x11, 0x10, 0x5, 0x10, 0x0, 0xa, 0x75, 0xd5, + 0x85, 0x5d, 0x50, 0x0, 0x57, 0x93, 0xa0, 0x52, + 0x54, 0x0, 0x2, 0x82, 0x5a, 0x10, 0x1a, 0x50, + 0x0, 0x1, 0x8, 0x96, 0x55, 0x74, 0xb7, 0x10, + 0x0, 0x18, 0x10, 0x0, 0x0, 0x89, 0xd2, 0x4, + 0x45, 0x55, 0x6c, 0x55, 0x52, 0x0, 0x0, 0x0, + 0xb4, 0x1a, 0x16, 0x10, 0x0, 0x0, 0x19, 0x30, + 0x1a, 0x0, 0xb6, 0x0, 0x3, 0x60, 0x6, 0xc9, + 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+5BE6 "實" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x84, + 0x44, 0x47, 0x44, 0x48, 0x60, 0x1, 0xb3, 0x55, + 0x55, 0x55, 0x87, 0x0, 0x2, 0x28, 0x52, 0x67, + 0x22, 0xb5, 0x80, 0x5, 0x3b, 0x43, 0x95, 0x36, + 0x93, 0x30, 0x0, 0x9, 0x55, 0x65, 0x57, 0x50, + 0x0, 0x0, 0xa, 0x55, 0x55, 0x55, 0xd0, 0x0, + 0x0, 0xb, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb, + 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x3, 0x29, + 0x0, 0x56, 0x40, 0x0, 0x0, 0x37, 0x72, 0x0, + 0x3, 0xc7, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0x3, 0x0, + + /* U+5BEB "寫" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x8, 0x55, 0x56, + 0x95, 0x55, 0x67, 0x7, 0x50, 0x5, 0x40, 0x0, + 0x26, 0x40, 0x61, 0xa5, 0x41, 0x46, 0x5d, 0x20, + 0x0, 0xc, 0x58, 0x31, 0x55, 0xb0, 0x0, 0x0, + 0xb0, 0x0, 0x1, 0xb, 0x0, 0x0, 0xc, 0x8a, + 0x55, 0x55, 0xa0, 0x0, 0x0, 0x1d, 0x65, 0x55, + 0x55, 0x91, 0x0, 0x38, 0x10, 0x2, 0x14, 0xb, + 0x0, 0x23, 0x60, 0x80, 0x91, 0xb1, 0xb0, 0x0, + 0x2c, 0x8, 0x24, 0x12, 0x39, 0x0, 0x1, 0x20, + 0x0, 0x4, 0xad, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x20, 0x0, + + /* U+5BFA "寺" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x1, 0x55, + 0x55, 0xe5, 0x55, 0x99, 0x0, 0x0, 0x10, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x1, 0x40, 0x36, 0x55, 0x55, 0x85, 0x66, + 0x57, 0x91, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x6, 0x30, + 0x6, 0x57, 0x55, 0x55, 0x6c, 0x55, 0x40, 0x0, + 0x1, 0xb0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + 0x0, 0x0, + + /* U+5BFE "対" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x63, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x1e, + 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6, 0x4, + 0x0, 0x0, 0xc0, 0x0, 0x6, 0x55, 0xc7, 0x35, + 0x55, 0xd5, 0xb0, 0x0, 0x0, 0xd0, 0x1, 0x0, + 0xc0, 0x0, 0x3, 0x21, 0xb0, 0x33, 0x0, 0xc0, + 0x0, 0x0, 0x5a, 0x60, 0xc, 0x20, 0xc0, 0x0, + 0x0, 0xc, 0x90, 0x7, 0x60, 0xc0, 0x0, 0x0, + 0x47, 0xa8, 0x0, 0x0, 0xc0, 0x0, 0x1, 0x90, + 0x1c, 0x0, 0x0, 0xc0, 0x0, 0x18, 0x0, 0x0, + 0x1, 0x32, 0xd0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x3d, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+5C04 "射" */ + 0x0, 0x1, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x6, 0x40, 0x0, 0x0, 0xc2, 0x0, 0x0, 0xa7, + 0x5b, 0x20, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0xb, + 0x10, 0x0, 0xc0, 0x10, 0x0, 0xd5, 0x5c, 0x46, + 0x55, 0xd6, 0xa0, 0x0, 0xc0, 0xb, 0x10, 0x0, + 0xc0, 0x0, 0x0, 0xd5, 0x5c, 0x15, 0x10, 0xc0, + 0x0, 0x0, 0xc0, 0xb, 0x12, 0xc0, 0xc0, 0x0, + 0x16, 0x86, 0xac, 0x10, 0xc0, 0xc0, 0x0, 0x0, + 0x9, 0x4b, 0x10, 0x0, 0xc0, 0x0, 0x0, 0x48, + 0xb, 0x10, 0x0, 0xc0, 0x0, 0x2, 0x80, 0xb, + 0x10, 0x0, 0xc0, 0x0, 0x15, 0x2, 0xad, 0x0, + 0x6d, 0xc0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, + 0x0, 0x0, + + /* U+5C07 "將" */ + 0x0, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x2, + 0x0, 0xd0, 0x1, 0xe1, 0x0, 0x0, 0xb, 0x10, + 0xb0, 0x9, 0x85, 0x5b, 0x60, 0xb, 0x0, 0xb0, + 0x58, 0x70, 0x3c, 0x10, 0xc, 0x55, 0xb3, 0x75, + 0x74, 0xb1, 0x0, 0x3, 0x0, 0xb0, 0x8, 0x2a, + 0x20, 0x0, 0x0, 0x0, 0xb0, 0x6, 0x80, 0xb1, + 0x0, 0x17, 0x95, 0xb3, 0x51, 0x0, 0xb1, 0x60, + 0x0, 0xc0, 0xb5, 0x65, 0x55, 0xc5, 0x50, 0x0, + 0xb0, 0xb0, 0x64, 0x0, 0xb0, 0x0, 0x3, 0x80, + 0xb0, 0x1d, 0x0, 0xb0, 0x0, 0x8, 0x20, 0xb0, + 0x3, 0x0, 0xb0, 0x0, 0x35, 0x0, 0xc0, 0x1, + 0x7d, 0xc0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x2, + 0x10, 0x0, + + /* U+5C08 "專" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x30, 0x3, 0x50, 0x0, 0x65, 0x55, + 0xc5, 0x55, 0x55, 0x0, 0x0, 0xa5, 0x5c, 0x55, + 0x79, 0x0, 0x0, 0xc, 0x0, 0xb1, 0x4, 0x80, + 0x0, 0x0, 0xc5, 0x5c, 0x55, 0x78, 0x0, 0x0, + 0xc, 0x55, 0xc5, 0x57, 0x80, 0x0, 0x0, 0x30, + 0xb, 0x22, 0x97, 0x0, 0x0, 0xac, 0xa8, 0x76, + 0x84, 0x96, 0x0, 0x45, 0x55, 0x55, 0x5c, 0x75, + 0xd7, 0x1, 0x3, 0x40, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0xb, 0x30, 0xa, 0x20, 0x0, 0x0, 0x0, + 0x30, 0x3a, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, + + /* U+5C0D "對" */ + 0x0, 0x3, 0x3, 0x0, 0x0, 0x2, 0x0, 0x1, + 0xc, 0xc, 0x1, 0x0, 0xd, 0x0, 0x8, 0x4a, + 0xa, 0x67, 0x0, 0xb, 0x0, 0x2, 0x4a, 0xc, + 0x42, 0x0, 0xb, 0x0, 0x16, 0x58, 0x59, 0x5a, + 0x10, 0xb, 0x51, 0x0, 0x72, 0xb, 0x10, 0x65, + 0x5c, 0x52, 0x0, 0x38, 0x25, 0x22, 0x30, 0xb, + 0x0, 0x4, 0x66, 0xa5, 0x70, 0xb3, 0xb, 0x0, + 0x0, 0x2, 0x90, 0x0, 0x59, 0xb, 0x0, 0x1, + 0x66, 0xb6, 0x90, 0x1, 0xb, 0x0, 0x0, 0x2, + 0x90, 0x0, 0x0, 0xb, 0x0, 0x0, 0x2, 0xa3, + 0x42, 0x1, 0x1b, 0x0, 0xb, 0xb8, 0x52, 0x0, + 0x5, 0xe8, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+5C0E "導" */ + 0x0, 0x10, 0x0, 0x30, 0x2, 0x0, 0x0, 0x0, + 0x94, 0x0, 0x2a, 0x8, 0x31, 0x0, 0x0, 0x38, + 0x46, 0x58, 0x77, 0x59, 0x60, 0x1, 0x26, 0x9, + 0x57, 0x55, 0x86, 0x0, 0x1, 0x3c, 0xb, 0x55, + 0x55, 0x95, 0x0, 0x0, 0xb, 0xb, 0x44, 0x44, + 0x95, 0x0, 0x0, 0xb, 0xb, 0x55, 0x55, 0x95, + 0x0, 0x1, 0x76, 0x89, 0x21, 0x11, 0x34, 0x41, + 0x2, 0x40, 0x4, 0x79, 0xac, 0xab, 0x70, 0x4, + 0x55, 0x55, 0x55, 0x5e, 0x5a, 0xb0, 0x1, 0x1, + 0x40, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0xa3, + 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x20, 0x5, + 0xb9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+5C0F "小" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x8, 0x10, 0xc0, 0x30, 0x0, 0x0, 0x1e, + 0x20, 0xc0, 0x46, 0x0, 0x0, 0x95, 0x0, 0xc0, + 0x9, 0x70, 0x2, 0x90, 0x0, 0xc0, 0x0, 0xe5, + 0x8, 0x0, 0x0, 0xc0, 0x0, 0x6c, 0x51, 0x0, + 0x0, 0xc0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x1, 0x45, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x0, + + /* U+5C11 "少" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x34, 0xa, 0x22, + 0x10, 0x0, 0x0, 0xa, 0x90, 0xa2, 0x7, 0x91, + 0x0, 0x2, 0xc0, 0xa, 0x20, 0x7, 0xe2, 0x0, + 0xa2, 0x0, 0xa2, 0x0, 0xa, 0x80, 0x54, 0x0, + 0xa, 0x20, 0x29, 0x12, 0x24, 0x0, 0x0, 0xa3, + 0x1d, 0xa1, 0x0, 0x0, 0x0, 0x1, 0x2d, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x6c, 0x30, 0x0, 0x0, + 0x0, 0x5, 0xb7, 0x0, 0x0, 0x0, 0x3, 0x68, + 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C1A "尚" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x11, 0x0, + 0xd, 0x0, 0x5, 0x0, 0x9, 0x60, 0xc, 0x0, + 0x4d, 0x10, 0x0, 0xe3, 0xc, 0x0, 0xa1, 0x0, + 0x20, 0x40, 0xc, 0x5, 0x20, 0x20, 0xc5, 0x55, + 0x57, 0x56, 0x56, 0xc0, 0xc0, 0x2, 0x0, 0x3, + 0x2, 0xa0, 0xc0, 0xc, 0x55, 0x5c, 0x2, 0xa0, + 0xc0, 0xb, 0x0, 0xb, 0x2, 0xa0, 0xc0, 0xb, + 0x0, 0xb, 0x2, 0xa0, 0xc0, 0xc, 0x55, 0x5b, + 0x2, 0xa0, 0xc0, 0x4, 0x0, 0x3, 0x24, 0xa0, + 0xc0, 0x0, 0x0, 0x1, 0x7f, 0x50, 0x10, 0x0, + 0x0, 0x0, 0x2, 0x0, + + /* U+5C24 "尤" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x66, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x30, 0xa, 0x90, 0x0, 0x0, 0x0, 0x8, + 0x30, 0x0, 0x44, 0x0, 0x6, 0x55, 0x5b, 0x78, + 0x55, 0x5b, 0x50, 0x0, 0x0, 0x9, 0x3a, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x2a, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xa, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xa, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x48, 0xa, 0x10, 0x0, 0x10, 0x0, 0x0, + 0xb1, 0xa, 0x10, 0x0, 0x50, 0x0, 0x9, 0x40, + 0xa, 0x20, 0x1, 0x80, 0x1, 0x82, 0x0, 0x6, + 0xdb, 0xbc, 0xb0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C31 "就" */ + 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x3, 0x90, 0x0, 0xb1, 0x30, 0x0, 0x0, 0x0, + 0x70, 0x21, 0xb0, 0x4a, 0x0, 0x5, 0x55, 0x55, + 0x52, 0xb0, 0x6, 0x0, 0x0, 0x75, 0x55, 0x74, + 0xc5, 0x56, 0x90, 0x0, 0xb0, 0x0, 0xb0, 0xb4, + 0x60, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0xb4, 0x60, + 0x0, 0x0, 0xc5, 0xb5, 0xa0, 0xb4, 0x60, 0x0, + 0x0, 0x30, 0xa1, 0x0, 0xb4, 0x60, 0x0, 0x0, + 0xc1, 0xa2, 0x82, 0x84, 0x60, 0x0, 0x5, 0x40, + 0xa0, 0x98, 0x24, 0x60, 0x40, 0x6, 0x0, 0xa0, + 0x8, 0x4, 0x60, 0x80, 0x10, 0x3b, 0x90, 0x70, + 0x2, 0xca, 0xd0, 0x0, 0x1, 0x2, 0x10, 0x0, + 0x0, 0x0, + + /* U+5C3A "尺" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, + 0xd, 0x55, 0x55, 0x55, 0x5d, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0x1b, 0x0, 0x0, 0xd, 0x55, 0x57, + 0x55, 0x5b, 0x0, 0x0, 0xd, 0x0, 0x6, 0x0, + 0x4, 0x0, 0x0, 0xc, 0x0, 0x7, 0x10, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x1, 0x70, 0x0, 0x0, + 0x0, 0x38, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, + 0x82, 0x0, 0x0, 0x1d, 0x40, 0x0, 0x2, 0x80, + 0x0, 0x0, 0x2, 0xe9, 0x20, 0x7, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xe3, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C40 "局" */ + 0x0, 0x8, 0x55, 0x55, 0x55, 0x5a, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, + 0x55, 0x55, 0x59, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x30, 0x0, 0xd, 0x55, 0x55, 0x55, + 0x55, 0xd0, 0x0, 0x1a, 0x7, 0x55, 0x58, 0x0, + 0xc0, 0x0, 0x28, 0xb, 0x0, 0xb, 0x0, 0xc0, + 0x0, 0x64, 0xb, 0x0, 0xb, 0x0, 0xc0, 0x0, + 0x90, 0xc, 0x55, 0x5a, 0x1, 0xb0, 0x1, 0x60, + 0x2, 0x0, 0x2, 0x14, 0xa0, 0x5, 0x0, 0x0, + 0x0, 0x1, 0x8f, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C45 "居" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x65, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x83, 0x0, + 0x0, 0x0, 0x38, 0x0, 0x8, 0x75, 0x55, 0x55, + 0x57, 0x90, 0x0, 0x83, 0x0, 0x9, 0x10, 0x13, + 0x0, 0x8, 0x30, 0x0, 0xc0, 0x0, 0x11, 0x0, + 0x87, 0x65, 0x5d, 0x55, 0x58, 0x60, 0xa, 0x10, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa0, 0x20, 0xc, + 0x0, 0x40, 0x0, 0xa, 0xc, 0x66, 0x66, 0x6d, + 0x10, 0x3, 0x50, 0xc0, 0x0, 0x0, 0xc0, 0x0, + 0x70, 0xc, 0x0, 0x0, 0xc, 0x0, 0x23, 0x0, + 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C4A "届" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x65, 0x55, 0x55, 0x55, 0xc0, 0x0, 0x83, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x8, 0x75, 0x55, 0x55, + 0x55, 0xc0, 0x0, 0x83, 0x0, 0x0, 0x30, 0x5, + 0x0, 0x8, 0x30, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x82, 0x65, 0x55, 0xd5, 0x59, 0x30, 0xa, 0x1b, + 0x10, 0xc, 0x0, 0xa1, 0x0, 0xa0, 0xb1, 0x0, + 0xc0, 0xa, 0x10, 0xa, 0xa, 0x65, 0x5d, 0x55, + 0xc1, 0x3, 0x60, 0xa1, 0x0, 0xc0, 0xa, 0x10, + 0x70, 0xb, 0x65, 0x5d, 0x55, 0xc1, 0x14, 0x0, + 0x91, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C4B "屋" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x97, 0x55, 0x55, 0x55, 0x5e, 0x0, 0x0, 0x83, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x87, 0x55, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0x83, 0x0, 0x0, + 0x0, 0x5, 0x0, 0x0, 0x84, 0x65, 0x78, 0x55, + 0x68, 0x10, 0x0, 0x92, 0x0, 0xb5, 0x6, 0x10, + 0x0, 0x0, 0xa1, 0x38, 0x10, 0x2, 0xd5, 0x0, + 0x0, 0xc0, 0x8a, 0x8b, 0x74, 0x4b, 0x0, 0x0, + 0xb0, 0x0, 0xa, 0x20, 0x13, 0x0, 0x3, 0x60, + 0x56, 0x5c, 0x65, 0x66, 0x0, 0x8, 0x0, 0x0, + 0xa, 0x10, 0x0, 0x0, 0x15, 0x5, 0x55, 0x5c, + 0x65, 0x58, 0xc0, 0x10, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C55 "展" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x55, 0x55, 0x55, 0x5d, 0x0, 0x0, 0x83, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x87, 0x55, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0x83, 0x3, 0xa0, + 0x1a, 0x2, 0x0, 0x0, 0x97, 0x57, 0xb5, 0x6b, + 0x69, 0x0, 0x0, 0x92, 0x3, 0x80, 0x1a, 0x0, + 0x0, 0x0, 0xa1, 0x3, 0x80, 0x1a, 0x5, 0x50, + 0x0, 0xb5, 0x5c, 0x59, 0x55, 0x75, 0x40, 0x0, + 0xb0, 0xb, 0x5, 0x32, 0xb3, 0x0, 0x2, 0x70, + 0xb, 0x0, 0xa7, 0x0, 0x0, 0x7, 0x10, 0xb, + 0x55, 0x1b, 0x83, 0x10, 0x15, 0x0, 0x1e, 0x40, + 0x0, 0x6d, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C65 "履" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xa6, 0x55, 0x55, 0x55, 0x5c, 0x10, 0x0, 0x96, + 0x55, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x91, 0x27, + 0x9, 0x30, 0x5, 0x0, 0x0, 0x91, 0x92, 0xc, + 0x55, 0x58, 0x20, 0x0, 0x95, 0x46, 0x6b, 0x55, + 0x5b, 0x0, 0x0, 0xa2, 0x69, 0x5a, 0x55, 0x5a, + 0x0, 0x0, 0xa0, 0xc1, 0xa, 0x0, 0xa, 0x0, + 0x0, 0xa6, 0xc1, 0x7, 0xc6, 0x56, 0x0, 0x0, + 0x92, 0xa0, 0x5, 0xc5, 0x78, 0x0, 0x3, 0x50, + 0xa0, 0x35, 0x42, 0xb2, 0x0, 0x7, 0x0, 0xa0, + 0x20, 0x3d, 0x80, 0x0, 0x13, 0x0, 0x91, 0x47, + 0x50, 0x5b, 0xa0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C6C "屬" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x3, 0x0, 0x9, + 0x75, 0x55, 0x55, 0x55, 0xc0, 0x0, 0x97, 0x55, + 0x56, 0x55, 0x6b, 0x0, 0x9, 0x23, 0x91, 0x92, + 0x57, 0x10, 0x0, 0x96, 0x76, 0x39, 0x15, 0x87, + 0x0, 0x9, 0x47, 0x55, 0x75, 0x55, 0xa0, 0x0, + 0xa2, 0x70, 0x90, 0x90, 0xa, 0x0, 0xb, 0x19, + 0x84, 0x44, 0x44, 0x60, 0x0, 0xa0, 0x96, 0x57, + 0x55, 0x5a, 0x40, 0x9, 0x57, 0x55, 0xb5, 0x91, + 0x91, 0x5, 0x40, 0x95, 0x5a, 0x5c, 0xa, 0x0, + 0x70, 0x4, 0x23, 0xa5, 0x81, 0xa0, 0x14, 0x0, + 0x85, 0x31, 0x6, 0x9a, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+5C71 "山" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x8, 0x10, 0xc, 0x0, 0x0, 0xa1, 0xc, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xc0, + 0xc, 0x0, 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0xe, 0x55, 0x5a, 0x55, 0x55, 0xc0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x80, + + /* U+5CF6 "島" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0x86, 0x56, + 0x55, 0x5c, 0x30, 0x0, 0x9, 0x75, 0x55, 0x55, + 0xc0, 0x0, 0x0, 0x93, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x9, 0x75, 0x55, 0x55, 0xb0, 0x0, 0x0, + 0x97, 0x55, 0x55, 0x55, 0x59, 0x70, 0x9, 0x30, + 0x0, 0x0, 0x0, 0x30, 0x0, 0x76, 0x57, 0x55, + 0x55, 0x5d, 0x10, 0x51, 0x0, 0xd0, 0x5, 0x0, + 0xb0, 0xb, 0x0, 0xb, 0x0, 0xb1, 0xb, 0x0, + 0xb5, 0x55, 0x95, 0x5b, 0x2, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x5b, 0xd3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x0, + + /* U+5D4C "嵌" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x71, 0x0, 0x85, 0x0, 0x18, 0x0, 0x0, 0xb0, + 0x0, 0x74, 0x0, 0x1a, 0x0, 0x0, 0xb5, 0x55, + 0x76, 0x55, 0x5a, 0x0, 0x0, 0x71, 0x8, 0x10, + 0x59, 0x0, 0x0, 0x0, 0xb0, 0xb, 0x41, 0xa3, + 0x0, 0x50, 0x6, 0xc5, 0x5c, 0x54, 0xb5, 0x57, + 0xb0, 0x0, 0xb0, 0xb, 0x8, 0x1c, 0x25, 0x0, + 0x0, 0xb5, 0x5c, 0x12, 0xe, 0x20, 0x0, 0x0, + 0xb0, 0xb, 0x0, 0x58, 0x60, 0x0, 0x0, 0xb0, + 0xb, 0x0, 0xa2, 0x72, 0x0, 0x0, 0xb5, 0x5d, + 0x5, 0x70, 0xc, 0x30, 0x0, 0x80, 0x4, 0x64, + 0x0, 0x3, 0xe4, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+5DDD "川" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0x0, 0xd1, 0x0, 0xa, 0x10, + 0xb, 0x20, 0xc, 0x0, 0x0, 0xa1, 0x0, 0xc0, + 0x0, 0xc0, 0x0, 0xa, 0x10, 0xc, 0x0, 0xc, + 0x0, 0x0, 0xb0, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0xb, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xb0, + 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xa, 0x0, 0xc, + 0x0, 0xc, 0x0, 0x3, 0x70, 0x0, 0xc0, 0x0, + 0xc0, 0x0, 0x71, 0x0, 0xa, 0x0, 0xc, 0x0, + 0x7, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x5, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x10, + + /* U+5DDE "州" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x27, 0x0, 0x20, 0x1, 0xc0, 0x0, 0x2, 0x90, + 0x9, 0x40, 0x1a, 0x0, 0x0, 0x29, 0x0, 0x92, + 0x1, 0xa0, 0x0, 0x3, 0x80, 0x9, 0x20, 0xa, + 0x0, 0x6, 0x47, 0x80, 0x92, 0x91, 0xa0, 0x2, + 0xa5, 0x66, 0x79, 0x29, 0x4a, 0x0, 0x74, 0x65, + 0x23, 0x92, 0x21, 0xa0, 0x0, 0x9, 0x20, 0x9, + 0x20, 0xa, 0x0, 0x0, 0xc0, 0x0, 0x92, 0x0, + 0xa0, 0x0, 0x38, 0x0, 0x9, 0x20, 0xa, 0x0, + 0x9, 0x0, 0x0, 0x71, 0x1, 0xa0, 0x5, 0x30, + 0x0, 0x0, 0x0, 0x1b, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5DE5 "工" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3, + 0x65, 0x55, 0x75, 0x55, 0x8b, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x1, 0x0, 0x15, 0x55, + 0x55, 0xc7, 0x55, 0x5e, 0x80, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+5DE6 "左" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x16, 0x0, 0x46, 0x56, 0xc5, 0x55, + 0x56, 0x81, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xb0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x76, + 0x55, 0xb5, 0x58, 0x10, 0x0, 0x1a, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x8, 0x10, 0x0, 0xc0, 0x0, + 0x0, 0x4, 0x40, 0x0, 0xc, 0x0, 0x0, 0x2, + 0x40, 0x0, 0x0, 0xc0, 0x0, 0x70, 0x0, 0x17, + 0x55, 0x56, 0x55, 0x56, 0x30, + + /* U+5DEE "差" */ + 0x0, 0x1, 0x10, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, + 0x17, 0x0, 0x44, 0x3, 0x50, 0x0, 0x55, 0x55, + 0xb6, 0x55, 0x56, 0x60, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x24, 0x0, 0x0, 0x25, 0x56, 0xc5, 0x55, + 0x55, 0x0, 0x0, 0x0, 0x6, 0x50, 0x0, 0x3, + 0x80, 0x4, 0x55, 0x5d, 0x55, 0x55, 0x55, 0x51, + 0x0, 0x0, 0x56, 0x0, 0x0, 0x11, 0x0, 0x0, + 0x1, 0x95, 0x56, 0xa5, 0x66, 0x0, 0x0, 0x18, + 0x0, 0x2, 0xa0, 0x0, 0x0, 0x1, 0x70, 0x0, + 0x2, 0xa0, 0x0, 0x0, 0x3, 0x4, 0x55, 0x56, + 0xc5, 0x56, 0xd1, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5DF1 "己" */ + 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x65, + 0x55, 0x55, 0x55, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xb5, 0x55, 0x55, 0x55, 0xd0, 0x0, 0xb, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, + 0x0, 0x5, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x70, 0xa, 0x52, 0x22, 0x22, 0x22, 0x6e, 0x0, + 0x29, 0x99, 0x99, 0x99, 0x99, 0x50, + + /* U+5DF2 "已" */ + 0x4, 0x55, 0x55, 0x55, 0x5b, 0x0, 0x1, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x5, 0x10, 0x0, 0x0, 0xc, 0x0, + 0xb, 0x65, 0x55, 0x55, 0x5c, 0x0, 0xb, 0x10, + 0x0, 0x0, 0x9, 0x0, 0xb, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x10, + 0xb, 0x10, 0x0, 0x0, 0x0, 0x50, 0xb, 0x10, + 0x0, 0x0, 0x0, 0x62, 0xa, 0x42, 0x22, 0x22, + 0x22, 0xb8, 0x2, 0x88, 0x88, 0x88, 0x88, 0x72, + + /* U+5E02 "市" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x90, 0x0, 0x19, 0x4, 0x65, 0x55, 0x5d, 0x55, + 0x55, 0x52, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x10, + 0x0, 0xc, 0x55, 0x5d, 0x55, 0x6d, 0x0, 0x0, + 0xc0, 0x0, 0xc0, 0x1, 0xb0, 0x0, 0xc, 0x0, + 0xc, 0x0, 0x1b, 0x0, 0x0, 0xc0, 0x0, 0xc0, + 0x1, 0xb0, 0x0, 0xc, 0x0, 0xc, 0x0, 0x1b, + 0x0, 0x0, 0xc0, 0x0, 0xc0, 0x56, 0xa0, 0x0, + 0xa, 0x0, 0xc, 0x1, 0xb4, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x0, + + /* U+5E03 "布" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x60, 0x0, 0x1, 0x40, 0x5, 0x55, 0x5d, + 0x55, 0x55, 0x56, 0x81, 0x0, 0x0, 0x57, 0x9, + 0x30, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xb, 0x0, + 0x4, 0x0, 0x0, 0x8, 0xe5, 0x5c, 0x55, 0x5d, + 0x0, 0x0, 0x54, 0xc0, 0xb, 0x0, 0xc, 0x0, + 0x4, 0x40, 0xc0, 0xb, 0x0, 0xc, 0x0, 0x12, + 0x0, 0xc0, 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, + 0xc0, 0xb, 0x2, 0x2c, 0x0, 0x0, 0x0, 0xb0, + 0xb, 0x1, 0xc6, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, + + /* U+5E08 "师" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x55, 0x55, 0x55, 0xa5, 0x3, 0xa, 0x11, + 0x0, 0xb0, 0x0, 0x0, 0xa2, 0xa1, 0x0, 0xb, + 0x0, 0x0, 0xa, 0x1a, 0x1a, 0x55, 0xc5, 0x5c, + 0x20, 0xa1, 0xa1, 0xb0, 0xb, 0x0, 0xa0, 0xa, + 0x1a, 0xb, 0x0, 0xb0, 0xa, 0x0, 0xa1, 0xb0, + 0xb0, 0xb, 0x0, 0xa0, 0xa, 0x1b, 0xb, 0x0, + 0xb0, 0xa, 0x0, 0x32, 0x80, 0xb0, 0xb, 0x1, + 0xb0, 0x0, 0x82, 0x7, 0x0, 0xb0, 0x6b, 0x0, + 0x27, 0x0, 0x0, 0xb, 0x0, 0x0, 0x6, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x3, 0x0, 0x0, + + /* U+5E0C "希" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x14, 0x52, 0x3, 0xc8, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xdd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x68, + 0x14, 0xcb, 0x10, 0x0, 0x0, 0x44, 0xc, 0x40, + 0x6, 0x51, 0x0, 0x16, 0x55, 0x7c, 0x55, 0x55, + 0x5b, 0x80, 0x0, 0x0, 0xb1, 0x94, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x85, 0xb7, 0x55, 0x91, 0x0, + 0x0, 0x8c, 0x20, 0x92, 0x0, 0xc0, 0x0, 0x25, + 0x9, 0x20, 0x92, 0x0, 0xc0, 0x0, 0x0, 0x9, + 0x20, 0x92, 0x11, 0xd0, 0x0, 0x0, 0xa, 0x20, + 0x92, 0x2b, 0x90, 0x0, 0x0, 0x1, 0x0, 0xa3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+5E2B "師" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0x0, 0x0, 0x20, 0x23, 0x30, 0x36, + 0x55, 0xa5, 0x58, 0x2c, 0x55, 0x5c, 0x0, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0xb3, 0x54, 0xc4, 0x49, + 0xc, 0x55, 0x5b, 0x55, 0xb, 0x0, 0xb0, 0xb0, + 0x0, 0x45, 0x50, 0xb0, 0xb, 0xc, 0x55, 0x58, + 0x55, 0xb, 0x0, 0xb0, 0xb0, 0x0, 0xb5, 0x50, + 0xb0, 0xb, 0xb, 0x0, 0xb, 0x55, 0xb, 0x0, + 0xb0, 0xb0, 0x0, 0xb5, 0x40, 0xb3, 0xb9, 0xc, + 0x55, 0x5b, 0x0, 0xb, 0x1, 0x0, 0x70, 0x0, + 0x10, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, + + /* U+5E2D "席" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0x0, 0x0, 0x20, 0x0, 0xc5, + 0x55, 0x58, 0x55, 0x57, 0x80, 0x0, 0xc0, 0x6, + 0x50, 0xc, 0x0, 0x0, 0x0, 0xc3, 0x59, 0x85, + 0x5d, 0x5a, 0x50, 0x0, 0xb0, 0x5, 0x50, 0xb, + 0x0, 0x0, 0x0, 0xb0, 0x6, 0x86, 0x5c, 0x0, + 0x0, 0x1, 0xa0, 0x3, 0x1b, 0x4, 0x0, 0x0, + 0x2, 0x90, 0xa5, 0x5c, 0x55, 0x5c, 0x0, 0x5, + 0x60, 0xb0, 0xb, 0x0, 0xb, 0x0, 0x8, 0x10, + 0xb0, 0xb, 0x0, 0xb, 0x0, 0x7, 0x0, 0xb0, + 0xb, 0x3, 0xba, 0x0, 0x22, 0x0, 0x30, 0xb, + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+5E2F "帯" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x20, 0x37, 0x0, 0x80, 0x0, 0x3, 0x5a, + 0x75, 0x79, 0x55, 0xd8, 0xc0, 0x0, 0x7, 0x30, + 0x36, 0x0, 0xb0, 0x0, 0x0, 0x9, 0x75, 0x68, + 0x55, 0xc0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x20, 0x40, 0x4, 0x85, 0x55, 0x78, 0x55, 0x56, + 0xd1, 0xb, 0x22, 0x0, 0x37, 0x0, 0x24, 0x0, + 0x0, 0xc, 0x55, 0x79, 0x55, 0xa5, 0x0, 0x0, + 0xb, 0x0, 0x36, 0x0, 0x73, 0x0, 0x0, 0xb, + 0x0, 0x36, 0x0, 0x73, 0x0, 0x0, 0xb, 0x0, + 0x36, 0x16, 0xd2, 0x0, 0x0, 0x1, 0x0, 0x36, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, + 0x0, 0x0, + + /* U+5E30 "帰" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xb, 0x14, 0x65, 0x55, 0x5c, 0x20, 0x0, 0xb, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x3, 0xb, 0x2, + 0x65, 0x55, 0x5c, 0x0, 0xa, 0xb, 0x3, 0x55, + 0x55, 0x5c, 0x0, 0xa, 0xb, 0x3, 0x0, 0x0, + 0x3, 0x20, 0xa, 0xb, 0x48, 0x55, 0xb5, 0x55, + 0xd2, 0xa, 0xb, 0x82, 0x0, 0xb0, 0x3, 0x20, + 0x2, 0x19, 0x9, 0x65, 0xc5, 0x5d, 0x10, 0x0, + 0x55, 0x9, 0x20, 0xb0, 0xb, 0x0, 0x0, 0x80, + 0x9, 0x20, 0xb0, 0xb, 0x0, 0x1, 0x70, 0x9, + 0x20, 0xb1, 0x7d, 0x0, 0x5, 0x0, 0x3, 0x0, + 0xb0, 0x24, 0x0, 0x1, 0x0, 0x0, 0x0, 0x40, + 0x0, 0x0, + + /* U+5E33 "帳" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0xb, 0x55, 0x58, 0x50, 0x0, 0x1b, + 0x0, 0xb, 0x0, 0x4, 0x0, 0xb, 0x5d, 0x5c, + 0xc, 0x55, 0x56, 0x0, 0xb, 0x1b, 0xb, 0xb, + 0x0, 0x6, 0x0, 0xb, 0x1b, 0xb, 0xc, 0x55, + 0x55, 0x10, 0xb, 0x1b, 0xb, 0x5c, 0x55, 0x55, + 0xb1, 0xb, 0x1b, 0xb, 0x28, 0x13, 0x1, 0x10, + 0xb, 0x1b, 0xb, 0x28, 0x7, 0xa, 0x60, 0xa, + 0x1c, 0x96, 0x28, 0x6, 0x82, 0x0, 0x0, 0x1b, + 0x0, 0x28, 0x0, 0xb1, 0x0, 0x0, 0x1b, 0x0, + 0x2a, 0x72, 0x3d, 0x30, 0x0, 0x1c, 0x0, 0x3c, + 0x10, 0x4, 0xb2, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E36 "帶" */ + 0x0, 0x3, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, + 0xb, 0x1a, 0x1a, 0x2a, 0x30, 0x0, 0x3, 0x5d, + 0x5c, 0x5c, 0x5b, 0x6d, 0x70, 0x0, 0xb, 0xa, + 0xa, 0x9, 0x10, 0x30, 0x0, 0x64, 0xa, 0x5c, + 0x9, 0x65, 0xa0, 0x4, 0x20, 0x4, 0x3, 0x1, + 0x44, 0x20, 0x6, 0x55, 0x55, 0x86, 0x55, 0x58, + 0xc0, 0xd, 0x0, 0x0, 0x92, 0x0, 0x36, 0x10, + 0x14, 0x49, 0x55, 0xb6, 0x55, 0xd0, 0x0, 0x0, + 0x46, 0x0, 0x91, 0x0, 0xb0, 0x0, 0x0, 0x46, + 0x0, 0x91, 0x0, 0xb0, 0x0, 0x0, 0x45, 0x0, + 0x91, 0x28, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x91, + 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+5E38 "常" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x5, + 0x70, 0xc, 0x5, 0x90, 0x0, 0x0, 0xb, 0x10, + 0xb0, 0x80, 0x0, 0x0, 0x85, 0x55, 0x59, 0x65, + 0x55, 0xe1, 0x67, 0x2, 0x0, 0x0, 0x30, 0x53, + 0x5, 0x10, 0x96, 0x55, 0x5c, 0x10, 0x0, 0x0, + 0x9, 0x20, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x86, + 0x5c, 0x58, 0x0, 0x0, 0x0, 0x95, 0x55, 0xc5, + 0x57, 0x60, 0x0, 0xc, 0x0, 0xb, 0x0, 0x56, + 0x0, 0x0, 0xc0, 0x0, 0xb0, 0x5, 0x60, 0x0, + 0xc, 0x0, 0xb, 0x7, 0xc4, 0x0, 0x0, 0x30, + 0x0, 0xb0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x0, + + /* U+5E45 "幅" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x55, 0x55, 0x55, 0xa1, 0x0, 0xa0, 0x1, + 0x0, 0x0, 0x0, 0xa, 0x5c, 0x5b, 0x9, 0x55, + 0x5c, 0x0, 0xa0, 0xa0, 0xa0, 0xb0, 0x0, 0xb0, + 0xa, 0xa, 0xa, 0xc, 0x55, 0x5b, 0x0, 0xa0, + 0xa0, 0xa0, 0x70, 0x0, 0x40, 0xa, 0xa, 0xa, + 0x95, 0x59, 0x55, 0xb0, 0xa0, 0xa0, 0xa9, 0x0, + 0xa0, 0x1a, 0xb, 0xa, 0x78, 0x95, 0x5c, 0x55, + 0xa0, 0x30, 0xa1, 0x9, 0x0, 0xa0, 0x1a, 0x0, + 0xb, 0x0, 0x95, 0x5c, 0x55, 0xa0, 0x0, 0xb0, + 0xa, 0x0, 0x0, 0x1a, 0x0, 0x2, 0x0, 0x10, + 0x0, 0x0, 0x0, + + /* U+5E73 "平" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x55, 0x55, 0x55, 0x55, 0x8b, 0x0, 0x0, 0x10, + 0x0, 0xa2, 0x0, 0x30, 0x0, 0x0, 0x9, 0x0, + 0xa2, 0x4, 0xd1, 0x0, 0x0, 0x6, 0xb0, 0xa2, + 0x9, 0x10, 0x0, 0x0, 0x0, 0xb0, 0xa2, 0x42, + 0x0, 0x0, 0x36, 0x55, 0x55, 0xc7, 0x65, 0x5a, + 0x90, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E74 "年" */ + 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x65, 0x55, 0x55, 0x5c, 0x60, 0x0, 0x74, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x3, 0x60, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x4, 0x8, 0x55, 0x5d, 0x55, + 0xa7, 0x0, 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0xd, 0x0, 0x2, 0x80, 0x17, + 0x55, 0x55, 0x5d, 0x55, 0x55, 0x51, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, + + /* U+5E78 "幸" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x16, + 0x55, 0xc6, 0x58, 0x90, 0x0, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, 0xb6, + 0x55, 0x6d, 0x30, 0x0, 0x0, 0x52, 0x0, 0x83, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0xa0, 0x0, + 0x0, 0x0, 0x65, 0x57, 0x68, 0x65, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa1, 0x0, 0x7, 0x50, 0x26, 0x55, + 0x55, 0xc6, 0x55, 0x55, 0x40, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+5E7E "幾" */ + 0x0, 0x0, 0x10, 0x13, 0x0, 0x20, 0x0, 0x0, + 0x4, 0xa0, 0x1a, 0x4, 0xa0, 0x0, 0x0, 0x18, + 0x2, 0xa, 0x18, 0x3, 0x0, 0x1, 0xb6, 0x6b, + 0x1b, 0xa8, 0x5c, 0x30, 0x0, 0x32, 0x80, 0xa, + 0x10, 0x82, 0x0, 0x0, 0x36, 0x28, 0xb, 0x3a, + 0x47, 0x60, 0x0, 0x99, 0x67, 0x3a, 0x2a, 0x30, + 0x90, 0x0, 0x3, 0x90, 0x9, 0x12, 0x73, 0x40, + 0x5, 0x58, 0x95, 0x59, 0x85, 0x57, 0x60, 0x0, + 0x9, 0x80, 0x2, 0x90, 0xaa, 0x0, 0x0, 0x9, + 0x3c, 0x0, 0xbb, 0x70, 0x2, 0x0, 0x71, 0x3, + 0x4, 0xac, 0x40, 0x24, 0x5, 0x20, 0x4, 0x73, + 0x1, 0x9c, 0xc4, 0x1, 0x0, 0x30, 0x0, 0x0, + 0x1, 0x52, + + /* U+5E83 "広" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x5, 0x30, 0x8, 0x20, 0x9, 0x85, 0x55, 0x55, + 0x55, 0x53, 0x0, 0x94, 0x0, 0x4, 0x20, 0x0, + 0x0, 0x9, 0x30, 0x0, 0xb7, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x2d, 0x0, 0x0, 0x0, 0xb, 0x10, + 0x8, 0x40, 0x0, 0x0, 0x0, 0xc0, 0x1, 0xa0, + 0x0, 0x0, 0x0, 0xa, 0x0, 0x82, 0x0, 0x19, + 0x10, 0x3, 0x50, 0x46, 0x0, 0x0, 0x3d, 0x10, + 0x70, 0x2e, 0x99, 0x98, 0x87, 0xc8, 0x15, 0x0, + 0x84, 0x10, 0x0, 0x2, 0x61, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5E86 "庆" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x85, + 0x55, 0x5c, 0x55, 0x5b, 0x80, 0x0, 0xc0, 0x0, + 0x7, 0x10, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, + 0x0, 0x10, 0x0, 0xc3, 0x65, 0x5d, 0x65, 0x57, + 0x80, 0x0, 0xc0, 0x0, 0xc, 0x50, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x29, 0x71, 0x0, 0x0, 0x1, + 0xa0, 0x0, 0x84, 0x19, 0x0, 0x0, 0x5, 0x60, + 0x1, 0xb0, 0x7, 0x70, 0x0, 0x8, 0x0, 0x29, + 0x10, 0x0, 0xab, 0x30, 0x24, 0x5, 0x60, 0x0, + 0x0, 0x8, 0x91, 0x10, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E95 "底" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0xb5, + 0x55, 0x5b, 0x55, 0x5a, 0x70, 0x0, 0xd0, 0x0, + 0x0, 0x0, 0x40, 0x0, 0x0, 0xd0, 0x42, 0x47, + 0x9b, 0xb5, 0x0, 0x0, 0xd0, 0xc3, 0x15, 0x80, + 0x0, 0x0, 0x0, 0xd0, 0xc0, 0x2, 0xa0, 0x2, + 0x0, 0x0, 0xd0, 0xc5, 0x55, 0xd5, 0x59, 0x40, + 0x0, 0xb0, 0xc0, 0x0, 0xb1, 0x0, 0x0, 0x2, + 0x80, 0xc0, 0x0, 0x77, 0x0, 0x0, 0x6, 0x30, + 0xc1, 0x75, 0xd, 0x20, 0x50, 0x8, 0x0, 0xdb, + 0x38, 0x13, 0xd4, 0x90, 0x23, 0x0, 0x30, 0x5, + 0x80, 0x2b, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+5E97 "店" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x10, 0x0, 0x20, 0x0, 0x86, + 0x55, 0x5a, 0x55, 0x58, 0xb1, 0x0, 0x93, 0x0, + 0xa, 0x20, 0x0, 0x0, 0x0, 0x93, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, 0xc, 0x55, + 0x5b, 0x40, 0x0, 0xa2, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0xc, 0x0, 0x1, 0x0, + 0x0, 0xc0, 0xb5, 0x58, 0x55, 0x5e, 0x0, 0x0, + 0xc0, 0xb0, 0x0, 0x0, 0xd, 0x0, 0x3, 0x70, + 0xb0, 0x0, 0x0, 0xd, 0x0, 0x7, 0x0, 0xb5, + 0x55, 0x55, 0x5d, 0x0, 0x23, 0x0, 0xb0, 0x0, + 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E9C "府" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x10, 0x0, 0xa5, + 0x55, 0x59, 0x55, 0x59, 0x90, 0x0, 0xc0, 0x2, + 0x50, 0x0, 0x61, 0x0, 0x0, 0xc0, 0x8, 0x70, + 0x0, 0xb0, 0x0, 0x0, 0xc0, 0xc, 0x0, 0x0, + 0xb0, 0x60, 0x0, 0xc0, 0x7d, 0x26, 0x55, 0xc5, + 0x51, 0x0, 0xb1, 0x9b, 0x12, 0x0, 0xb0, 0x0, + 0x2, 0xa7, 0xb, 0x9, 0x50, 0xb0, 0x0, 0x4, + 0x70, 0xb, 0x1, 0x90, 0xb0, 0x0, 0x7, 0x10, + 0xb, 0x0, 0x0, 0xb0, 0x0, 0x8, 0x0, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0x32, 0x0, 0xb, 0x0, + 0x39, 0xc0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x1, + 0x20, 0x0, + + /* U+5EA6 "度" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0x0, 0x1, 0x0, 0x0, 0xb5, + 0x55, 0x58, 0x55, 0x59, 0x70, 0x0, 0xc0, 0x9, + 0x30, 0xa, 0x20, 0x0, 0x0, 0xc4, 0x5b, 0x65, + 0x5d, 0x5b, 0x40, 0x0, 0xc0, 0x9, 0x20, 0xb, + 0x0, 0x0, 0x0, 0xc0, 0x9, 0x65, 0x5c, 0x0, + 0x0, 0x0, 0xc0, 0x4, 0x0, 0x3, 0x20, 0x0, + 0x0, 0xa0, 0x47, 0x55, 0x59, 0xb0, 0x0, 0x2, + 0x70, 0x0, 0x70, 0x2c, 0x0, 0x0, 0x6, 0x20, + 0x0, 0x29, 0xc1, 0x0, 0x0, 0x7, 0x0, 0x0, + 0x6a, 0xb6, 0x10, 0x0, 0x23, 0x2, 0x67, 0x30, + 0x7, 0xcd, 0x80, 0x10, 0x22, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+5EA7 "座" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4b, 0x0, 0x1, 0x0, 0x0, 0x95, + 0x55, 0x5b, 0x55, 0x5d, 0x50, 0x0, 0xd0, 0x0, + 0x3, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x36, 0xa, + 0x20, 0x81, 0x0, 0x0, 0xc0, 0x75, 0xa, 0x1, + 0xd0, 0x0, 0x0, 0xc0, 0xa5, 0xa, 0x6, 0x94, + 0x0, 0x0, 0xc2, 0x55, 0x9a, 0x8, 0x9, 0x70, + 0x0, 0xb6, 0x0, 0x5a, 0x41, 0x21, 0x30, 0x1, + 0x90, 0x65, 0x5c, 0x55, 0x86, 0x0, 0x5, 0x40, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, + 0xa, 0x0, 0x0, 0x0, 0x14, 0x15, 0x55, 0x5c, + 0x55, 0x5b, 0xa0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EAB "庫" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x65, 0x55, + 0x5a, 0x55, 0x5d, 0x30, 0x8, 0x30, 0x0, 0x28, + 0x0, 0x0, 0x0, 0x83, 0x65, 0x56, 0xb5, 0x88, + 0x0, 0x8, 0x30, 0x20, 0x19, 0x3, 0x0, 0x0, + 0x92, 0xd, 0x56, 0xb5, 0xc2, 0x0, 0xa, 0x10, + 0xc5, 0x6b, 0x5c, 0x10, 0x0, 0xa0, 0xb, 0x1, + 0x90, 0xa1, 0x0, 0xa, 0x0, 0xc5, 0x6b, 0x59, + 0x10, 0x3, 0x53, 0x55, 0x56, 0xb5, 0x5d, 0x50, + 0x70, 0x1, 0x0, 0x19, 0x0, 0x0, 0x23, 0x0, + 0x0, 0x2, 0xa0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x12, 0x0, 0x0, + + /* U+5EAD "庭" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0x3, 0x0, 0x2, 0xa5, + 0x55, 0x58, 0x55, 0x59, 0x40, 0x2, 0xa0, 0x2, + 0x0, 0x0, 0x48, 0x0, 0x2, 0xa6, 0x6e, 0x24, + 0x5d, 0x53, 0x0, 0x2, 0xa0, 0x84, 0x0, 0xc, + 0x0, 0x0, 0x2, 0x95, 0x82, 0x10, 0xc, 0x4, + 0x10, 0x2, 0x97, 0x5b, 0x56, 0x5d, 0x55, 0x30, + 0x3, 0x72, 0xb, 0x0, 0xc, 0x0, 0x0, 0x4, + 0x53, 0x69, 0x0, 0xc, 0x0, 0x30, 0x7, 0x10, + 0xd5, 0x26, 0x56, 0x55, 0x60, 0x7, 0x7, 0x68, + 0x94, 0x10, 0x0, 0x0, 0x32, 0x74, 0x0, 0x28, + 0xbd, 0xef, 0xa1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EB7 "康" */ + 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x40, 0x1, 0x20, 0x0, 0xa5, + 0x55, 0x57, 0x65, 0x58, 0x80, 0x0, 0xa1, 0x0, + 0xc, 0x0, 0x20, 0x0, 0x0, 0xa1, 0x65, 0x5c, + 0x55, 0xc3, 0x0, 0x0, 0xa5, 0x55, 0x5c, 0x55, + 0xc7, 0xa0, 0x0, 0xb2, 0x0, 0xb, 0x0, 0xa0, + 0x0, 0x0, 0xc0, 0x65, 0x5c, 0x65, 0xc1, 0x0, + 0x0, 0xb0, 0x44, 0xb, 0x50, 0x2a, 0x20, 0x1, + 0xa0, 0xb, 0x2c, 0x54, 0x83, 0x0, 0x5, 0x40, + 0x7, 0x5b, 0xb, 0x20, 0x0, 0x8, 0x9, 0xa1, + 0xb, 0x1, 0xc7, 0x20, 0x23, 0x5, 0x3, 0xba, + 0x0, 0x9, 0x60, 0x10, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+5EE0 "廠" */ + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x10, 0x1, 0x10, 0x0, 0x85, + 0x55, 0x58, 0x55, 0x59, 0x80, 0x0, 0xb0, 0x2, + 0x70, 0x2, 0x30, 0x0, 0x0, 0xb1, 0x63, 0xb2, + 0x96, 0x60, 0x0, 0x0, 0xb0, 0x84, 0xb6, 0x9, + 0x44, 0x60, 0x0, 0xb3, 0x66, 0xb6, 0x9a, 0x19, + 0x20, 0x0, 0xa4, 0x61, 0x12, 0xb6, 0x19, 0x0, + 0x0, 0xa4, 0x6b, 0x87, 0xa1, 0x59, 0x0, 0x0, + 0x84, 0x69, 0x46, 0x90, 0xa6, 0x0, 0x4, 0x44, + 0x69, 0x75, 0x90, 0xb4, 0x0, 0x6, 0x4, 0x60, + 0x13, 0x95, 0x4b, 0x20, 0x4, 0x4, 0x30, 0x8, + 0x73, 0x2, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EFA "建" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x5, 0x57, + 0xa2, 0x55, 0xc5, 0x5b, 0x0, 0x0, 0xa, 0x20, + 0x0, 0xb0, 0xb, 0x20, 0x0, 0x48, 0x15, 0x55, + 0xc5, 0x5d, 0x70, 0x0, 0xa0, 0x1, 0x22, 0xb2, + 0x2b, 0x0, 0x5, 0x85, 0xd2, 0x33, 0xc3, 0x35, + 0x0, 0x0, 0x0, 0xa2, 0x55, 0xc5, 0x86, 0x0, + 0x1, 0x33, 0x70, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x77, 0x45, 0x55, 0xc5, 0x57, 0x70, 0x0, 0x2d, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x77, 0xb5, + 0x10, 0xa0, 0x0, 0x0, 0x5, 0x20, 0x17, 0xbc, + 0xcc, 0xde, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EFF "廿" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc2, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0xc, 0x1, 0x60, 0x6, 0x55, 0xd5, 0x55, 0x5d, + 0x56, 0x61, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F0F "式" */ + 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xc2, 0x81, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xb0, 0x68, 0x0, 0x3, 0x55, 0x55, + 0x56, 0xd5, 0x5b, 0xa0, 0x1, 0x10, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xc0, + 0x0, 0x0, 0x3, 0x65, 0x85, 0xb3, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x93, 0x0, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x58, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0xd, 0x0, 0x30, 0x0, 0x0, + 0xd6, 0x64, 0x8, 0x80, 0x60, 0x8, 0xba, 0x61, + 0x0, 0x0, 0xc8, 0x90, 0x5, 0x20, 0x0, 0x0, + 0x0, 0xa, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, + + /* U+5F15 "引" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x55, 0x55, + 0x59, 0x0, 0xb4, 0x1, 0x0, 0x2, 0x90, 0xa, + 0x10, 0x0, 0x0, 0x29, 0x0, 0xa1, 0x6, 0x75, + 0x56, 0xa0, 0xa, 0x10, 0x93, 0x0, 0x12, 0x0, + 0xa1, 0xc, 0x0, 0x0, 0x0, 0xa, 0x12, 0xc5, + 0x55, 0x5d, 0x10, 0xa1, 0x0, 0x0, 0x0, 0xa0, + 0xa, 0x10, 0x0, 0x0, 0x47, 0x0, 0xa1, 0x0, + 0x0, 0x8, 0x40, 0xa, 0x10, 0x2, 0x54, 0xd0, + 0x0, 0xa1, 0x0, 0x4, 0xe4, 0x0, 0xb, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+5F1F "弟" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x94, 0x0, 0xd, 0x30, 0x0, 0x0, 0x1, 0xb0, + 0x6, 0x30, 0x0, 0x0, 0x46, 0x55, 0x58, 0x75, + 0x5d, 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, 0xc0, + 0x0, 0x8, 0x55, 0x6c, 0x55, 0x5c, 0x0, 0x1, + 0xb0, 0x1, 0xa0, 0x0, 0x60, 0x0, 0x76, 0x0, + 0x1a, 0x0, 0x0, 0x40, 0x6, 0x55, 0x6f, 0xc5, + 0x55, 0x7c, 0x0, 0x0, 0xb, 0x5a, 0x0, 0x4, + 0x80, 0x0, 0x9, 0x41, 0xa0, 0x0, 0x75, 0x0, + 0x18, 0x20, 0x1a, 0x5, 0xad, 0x20, 0x35, 0x0, + 0x2, 0xb0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+5F31 "弱" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, + 0x55, 0xb3, 0x56, 0x55, 0xc1, 0x0, 0x0, 0xa, + 0x10, 0x0, 0xb, 0x0, 0x3, 0x0, 0xa1, 0x14, + 0x22, 0xc0, 0x0, 0xc5, 0x59, 0x13, 0x92, 0x27, + 0x0, 0x1a, 0x0, 0x0, 0x65, 0x0, 0x10, 0x4, + 0x95, 0x5c, 0x3a, 0x65, 0x5a, 0x60, 0x4, 0x10, + 0xb0, 0x5, 0x10, 0x75, 0x0, 0x1c, 0xb, 0x0, + 0x2b, 0x7, 0x50, 0x0, 0x24, 0xc0, 0x0, 0x45, + 0x84, 0x2, 0x87, 0xb, 0x3, 0x86, 0x8, 0x40, + 0xc3, 0x0, 0xb0, 0xa2, 0x10, 0xb2, 0x0, 0x6, + 0xd6, 0x0, 0x3, 0xcc, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x1, 0x0, + + /* U+5F35 "張" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x55, 0x92, 0x75, 0x55, 0x5b, 0x20, 0x0, 0x0, + 0xa1, 0x91, 0x0, 0x1, 0x0, 0x0, 0x0, 0xa1, + 0x96, 0x55, 0x67, 0x0, 0x8, 0x55, 0xc1, 0x91, + 0x0, 0x5, 0x0, 0xc, 0x0, 0x30, 0x96, 0x55, + 0x55, 0x0, 0xb, 0x0, 0x2, 0xa4, 0x33, 0x35, + 0x60, 0x3c, 0x55, 0x96, 0xc2, 0x72, 0x23, 0x20, + 0x0, 0x0, 0xa2, 0xb0, 0x51, 0x2c, 0x20, 0x0, + 0x0, 0xb0, 0xb0, 0x19, 0x60, 0x0, 0x0, 0x0, + 0xb0, 0xb0, 0x7, 0x50, 0x0, 0x2, 0x14, 0x80, + 0xb5, 0x60, 0xb7, 0x0, 0x0, 0xaf, 0x20, 0xd7, + 0x0, 0x1b, 0x90, 0x0, 0x1, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+5F37 "強" */ + 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x1, 0x55, + 0x5a, 0x20, 0xc, 0x50, 0x0, 0x0, 0x0, 0xa0, + 0x7, 0x30, 0x10, 0x0, 0x0, 0xa, 0x6, 0x20, + 0x1, 0xa3, 0x9, 0x55, 0xc4, 0xd9, 0x88, 0x44, + 0xc0, 0xb0, 0x2, 0x0, 0x2, 0xa0, 0x1, 0xa, + 0x0, 0x0, 0xa5, 0x6b, 0x5b, 0x14, 0xb5, 0x59, + 0x3b, 0x2, 0x90, 0xb0, 0x0, 0x0, 0xb1, 0xb0, + 0x29, 0xb, 0x0, 0x0, 0xc, 0xc, 0x56, 0xb5, + 0xb0, 0x0, 0x1, 0xb0, 0x0, 0x29, 0x5, 0x0, + 0x20, 0x77, 0x1, 0x25, 0xb5, 0x87, 0x0, 0xad, + 0x2, 0xd8, 0x53, 0x0, 0xb0, 0x1, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+5F53 "当" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x50, 0x2, 0x0, 0x4, 0x80, 0xa, 0x10, + 0x4e, 0x10, 0x0, 0x7a, 0xa, 0x10, 0xb2, 0x0, + 0x0, 0x5, 0xa, 0x16, 0x10, 0x0, 0x16, 0x55, + 0x5b, 0x65, 0x55, 0xb2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x3, 0x55, 0x55, 0x55, 0x55, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x46, 0x55, 0x55, 0x55, 0x55, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x20, + + /* U+5F62 "形" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x55, 0x55, 0x5b, 0x50, 0x1d, 0x10, 0x0, 0xc, + 0x0, 0xb0, 0x0, 0x95, 0x0, 0x0, 0xc, 0x0, + 0xb0, 0x5, 0x50, 0x0, 0x0, 0xc, 0x0, 0xb0, + 0x24, 0x0, 0x0, 0x0, 0xc, 0x0, 0xb4, 0x40, + 0xa, 0x70, 0x5, 0x5d, 0x55, 0xc5, 0x40, 0x79, + 0x0, 0x0, 0xc, 0x0, 0xb0, 0x7, 0x60, 0x0, + 0x0, 0x1a, 0x0, 0xb0, 0x63, 0x0, 0x40, 0x0, + 0x56, 0x0, 0xb0, 0x0, 0x8, 0xd1, 0x0, 0x91, + 0x0, 0xb0, 0x0, 0x79, 0x0, 0x2, 0x60, 0x0, + 0xb0, 0x8, 0x50, 0x0, 0x6, 0x0, 0x0, 0x73, + 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+5F71 "影" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x95, 0x55, 0x5c, 0x0, 0x8, 0x50, 0x1, 0xa0, + 0x0, 0xb, 0x0, 0x3b, 0x0, 0x1, 0xb5, 0x55, + 0x5b, 0x1, 0x90, 0x0, 0x1, 0xb5, 0x85, 0x5a, + 0x15, 0x0, 0x10, 0x2, 0x22, 0xb2, 0x26, 0x40, + 0x2, 0xe1, 0x4, 0x53, 0x33, 0x37, 0x20, 0xb, + 0x20, 0x0, 0xc5, 0x55, 0x6b, 0x0, 0x91, 0x0, + 0x0, 0xa0, 0x0, 0x1a, 0x16, 0x0, 0x33, 0x0, + 0x95, 0xc5, 0x67, 0x0, 0x1, 0xd5, 0x0, 0x66, + 0xb3, 0x60, 0x0, 0x2b, 0x20, 0x1, 0x90, 0xb0, + 0x77, 0x4, 0x91, 0x0, 0x6, 0x17, 0xd0, 0x3, + 0x64, 0x0, 0x0, 0x0, 0x0, 0x10, 0x2, 0x0, + 0x0, 0x0, + + /* U+5F79 "役" */ + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x80, 0x2a, 0x55, 0xc0, 0x0, 0x0, 0x49, + 0x0, 0x29, 0x0, 0xb0, 0x0, 0x2, 0x80, 0x20, + 0x47, 0x0, 0xb0, 0x0, 0x4, 0x3, 0xe1, 0x82, + 0x0, 0xc0, 0x10, 0x0, 0xc, 0x24, 0x50, 0x0, + 0x68, 0x83, 0x0, 0x8c, 0x23, 0x55, 0x55, 0x78, + 0x0, 0x5, 0x4c, 0x0, 0x5, 0x0, 0x93, 0x0, + 0x13, 0xc, 0x0, 0x6, 0x1, 0xb0, 0x0, 0x0, + 0xc, 0x0, 0x1, 0x8a, 0x30, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xbb, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x19, 0x57, 0xa2, 0x0, 0x0, 0xc, 0x5, 0x71, + 0x0, 0x4c, 0xc1, 0x0, 0x3, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F7C "彼" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, 0x57, + 0x0, 0x30, 0xb, 0x0, 0x40, 0x1, 0x90, 0x30, + 0xd5, 0x5c, 0x57, 0xc1, 0x6, 0x6, 0xb0, 0xb0, + 0xb, 0x5, 0x0, 0x0, 0xc, 0x10, 0xb0, 0xb, + 0x0, 0x0, 0x0, 0x8b, 0x0, 0xc6, 0x58, 0x5c, + 0x20, 0x4, 0x5b, 0x0, 0xa1, 0x40, 0x1a, 0x0, + 0x3, 0xb, 0x2, 0x90, 0x80, 0x83, 0x0, 0x0, + 0xb, 0x5, 0x50, 0x65, 0xa0, 0x0, 0x0, 0xb, + 0x8, 0x0, 0x1f, 0x20, 0x0, 0x0, 0xb, 0x16, + 0x3, 0x94, 0xb5, 0x0, 0x0, 0xb, 0x53, 0x53, + 0x0, 0x1a, 0xc1, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F80 "往" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x90, 0x4, 0x70, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x71, 0x0, + 0x0, 0x20, 0x6, 0x10, 0x4, 0x2, 0xa5, 0x55, + 0xd5, 0x55, 0x30, 0x0, 0xa, 0x60, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x1, 0x9c, 0x1, 0x55, 0xd5, 0x5a, 0x10, + 0x7, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x10, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0x0, 0x50, 0x0, 0xc, 0x36, 0x55, + 0x75, 0x56, 0x71, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F85 "待" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x7, 0x90, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x0, 0xc0, 0x5, 0x0, 0x0, 0x91, 0x32, + 0x55, 0xd5, 0x55, 0x0, 0x5, 0x13, 0xd0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0xb, 0x47, 0x55, 0x95, + 0x55, 0xa1, 0x0, 0x6d, 0x0, 0x0, 0x0, 0xa1, + 0x0, 0x2, 0x6c, 0x5, 0x55, 0x55, 0xd5, 0xb0, + 0x4, 0xc, 0x0, 0x30, 0x0, 0xb0, 0x0, 0x0, + 0xc, 0x0, 0x3a, 0x0, 0xb0, 0x0, 0x0, 0xc, + 0x0, 0xa, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x5b, 0xc0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, + 0x10, 0x0, + + /* U+5F88 "很" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x75, 0x55, 0x59, 0x0, 0x0, 0x47, + 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x80, 0x30, + 0xb0, 0x0, 0xb, 0x0, 0x5, 0x3, 0xc0, 0xb5, + 0x55, 0x5b, 0x0, 0x0, 0xa, 0x20, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0x4c, 0x0, 0xb5, 0x65, 0x5b, + 0x0, 0x0, 0x8b, 0x0, 0xb0, 0x60, 0x8, 0x20, + 0x6, 0xb, 0x0, 0xb0, 0x61, 0x67, 0x10, 0x0, + 0xb, 0x0, 0xb0, 0xb, 0x10, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x6, 0x80, 0x0, 0x0, 0xb, 0x0, + 0xb6, 0x71, 0x7c, 0x40, 0x0, 0xc, 0x0, 0xb5, + 0x0, 0x3, 0x81, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F8B "律" */ + 0x0, 0x4, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xa1, + 0x3, 0x55, 0xd5, 0x5a, 0x10, 0x5, 0x24, 0x50, + 0x0, 0xc0, 0xc, 0x0, 0x2, 0xb, 0x66, 0x55, + 0xd5, 0x5d, 0xa3, 0x0, 0x3b, 0x0, 0x0, 0xc0, + 0xc, 0x0, 0x0, 0xba, 0x4, 0x65, 0xd5, 0x5b, + 0x0, 0x6, 0x3a, 0x0, 0x0, 0xc0, 0x4, 0x0, + 0x2, 0x1a, 0x5, 0x55, 0xd5, 0x56, 0x20, 0x0, + 0x1a, 0x0, 0x0, 0xc0, 0x0, 0x60, 0x0, 0x1a, + 0x56, 0x55, 0xd5, 0x55, 0x51, 0x0, 0x1a, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x40, + 0x0, 0x0, + + /* U+5F8C "後" */ + 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x7, 0xb0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x2b, + 0x0, 0x9, 0x20, 0x97, 0x0, 0x1, 0x90, 0x31, + 0xd8, 0x59, 0x70, 0x0, 0x6, 0x3, 0xd1, 0x41, + 0x83, 0x31, 0x0, 0x0, 0xb, 0x20, 0x58, 0x0, + 0x2c, 0x20, 0x0, 0x8d, 0x4, 0xcc, 0x85, 0x35, + 0x70, 0x6, 0x5c, 0x0, 0xc, 0x20, 0x12, 0x0, + 0x12, 0xc, 0x0, 0x89, 0x55, 0xaa, 0x0, 0x0, + 0xc, 0x4, 0x54, 0x21, 0xc0, 0x0, 0x0, 0xc, + 0x13, 0x0, 0x9b, 0x20, 0x0, 0x0, 0xc, 0x0, + 0x1, 0xab, 0x40, 0x0, 0x0, 0xc, 0x2, 0x77, + 0x10, 0x7d, 0xa2, 0x0, 0x3, 0x22, 0x0, 0x0, + 0x0, 0x20, + + /* U+5F92 "徒" */ + 0x0, 0x2, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x58, + 0x0, 0x0, 0x92, 0x3, 0x0, 0x1, 0x90, 0x42, + 0x65, 0xb7, 0x57, 0x40, 0x6, 0x5, 0xc0, 0x0, + 0x92, 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x92, + 0x1, 0x70, 0x0, 0x7c, 0x16, 0x55, 0xb8, 0x55, + 0x51, 0x3, 0x8c, 0x0, 0xa0, 0x92, 0x0, 0x0, + 0x15, 0xc, 0x1, 0xb0, 0x97, 0x59, 0x50, 0x0, + 0xc, 0x3, 0xa0, 0x92, 0x0, 0x0, 0x0, 0xc, + 0x7, 0x35, 0x92, 0x0, 0x0, 0x0, 0xc, 0x7, + 0x3, 0xd6, 0x10, 0x0, 0x0, 0xc, 0x40, 0x0, + 0x6, 0xbe, 0xe3, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F93 "従" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x7, 0xc0, 0x73, 0x0, 0xb, 0x60, 0x0, 0x2b, + 0x0, 0xd, 0x20, 0x29, 0x0, 0x0, 0x90, 0x20, + 0x5, 0x40, 0x70, 0x0, 0x6, 0x1, 0xe4, 0x55, + 0x55, 0x66, 0xc1, 0x0, 0x9, 0x60, 0x10, 0xc, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x51, 0xc, 0x0, + 0x0, 0x1, 0x8c, 0x0, 0xa4, 0xc, 0x2, 0x20, + 0x5, 0xc, 0x0, 0xb1, 0xd, 0x55, 0x30, 0x0, + 0xc, 0x0, 0xd1, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x2, 0x97, 0x1c, 0x0, 0x0, 0x0, 0xc, 0x7, + 0x10, 0xac, 0x0, 0x0, 0x0, 0xc, 0x23, 0x0, + 0x7, 0xdc, 0xa3, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x2, 0x40, + + /* U+5F97 "得" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xd0, 0x85, 0x55, 0x5b, 0x0, 0x0, 0x2b, + 0x10, 0xb0, 0x0, 0x1a, 0x0, 0x1, 0x80, 0x42, + 0xb5, 0x55, 0x6a, 0x0, 0x4, 0x0, 0xd5, 0xb0, + 0x0, 0x1a, 0x0, 0x0, 0x8, 0x60, 0xc5, 0x55, + 0x6a, 0x0, 0x0, 0x4d, 0x3, 0x65, 0x55, 0x58, + 0x60, 0x3, 0x6c, 0x0, 0x10, 0x0, 0xc0, 0x0, + 0x3, 0xc, 0x16, 0x55, 0x55, 0xd5, 0xc1, 0x0, + 0xc, 0x0, 0x51, 0x0, 0xc0, 0x0, 0x0, 0xc, + 0x0, 0x2c, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, + 0x5, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x4a, 0xd0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, + 0x10, 0x0, + + /* U+5F9E "從" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xa0, 0x6b, 0x0, 0x5a, 0x0, 0x0, 0x2a, + 0x0, 0x85, 0x0, 0x94, 0x0, 0x0, 0x80, 0x10, + 0xa8, 0x30, 0xb7, 0x0, 0x5, 0x0, 0xe4, 0x61, + 0xd5, 0x33, 0xc0, 0x0, 0x8, 0x55, 0x0, 0x15, + 0x0, 0x40, 0x0, 0x4c, 0x0, 0x0, 0x9, 0x0, + 0x0, 0x3, 0x7c, 0x0, 0xa3, 0xc, 0x0, 0x0, + 0x13, 0xc, 0x0, 0xc0, 0xd, 0x59, 0x20, 0x0, + 0xc, 0x0, 0xc0, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x1, 0xc7, 0xc, 0x0, 0x0, 0x0, 0xc, 0x6, + 0x21, 0xad, 0x30, 0x0, 0x0, 0xc, 0x24, 0x0, + 0x4, 0xae, 0xd4, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x10, + + /* U+5FA1 "御" */ + 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x50, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x48, + 0x2, 0x80, 0x40, 0x63, 0x71, 0x2, 0x70, 0x37, + 0x6b, 0x52, 0xc1, 0xb0, 0x4, 0x5, 0xa6, 0xa, + 0x0, 0xb0, 0xa0, 0x0, 0xb, 0x15, 0x5b, 0x86, + 0xb0, 0xa0, 0x0, 0x99, 0x0, 0xa, 0x0, 0xb0, + 0xa0, 0x4, 0x49, 0xa, 0x1a, 0x31, 0xb0, 0xa0, + 0x2, 0x19, 0xa, 0xb, 0x53, 0xb0, 0xa0, 0x0, + 0x19, 0xa, 0xa, 0x0, 0xb0, 0xa0, 0x0, 0x19, + 0xa, 0x1c, 0x52, 0xb6, 0xb0, 0x0, 0x19, 0x4d, + 0x82, 0x0, 0xb0, 0x10, 0x0, 0x29, 0x1, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+5FA9 "復" */ + 0x0, 0x0, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xc0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0x6a, 0x55, 0x57, 0x90, 0x0, 0x91, 0x1, + 0x72, 0x0, 0x3, 0x10, 0x6, 0x0, 0x94, 0xd, + 0x55, 0x5b, 0x40, 0x0, 0x7, 0x80, 0xc, 0x55, + 0x5b, 0x20, 0x0, 0x3c, 0x0, 0xb, 0x0, 0x9, + 0x20, 0x1, 0x8b, 0x0, 0xa, 0xc5, 0x58, 0x10, + 0x4, 0xb, 0x0, 0x8, 0x85, 0x5a, 0x10, 0x0, + 0xb, 0x0, 0x45, 0x50, 0x6a, 0x0, 0x0, 0xb, + 0x3, 0x30, 0x38, 0xb0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x5c, 0x80, 0x0, 0x0, 0xb, 0x0, 0x47, + 0x30, 0x6d, 0xa2, 0x0, 0x1, 0x2, 0x0, 0x0, + 0x0, 0x20, + + /* U+5FC3 "心" */ + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40, 0xe, 0x60, 0x0, 0x0, 0x0, 0x0, 0xc4, + 0x5, 0x20, 0x0, 0x0, 0x0, 0x30, 0xb1, 0x0, + 0x0, 0x21, 0x0, 0x0, 0x80, 0xb1, 0x0, 0x0, + 0xb, 0x10, 0x3, 0xa0, 0xb1, 0x0, 0x0, 0x6, + 0xb0, 0xd, 0x70, 0xb1, 0x0, 0x0, 0x42, 0xd0, + 0x4, 0x0, 0xb1, 0x0, 0x0, 0x60, 0x10, 0x0, + 0x0, 0xb2, 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, + 0x7d, 0xaa, 0xad, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x10, 0x0, 0x0, + + /* U+5FC5 "必" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x53, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, + 0xb5, 0x7, 0x80, 0x0, 0x0, 0xc, 0x23, 0xb0, + 0xc1, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x49, 0x0, + 0x0, 0x5, 0xc, 0x0, 0xb, 0x13, 0x20, 0x0, + 0x80, 0xc0, 0x4, 0x80, 0xa, 0x10, 0x67, 0xc, + 0x0, 0xb1, 0x0, 0x6a, 0xa, 0x20, 0xc0, 0x93, + 0x0, 0x21, 0x70, 0x0, 0xc, 0x76, 0x0, 0x6, + 0x0, 0x0, 0x0, 0xd5, 0x0, 0x1, 0xb0, 0x0, + 0x16, 0x79, 0xdc, 0xcc, 0xdb, 0x0, 0x13, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5FD8 "忘" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x4, 0x70, 0x6, 0x55, 0xd5, + 0x55, 0x55, 0x55, 0x50, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xd5, 0x55, 0x55, 0x7c, + 0x0, 0x0, 0x0, 0x50, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x30, 0x2d, 0x10, 0x0, 0x0, 0x0, + 0x40, 0x95, 0x9, 0x20, 0x19, 0x10, 0x0, 0xa0, + 0x83, 0x0, 0x0, 0x45, 0xc0, 0x6, 0xc0, 0x83, + 0x0, 0x0, 0x90, 0x70, 0x1, 0x0, 0x5c, 0xaa, + 0xab, 0xb0, 0x0, + + /* U+5FD9 "忙" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x95, 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x92, + 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x93, 0x0, + 0x0, 0x22, 0x2, 0x60, 0x2, 0x9a, 0x85, 0xd5, + 0x55, 0x55, 0x50, 0x9, 0x93, 0xa0, 0xc0, 0x0, + 0x0, 0x0, 0x4a, 0x92, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x21, 0x92, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x92, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x92, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, + 0xc0, 0x0, 0x4, 0x20, 0x0, 0xa3, 0x1, 0x85, + 0x55, 0x55, 0x40, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5FEB "快" */ + 0x0, 0x13, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x1a, + 0x0, 0x0, 0xc0, 0x1, 0x0, 0x0, 0x1c, 0x3, + 0x55, 0xd5, 0x5e, 0x10, 0x1, 0x3b, 0xb3, 0x0, + 0xc0, 0xc, 0x0, 0x7, 0x4a, 0x35, 0x0, 0xc0, + 0xc, 0x0, 0xd, 0x2a, 0x0, 0x0, 0xb0, 0xc, + 0x20, 0x0, 0x1a, 0x26, 0x56, 0xc6, 0x59, 0x94, + 0x0, 0x1a, 0x0, 0x6, 0x66, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0xb, 0x16, 0x20, 0x0, 0x0, 0x1a, + 0x0, 0x47, 0x0, 0xa0, 0x0, 0x0, 0x1a, 0x2, + 0x90, 0x0, 0x5b, 0x10, 0x0, 0x2b, 0x37, 0x0, + 0x0, 0x7, 0xe4, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x10, + + /* U+5FF5 "念" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x45, 0x30, 0x0, 0x0, 0x0, 0x0, 0xa5, + 0x50, 0x67, 0x0, 0x0, 0x0, 0xa, 0x30, 0x77, + 0x4, 0xd8, 0x41, 0x4, 0x71, 0x0, 0x13, 0x3, + 0x7, 0x80, 0x12, 0x4, 0x65, 0x55, 0x7e, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0x42, 0x93, 0x90, 0x0, 0x0, 0x0, + 0x40, 0xd2, 0x96, 0x0, 0x23, 0x0, 0x0, 0xb0, + 0xc0, 0x10, 0x4, 0xb, 0x40, 0x7, 0x80, 0xc0, + 0x0, 0x8, 0x24, 0x60, 0x0, 0x0, 0xac, 0xaa, + 0xad, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+600E "怎" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xb5, 0x55, 0x55, 0x6c, 0x10, 0x0, 0x1a, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x81, 0xc, 0x55, + 0x56, 0xb0, 0x0, 0x5, 0x10, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, 0xb7, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x30, 0xc1, 0x1d, 0x0, 0x17, 0x0, 0x0, 0x90, + 0xc0, 0x6, 0x0, 0x36, 0xb0, 0x9, 0x70, 0xc0, + 0x0, 0x1, 0x60, 0xa0, 0x4, 0x0, 0x8b, 0xaa, + 0xac, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6012 "怒" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x60, 0x1, 0x11, 0x15, 0x0, 0x5, 0x5d, + 0x57, 0x67, 0x44, 0x7c, 0x0, 0x0, 0x28, 0x9, + 0x31, 0x50, 0xa3, 0x0, 0x0, 0x92, 0xb, 0x0, + 0x76, 0x90, 0x0, 0x0, 0x26, 0xc9, 0x0, 0x4f, + 0x40, 0x0, 0x0, 0x7, 0x58, 0x55, 0x71, 0xb9, + 0x30, 0x4, 0x61, 0x3, 0x52, 0x0, 0x6, 0x80, + 0x10, 0x0, 0x10, 0x55, 0x0, 0x10, 0x0, 0x0, + 0x40, 0xb2, 0xd, 0x30, 0x39, 0x0, 0x0, 0xa0, + 0xb1, 0x4, 0x2, 0x8, 0x90, 0x7, 0x70, 0xb1, + 0x0, 0x6, 0x20, 0x40, 0x0, 0x0, 0x8c, 0xbb, + 0xbd, 0x50, 0x0, + + /* U+6015 "怕" */ + 0x0, 0x3, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0x7, 0x70, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x80, 0x0, 0x0, 0x0, 0xc0, 0x9, 0x57, + 0x55, 0xc2, 0x1, 0x2c, 0xa2, 0xc0, 0x0, 0xc, + 0x0, 0x64, 0xc3, 0x3c, 0x0, 0x0, 0xc0, 0xd, + 0x2c, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc0, + 0xc, 0x55, 0x55, 0xd0, 0x0, 0xc, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc, 0x0, + 0x0, 0xc0, 0xc, 0x55, 0x55, 0xd0, 0x0, 0xd, + 0x0, 0xc0, 0x0, 0xb, 0x0, 0x0, 0x20, 0x1, + 0x0, 0x0, 0x0, + + /* U+601D "思" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x55, 0x58, 0x55, 0x5d, 0x0, 0x0, 0xc, + 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, + 0xc, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, 0x5d, + 0x55, 0x5c, 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, + 0xc, 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0xc, + 0x0, 0x0, 0xd, 0x55, 0x65, 0x55, 0x5b, 0x0, + 0x0, 0x1, 0x30, 0x69, 0x0, 0x0, 0x0, 0x0, + 0x60, 0x95, 0xb, 0x20, 0x33, 0x91, 0x1, 0xb0, + 0x93, 0x0, 0x0, 0xc3, 0x6b, 0x8, 0x80, 0x94, + 0x0, 0x0, 0xe6, 0x6, 0x0, 0x0, 0x6d, 0xbb, + 0xbc, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6025 "急" */ + 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0x10, 0x12, 0x0, 0x0, 0x0, 0x1, + 0xb5, 0x55, 0xba, 0x0, 0x0, 0x0, 0x8, 0x0, + 0x2, 0x70, 0x2, 0x0, 0x0, 0x76, 0x55, 0x56, + 0x55, 0x8c, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x49, 0x0, 0x0, 0x2, 0x65, 0x55, 0x55, 0x79, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, + 0x0, 0x6, 0x55, 0x96, 0x55, 0x77, 0x0, 0x0, + 0x10, 0xb2, 0x1d, 0x11, 0x14, 0x0, 0x0, 0x80, + 0xc0, 0x3, 0x5, 0x7, 0x90, 0x5, 0xb0, 0xc0, + 0x0, 0x7, 0x20, 0x90, 0x2, 0x10, 0x9b, 0xaa, + 0xad, 0x50, 0x0, + + /* U+6027 "性" */ + 0x0, 0x13, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x1a, + 0x0, 0x77, 0xc, 0x0, 0x0, 0x0, 0x1c, 0x40, + 0xa3, 0xc, 0x0, 0x10, 0x2, 0x4a, 0xa3, 0xd5, + 0x5d, 0x57, 0xa0, 0x7, 0x5a, 0x14, 0x60, 0xc, + 0x0, 0x0, 0xa, 0x2a, 0x7, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x1a, 0x2, 0x45, 0x5d, 0x59, 0x70, + 0x0, 0x1a, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1a, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1a, 0x0, + 0x0, 0xc, 0x0, 0x71, 0x0, 0x2b, 0x7, 0x55, + 0x55, 0x55, 0x53, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+606F "息" */ + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x37, 0x0, 0x5, 0x0, 0x0, 0xd, 0x55, + 0x55, 0x55, 0xe0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xc0, + 0x0, 0x0, 0xd5, 0x55, 0x55, 0x5c, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd5, + 0x55, 0x55, 0x5d, 0x0, 0x0, 0x5, 0x0, 0x83, + 0x0, 0x30, 0x0, 0x2, 0xc, 0x22, 0xf0, 0x0, + 0x40, 0x0, 0x90, 0xd0, 0x3, 0x3, 0x17, 0x80, + 0xa8, 0xd, 0x0, 0x0, 0x54, 0x1c, 0x4, 0x0, + 0x9b, 0xaa, 0xac, 0x60, 0x0, + + /* U+60A8 "您" */ + 0x0, 0x2, 0x10, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x96, 0x8, 0x90, 0x0, 0x0, 0x0, 0x1c, 0x0, + 0xd5, 0x55, 0x59, 0x30, 0x9, 0xa0, 0x62, 0x3, + 0x0, 0xa2, 0x4, 0x6a, 0x23, 0x20, 0xc1, 0x20, + 0x0, 0x41, 0xa0, 0x1d, 0x1c, 0x7, 0x10, 0x0, + 0x1a, 0x8, 0x20, 0xc0, 0x2d, 0x10, 0x1, 0xa3, + 0x14, 0x8e, 0x0, 0x61, 0x0, 0x15, 0x0, 0x44, + 0x40, 0x0, 0x0, 0x1, 0x18, 0x55, 0x90, 0x2, + 0x40, 0x0, 0x81, 0x73, 0x7, 0x0, 0x48, 0x70, + 0x4e, 0x7, 0x30, 0x0, 0x28, 0x9, 0x1, 0x10, + 0x4b, 0x99, 0x9b, 0x80, 0x0, + + /* U+60AA "悪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, + 0x55, 0x65, 0x56, 0x58, 0xa0, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0x0, 0x8, 0x65, 0xd5, 0x5d, + 0x5c, 0x30, 0x0, 0x92, 0xc, 0x0, 0xc0, 0xb0, + 0x0, 0x9, 0x75, 0xd5, 0x5d, 0x5c, 0x10, 0x0, + 0x30, 0xc, 0x0, 0xc0, 0x24, 0x0, 0x55, 0x55, + 0x95, 0x59, 0x56, 0xa3, 0x0, 0x0, 0x20, 0x64, + 0x0, 0x0, 0x0, 0x3, 0x1d, 0x0, 0xc3, 0x1, + 0x70, 0x0, 0x91, 0xb0, 0x2, 0x4, 0x7, 0x70, + 0xb8, 0x1b, 0x0, 0x0, 0x63, 0x17, 0x3, 0x0, + 0xdb, 0xbb, 0xbd, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+60B2 "悲" */ + 0x0, 0x0, 0x3, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x3, 0x55, + 0x5c, 0x0, 0xd5, 0x57, 0x50, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x2, 0x0, 0x0, 0x55, 0x5c, 0x0, + 0xd5, 0x57, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, + 0x0, 0x10, 0x5, 0x55, 0x5c, 0x0, 0xd5, 0x57, + 0x70, 0x0, 0x0, 0xd, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x21, 0x46, 0x0, 0x11, 0x0, 0x0, + 0x40, 0xd1, 0xb, 0x30, 0x9, 0x40, 0x2, 0x80, + 0xc0, 0x2, 0x0, 0x41, 0xb0, 0xc, 0x40, 0xc0, + 0x0, 0x1, 0x80, 0x10, 0x0, 0x0, 0xbb, 0xaa, + 0xac, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+60C5 "情" */ + 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, 0xa, + 0x40, 0x0, 0xd, 0x0, 0x0, 0x0, 0xa2, 0x26, + 0x55, 0xd5, 0x6a, 0x0, 0x1a, 0x93, 0x0, 0xc, + 0x3, 0x0, 0x7, 0xa4, 0x74, 0x65, 0xd5, 0x63, + 0x4, 0x9a, 0x24, 0x55, 0x5d, 0x55, 0x86, 0x21, + 0xa2, 0x12, 0x0, 0x0, 0x20, 0x0, 0xa, 0x20, + 0xa5, 0x55, 0x5c, 0x30, 0x0, 0xa2, 0xa, 0x65, + 0x55, 0xc1, 0x0, 0xa, 0x20, 0xa1, 0x0, 0xa, + 0x10, 0x0, 0xa2, 0xa, 0x65, 0x55, 0xc1, 0x0, + 0xa, 0x20, 0xa1, 0x0, 0xa, 0x10, 0x0, 0xa2, + 0xa, 0x10, 0x28, 0xe0, 0x0, 0x2, 0x0, 0x20, + 0x0, 0x2, 0x0, + + /* U+60F3 "想" */ + 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x8, 0x55, 0x59, 0x10, 0x0, 0x8, + 0x24, 0xb, 0x0, 0xb, 0x0, 0x6, 0x5c, 0x78, + 0x2c, 0x55, 0x5c, 0x0, 0x0, 0x1f, 0x70, 0xb, + 0x0, 0xb, 0x0, 0x0, 0x8c, 0x6c, 0xc, 0x55, + 0x5c, 0x0, 0x2, 0x78, 0x25, 0xb, 0x0, 0xb, + 0x0, 0x6, 0x9, 0x20, 0xd, 0x55, 0x5c, 0x0, + 0x10, 0x7, 0x20, 0x46, 0x0, 0x4, 0x0, 0x0, + 0x0, 0x71, 0x2d, 0x0, 0x2, 0x0, 0x0, 0x70, + 0xb0, 0x7, 0x14, 0x7, 0x60, 0x4, 0xa0, 0xb0, + 0x0, 0x6, 0x10, 0xc0, 0x4, 0x20, 0x8a, 0x99, + 0x9c, 0x40, 0x0, + + /* U+6108 "愈" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, + 0x17, 0x0, 0x0, 0x0, 0x3, 0x93, 0x11, 0x7b, + 0x61, 0x0, 0x35, 0x52, 0x36, 0x33, 0x17, 0xda, + 0x10, 0xc, 0x55, 0xb0, 0x80, 0xc0, 0x0, 0x0, + 0xb4, 0x4a, 0x9, 0xa, 0x0, 0x0, 0xc, 0x55, + 0xa0, 0xa0, 0xa0, 0x0, 0x0, 0xa0, 0x69, 0x3, + 0x2b, 0x0, 0x0, 0x5, 0x23, 0x84, 0x5, 0x60, + 0x0, 0x1, 0x18, 0x40, 0xc0, 0x0, 0x70, 0x0, + 0xa1, 0x83, 0x0, 0x2, 0x15, 0xa0, 0x27, 0x5, + 0xb9, 0x99, 0xb6, 0x2, 0x0, + + /* U+610F "意" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x75, 0x0, 0x30, 0x0, 0x0, 0x25, + 0x76, 0x66, 0x97, 0x80, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xa1, 0x1, 0x0, 0x6, 0x55, 0x57, 0x56, + 0x65, 0x59, 0x80, 0x0, 0x7, 0x55, 0x55, 0x55, + 0x70, 0x0, 0x0, 0xb, 0x0, 0x0, 0x2, 0x90, + 0x0, 0x0, 0xc, 0x55, 0x55, 0x56, 0x90, 0x0, + 0x0, 0xc, 0x55, 0x55, 0x56, 0x90, 0x0, 0x0, + 0x5, 0x20, 0x71, 0x1, 0x30, 0x0, 0x0, 0x50, + 0xc0, 0x3a, 0x1, 0x39, 0x10, 0x2, 0xa0, 0xb0, + 0x1, 0x6, 0x6, 0x90, 0x8, 0x40, 0xaa, 0x99, + 0x9d, 0x10, 0x10, + + /* U+611A "愚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x58, 0x55, 0x5c, 0x0, 0x0, 0xc0, 0x9, 0x10, + 0xb, 0x0, 0x0, 0xd5, 0x5b, 0x65, 0x5b, 0x0, + 0x0, 0xd5, 0x5b, 0x65, 0x5c, 0x0, 0x3, 0x30, + 0x9, 0x10, 0x1, 0x50, 0xd, 0x55, 0x5b, 0x67, + 0x55, 0xc1, 0xc, 0x1, 0x2a, 0x57, 0xb0, 0xb0, + 0xc, 0xb, 0x74, 0x10, 0x60, 0xb0, 0xb, 0x1, + 0x1a, 0x20, 0x29, 0xb0, 0x3, 0xc, 0x4, 0x80, + 0x23, 0x60, 0x1a, 0xb, 0x0, 0x0, 0x60, 0x97, + 0x74, 0x9, 0xa9, 0x99, 0xc4, 0x13, + + /* U+611B "愛" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x1, 0x24, + 0x57, 0x8a, 0xcc, 0x50, 0x1, 0x43, 0x7, 0x10, + 0x86, 0x0, 0x2, 0xb, 0x2, 0x60, 0x70, 0x12, + 0x2a, 0x56, 0x5a, 0x75, 0x55, 0xb7, 0xa4, 0x5a, + 0x31, 0xd1, 0x13, 0x80, 0x8, 0x59, 0x30, 0x10, + 0x64, 0x4c, 0x6, 0x4, 0xaa, 0xaa, 0x92, 0x2, + 0x0, 0xa, 0x50, 0x0, 0x10, 0x0, 0x0, 0x5a, + 0x85, 0x59, 0xc0, 0x0, 0x4, 0x50, 0x64, 0x5a, + 0x10, 0x0, 0x1, 0x0, 0x2d, 0xe2, 0x0, 0x0, + 0x2, 0x57, 0x61, 0x3a, 0xdb, 0x93, 0x12, 0x0, + 0x0, 0x0, 0x3, 0x30, + + /* U+611F "感" */ + 0x0, 0x0, 0x0, 0x0, 0x41, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb0, 0xa2, 0x0, 0x0, 0x95, + 0x55, 0x55, 0xc5, 0x67, 0xb0, 0x0, 0xb0, 0x0, + 0x2, 0x91, 0x3, 0x0, 0x0, 0xb3, 0x55, 0x56, + 0x73, 0x2d, 0x10, 0x0, 0xb0, 0x85, 0x58, 0x48, + 0xb3, 0x0, 0x0, 0xb0, 0xb0, 0x1a, 0xe, 0x70, + 0x10, 0x3, 0x70, 0xd5, 0x6a, 0x4a, 0xa0, 0x50, + 0x8, 0x0, 0x60, 0x7, 0x40, 0x5c, 0xb0, 0x22, + 0x0, 0x50, 0x75, 0x0, 0x32, 0x82, 0x0, 0x70, + 0xd0, 0xc, 0x2, 0xc, 0x20, 0x7, 0x80, 0xb0, + 0x0, 0x7, 0x6, 0x40, 0x5, 0x10, 0xb9, 0x99, + 0x9c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+614B "態" */ + 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, + 0x51, 0x1, 0xb0, 0x4, 0x0, 0x47, 0x10, 0x47, + 0x1b, 0x58, 0x61, 0x8, 0xa8, 0x54, 0x91, 0xa0, + 0x0, 0x70, 0xa, 0x55, 0x96, 0xb, 0x99, 0xa8, + 0x0, 0xc5, 0x59, 0x51, 0xc0, 0x16, 0x0, 0xb, + 0x0, 0x75, 0x1b, 0x69, 0x61, 0x0, 0xc4, 0x49, + 0x51, 0xb0, 0x0, 0x60, 0xc, 0x6, 0xc4, 0xc, + 0xaa, 0xb8, 0x0, 0x20, 0x55, 0x2a, 0x10, 0x3, + 0x0, 0x6, 0xc, 0x10, 0x47, 0x4, 0x58, 0x4, + 0xb0, 0xc0, 0x0, 0x0, 0x70, 0xc0, 0x42, 0xa, + 0xba, 0xaa, 0xc9, 0x0, 0x0, + + /* U+6163 "慣" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xb2, 0x0, 0xc5, 0x87, 0x5c, 0x0, 0x0, 0xb0, + 0x0, 0xb0, 0x92, 0x1a, 0x50, 0x2, 0xb6, 0x56, + 0xb5, 0xd5, 0x8a, 0x50, 0x7, 0xb6, 0x55, 0xa5, + 0xd5, 0x97, 0x0, 0x49, 0xb2, 0x21, 0x10, 0x0, + 0x22, 0x0, 0x31, 0xb0, 0xa, 0x55, 0x55, 0x5c, + 0x0, 0x0, 0xb0, 0xb, 0x44, 0x44, 0x4b, 0x0, + 0x0, 0xb0, 0xb, 0x11, 0x11, 0x1b, 0x0, 0x0, + 0xb0, 0xb, 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb0, + 0xc, 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb0, 0x3, + 0xc4, 0x1, 0x84, 0x0, 0x0, 0xb0, 0x38, 0x20, + 0x0, 0x1d, 0x30, 0x0, 0x10, 0x20, 0x0, 0x0, + 0x1, 0x10, + + /* U+6167 "慧" */ + 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xc1, 0x40, 0xc, 0x3, 0x20, 0x36, 0x5c, 0x55, + 0x46, 0xc5, 0x53, 0x0, 0x65, 0xc6, 0x53, 0x6c, + 0x59, 0x10, 0x45, 0x5c, 0x59, 0x35, 0xc5, 0x59, + 0x1, 0x0, 0xa0, 0x0, 0x1a, 0x0, 0x0, 0x3, + 0x65, 0x55, 0x55, 0x59, 0x70, 0x0, 0x5, 0x55, + 0x55, 0x55, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x50, 0x0, 0x27, 0x65, 0x95, 0x55, 0x83, + 0x0, 0x4, 0xa, 0x35, 0x90, 0x21, 0x70, 0x0, + 0xa0, 0xa2, 0x3, 0x7, 0x13, 0xb0, 0x33, 0x7, + 0xb9, 0x99, 0xc3, 0x3, 0x0, + + /* U+616E "慮" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x11, 0x50, 0x0, 0x0, 0x10, + 0x0, 0x1b, 0x44, 0x42, 0x0, 0x0, 0xb6, 0x55, + 0x6a, 0x56, 0x5c, 0x50, 0x0, 0xa1, 0x24, 0x6b, + 0x58, 0x35, 0x0, 0x0, 0xb1, 0x30, 0x1a, 0x22, + 0x39, 0x0, 0x0, 0xb0, 0x20, 0x4, 0x66, 0xa3, + 0x0, 0x0, 0xb0, 0xc5, 0x5b, 0x65, 0xc2, 0x0, + 0x0, 0xb0, 0xb5, 0x5b, 0x65, 0xc0, 0x0, 0x0, + 0x90, 0xc5, 0x5a, 0x65, 0xc0, 0x0, 0x4, 0x40, + 0x28, 0x5, 0x60, 0x14, 0x0, 0x7, 0x4, 0x3d, + 0x0, 0x91, 0x42, 0xd0, 0x32, 0x3d, 0xb, 0xba, + 0xab, 0x80, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+61C9 "應" */ + 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x2b, 0x0, 0x1, 0x40, 0x0, 0xc5, + 0x56, 0x57, 0x76, 0x56, 0x70, 0x0, 0xc0, 0x2d, + 0x6b, 0x1b, 0x1, 0x0, 0x0, 0xc0, 0xb2, 0xc6, + 0x5a, 0x57, 0x40, 0x0, 0xc4, 0xc4, 0xc5, 0x5c, + 0x59, 0x0, 0x0, 0xc0, 0xb1, 0xa1, 0xa, 0x4, + 0x0, 0x0, 0xb0, 0xb0, 0xa5, 0x5c, 0x55, 0x10, + 0x0, 0xb0, 0xb0, 0xa5, 0x59, 0x56, 0x80, 0x3, + 0x80, 0x40, 0x41, 0x0, 0x1, 0x0, 0x7, 0x34, + 0x39, 0xa, 0x60, 0x24, 0x70, 0x8, 0x1b, 0x28, + 0x0, 0x60, 0x70, 0xc1, 0x23, 0x54, 0xc, 0xaa, + 0xab, 0xd1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+61F8 "懸" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, + 0xa5, 0x5b, 0x33, 0x57, 0x9a, 0x70, 0x0, 0xb5, + 0x5b, 0x10, 0x19, 0x65, 0x10, 0x0, 0xa4, 0x4b, + 0x13, 0xd6, 0x9a, 0x30, 0x0, 0xa5, 0x5b, 0x10, + 0x5a, 0x32, 0x50, 0x0, 0xa0, 0x9, 0x55, 0xf9, + 0xa5, 0xb2, 0x6, 0x97, 0xa5, 0x54, 0x60, 0xb3, + 0x10, 0x2, 0xa4, 0x79, 0x24, 0xa1, 0xb3, 0xa0, + 0x5, 0x2a, 0x52, 0x65, 0x26, 0xa0, 0x81, 0x0, + 0x3, 0x50, 0x52, 0x6, 0x31, 0x0, 0x0, 0x51, + 0x90, 0x1d, 0x10, 0x8, 0x50, 0x4, 0xa1, 0x90, + 0x2, 0x0, 0x60, 0xc0, 0x7, 0x20, 0xca, 0xaa, + 0xac, 0xa0, 0x0, + + /* U+6210 "成" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x15, 0x70, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0xc3, 0x0, 0x0, 0x75, 0x55, + 0x5e, 0x55, 0x6b, 0x60, 0x0, 0xc1, 0x0, 0xb, + 0x10, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x9, 0x30, + 0x38, 0x0, 0x0, 0xc5, 0x58, 0x46, 0x60, 0x97, + 0x0, 0x0, 0xc0, 0x9, 0x33, 0x90, 0xd0, 0x0, + 0x0, 0xc0, 0xa, 0x10, 0xd7, 0x70, 0x0, 0x0, + 0xb0, 0xb, 0x0, 0x8e, 0x0, 0x20, 0x2, 0x74, + 0x6c, 0x0, 0xbd, 0x50, 0x60, 0x7, 0x10, 0x75, + 0x19, 0x12, 0xd9, 0x90, 0x6, 0x0, 0x2, 0x50, + 0x0, 0x9, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6211 "我" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x8d, 0x6a, 0x51, 0x30, 0x0, 0x2, 0x43, + 0xc0, 0xa, 0x20, 0x99, 0x0, 0x0, 0x0, 0xc0, + 0x9, 0x20, 0x9, 0x0, 0x5, 0x55, 0xd5, 0x5b, + 0x75, 0x5a, 0x90, 0x1, 0x0, 0xc0, 0x7, 0x40, + 0x1, 0x0, 0x0, 0x0, 0xc0, 0x5, 0x60, 0x79, + 0x0, 0x0, 0x1, 0xe6, 0x33, 0x82, 0xb0, 0x0, + 0x18, 0xc8, 0xc0, 0x0, 0xcb, 0x10, 0x0, 0x6, + 0x10, 0xc0, 0x1, 0xe5, 0x0, 0x10, 0x0, 0x0, + 0xc0, 0x29, 0x4c, 0x10, 0x50, 0x0, 0x43, 0xc4, + 0x50, 0x2, 0xd6, 0x90, 0x0, 0x2d, 0x60, 0x0, + 0x0, 0x18, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6216 "或" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0xb4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x15, 0x40, 0x6, 0x55, 0x55, + 0x55, 0xd5, 0x56, 0x70, 0x0, 0x0, 0x1, 0x0, + 0xc0, 0x1, 0x0, 0x0, 0xd5, 0x5c, 0x50, 0xc0, + 0xe, 0x10, 0x0, 0xc0, 0xa, 0x20, 0xa2, 0x4a, + 0x0, 0x0, 0xc0, 0xa, 0x20, 0x74, 0xa3, 0x0, + 0x0, 0xd5, 0x5c, 0x20, 0x3b, 0xb0, 0x0, 0x0, + 0x50, 0x0, 0x0, 0xf, 0x40, 0x10, 0x0, 0x35, + 0x77, 0x54, 0x98, 0xb0, 0x50, 0x1f, 0xa5, 0x10, + 0x28, 0x10, 0x7c, 0xa0, 0x0, 0x0, 0x5, 0x40, + 0x0, 0x5, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6226 "戦" */ + 0x0, 0x2, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8, + 0x18, 0x51, 0xb0, 0xe, 0x25, 0x0, 0x4, 0x81, + 0x66, 0x10, 0xc, 0x9, 0x50, 0x9, 0x55, 0x77, + 0xb0, 0xc, 0x1, 0x20, 0xb, 0x1, 0x90, 0xb0, + 0x2d, 0x55, 0x80, 0xb, 0x55, 0xb5, 0xb5, 0x3c, + 0x4, 0x20, 0xb, 0x1, 0x90, 0xb0, 0xc, 0xc, + 0x40, 0xb, 0x55, 0xb5, 0xb0, 0xc, 0x59, 0x0, + 0x7, 0x1, 0x90, 0x60, 0x9, 0xd1, 0x0, 0x0, + 0x1, 0x90, 0x43, 0x8, 0x90, 0x0, 0x27, 0x55, + 0xb5, 0x54, 0x4a, 0xd1, 0x51, 0x0, 0x1, 0x90, + 0x3, 0x90, 0x4d, 0xb0, 0x0, 0x1, 0xa0, 0x56, + 0x0, 0x6, 0xf1, 0x0, 0x0, 0x10, 0x10, 0x0, + 0x0, 0x31, + + /* U+6230 "戰" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0xa, + 0x5b, 0x57, 0xb2, 0xd, 0x34, 0x0, 0xa, 0xa, + 0x55, 0x91, 0xd, 0xa, 0x40, 0xb, 0x5b, 0x58, + 0xb1, 0xc, 0x1, 0x10, 0x5, 0x2, 0x21, 0x50, + 0xc, 0x46, 0x80, 0x7, 0x77, 0x95, 0xc3, 0x5c, + 0x3, 0x10, 0x7, 0x77, 0x95, 0xa0, 0xb, 0xb, + 0x40, 0x7, 0x33, 0x70, 0xa0, 0xa, 0x4a, 0x0, + 0x8, 0x77, 0x95, 0xa0, 0x7, 0xd2, 0x0, 0x3, + 0x3, 0x70, 0x20, 0x6, 0xb0, 0x0, 0x6, 0x57, + 0x95, 0x74, 0x2a, 0xb3, 0x60, 0x0, 0x3, 0x70, + 0x2, 0x80, 0x2d, 0xb0, 0x0, 0x4, 0x70, 0x34, + 0x0, 0x4, 0xf0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x21, + + /* U+623B "戻" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x55, 0x5a, 0x55, 0x5a, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0xe, 0x55, 0x55, 0x55, + 0x5c, 0x0, 0x0, 0x1c, 0x0, 0x8, 0x40, 0x4, + 0x0, 0x0, 0x3a, 0x0, 0xc, 0x20, 0x3, 0x0, + 0x0, 0x66, 0x65, 0x5d, 0x75, 0x58, 0x40, 0x0, + 0xa1, 0x0, 0x75, 0x43, 0x0, 0x0, 0x1, 0x90, + 0x3, 0xa0, 0x9, 0x30, 0x0, 0x7, 0x10, 0x38, + 0x0, 0x0, 0xb9, 0x20, 0x14, 0x15, 0x40, 0x0, + 0x0, 0x8, 0xc2, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+623F "房" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x3a, + 0x55, 0x56, 0x55, 0x5d, 0x10, 0x0, 0x39, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x2b, 0x55, 0x55, + 0x55, 0x5d, 0x0, 0x0, 0x38, 0x0, 0x8, 0x30, + 0x1, 0x0, 0x0, 0x47, 0x0, 0x2, 0x70, 0x1, + 0x50, 0x0, 0x56, 0x55, 0x8b, 0x55, 0x55, 0x50, + 0x0, 0x82, 0x0, 0x68, 0x0, 0x5, 0x0, 0x0, + 0xa0, 0x0, 0xb7, 0x55, 0x5e, 0x10, 0x2, 0x70, + 0x2, 0xd0, 0x0, 0x1c, 0x0, 0x6, 0x10, 0x1c, + 0x20, 0x0, 0x3a, 0x0, 0x13, 0x2, 0x92, 0x0, + 0x17, 0xd5, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x40, 0x0, + + /* U+6240 "所" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x21, 0x6b, 0x52, 0x4, 0x8c, 0x60, 0x0, 0xd4, + 0x0, 0xa, 0x61, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0xa, 0x30, 0x0, 0x0, 0x0, 0xd5, 0x59, 0x29, + 0x30, 0x0, 0x20, 0x0, 0xc0, 0xc, 0x9, 0x75, + 0x96, 0x80, 0x0, 0xc0, 0xc, 0xa, 0x20, 0xb0, + 0x0, 0x0, 0xd5, 0x5d, 0xc, 0x0, 0xb0, 0x0, + 0x0, 0xc0, 0x8, 0xb, 0x0, 0xb0, 0x0, 0x0, + 0xb0, 0x0, 0x47, 0x0, 0xb0, 0x0, 0x4, 0x60, + 0x0, 0x91, 0x0, 0xb0, 0x0, 0x7, 0x0, 0x4, + 0x50, 0x0, 0xb0, 0x0, 0x15, 0x0, 0x15, 0x0, + 0x0, 0xb1, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, + 0x10, 0x0, + + /* U+624B "手" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x25, 0x8c, 0xf3, 0x0, 0x2, 0x45, + 0x66, 0xd4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x55, 0x55, 0xd5, + 0x55, 0xd5, 0x0, 0x0, 0x10, 0x0, 0xc1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, + 0x0, 0x25, 0x55, 0x55, 0xd5, 0x55, 0x5b, 0xa0, + 0x1, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+624D "才" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x50, 0x5, 0x65, 0x55, 0x5c, + 0xd5, 0x56, 0x71, 0x0, 0x0, 0x0, 0x6a, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xd1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x30, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x75, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x6, 0x50, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x63, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x5, 0x10, 0x1, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9f, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x0, 0x0, + + /* U+6253 "打" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x55, 0x57, 0x58, 0x90, 0x15, 0x5d, 0x5a, + 0x10, 0xd, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0xd, + 0x0, 0x0, 0x0, 0xc, 0x73, 0x0, 0xd, 0x0, + 0x0, 0x29, 0xbd, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x5, 0xc, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x3, 0x2d, 0x0, + 0x3, 0x1d, 0x0, 0x0, 0x1, 0xbc, 0x0, 0x2, + 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+6255 "払" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x8, 0x50, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xd3, 0x0, 0x1, 0x55, 0xd5, 0xa1, 0x1d, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x5, 0x80, 0x0, + 0x0, 0x0, 0xb0, 0x11, 0x92, 0x0, 0x0, 0x0, + 0xc, 0x74, 0xb, 0x0, 0x0, 0x2, 0xab, 0xd0, + 0x3, 0x70, 0x4, 0x0, 0x5, 0xb, 0x0, 0x72, + 0x0, 0x43, 0x0, 0x0, 0xb0, 0x9, 0x0, 0x0, + 0xb0, 0x0, 0xb, 0x3, 0x60, 0x0, 0x8, 0x70, + 0x32, 0xd0, 0xcb, 0xa9, 0x76, 0x7c, 0x1, 0xbb, + 0x4, 0x40, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+627E "找" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x8, 0x61, 0x40, 0x0, 0x0, 0xc, + 0x0, 0x8, 0x40, 0x8a, 0x0, 0x0, 0xc, 0x4, + 0x8, 0x40, 0x5, 0x0, 0x16, 0x5d, 0x55, 0x19, + 0x64, 0x5b, 0x30, 0x0, 0xc, 0x3, 0x39, 0x40, + 0x0, 0x0, 0x0, 0xc, 0x64, 0x7, 0x50, 0x6a, + 0x0, 0x28, 0xae, 0x0, 0x5, 0x74, 0xc1, 0x0, + 0x16, 0xc, 0x0, 0x2, 0xdb, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x5, 0xf2, 0x0, 0x30, 0x0, 0xc, + 0x0, 0x75, 0x2c, 0x10, 0x60, 0x3, 0x3d, 0x5, + 0x10, 0x4, 0xd8, 0x70, 0x1, 0xaa, 0x0, 0x0, + 0x0, 0x2b, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6280 "技" */ + 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x0, 0xe, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x15, 0x5d, 0x6a, + 0x35, 0x5d, 0x55, 0xb1, 0x0, 0xc, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc, 0x75, 0x47, 0x59, 0x5d, + 0x30, 0x18, 0xbd, 0x0, 0x6, 0x0, 0x1b, 0x0, + 0x6, 0xc, 0x0, 0x3, 0x40, 0x84, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x94, 0xb0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x5f, 0x20, 0x0, 0x1, 0xc, 0x0, + 0x7, 0x95, 0xc4, 0x0, 0x3, 0xcc, 0x15, 0x72, + 0x0, 0x2a, 0xd3, 0x0, 0x10, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+628A "把" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x10, 0x0, 0x2, 0x0, 0x0, 0xc, + 0x0, 0xd5, 0x5b, 0x5d, 0x30, 0x15, 0x5d, 0x77, + 0xc0, 0xb, 0xb, 0x0, 0x0, 0xc, 0x0, 0xc0, + 0xb, 0xb, 0x0, 0x0, 0xc, 0x0, 0xc0, 0xb, + 0xb, 0x0, 0x0, 0xd, 0x73, 0xd5, 0x57, 0x5c, + 0x10, 0x2a, 0xbd, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x5, 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0x0, 0x50, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0x0, 0xa0, 0x5, 0xbb, 0x0, 0xab, + 0xaa, 0xab, 0xd0, 0x0, 0x21, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6295 "投" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x9, 0x55, 0xa1, 0x0, 0x0, 0xc, + 0x0, 0xb, 0x0, 0xc0, 0x0, 0x5, 0x5d, 0x78, + 0x2a, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x55, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x1, 0x90, 0x0, + 0x8a, 0xb3, 0x0, 0xd, 0x67, 0x65, 0x55, 0x87, + 0x0, 0x18, 0xbc, 0x0, 0x5, 0x0, 0xa3, 0x0, + 0x6, 0xc, 0x0, 0x6, 0x11, 0xb0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x9a, 0x30, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xac, 0x0, 0x0, 0x1, 0xc, 0x0, + 0x19, 0x57, 0xc3, 0x0, 0x3, 0xc8, 0x15, 0x60, + 0x0, 0x3c, 0xb1, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+62BC "押" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x85, 0x55, 0x55, 0xa0, 0x0, 0xc, + 0x0, 0xc0, 0xc, 0x1, 0xb0, 0x5, 0x5d, 0x95, + 0xc0, 0xc, 0x1, 0xb0, 0x0, 0xc, 0x0, 0xd5, + 0x5d, 0x56, 0xb0, 0x0, 0xc, 0x1, 0xc0, 0xc, + 0x1, 0xb0, 0x0, 0xe, 0x61, 0xc0, 0xc, 0x1, + 0xb0, 0x17, 0xbc, 0x0, 0xd5, 0x5d, 0x56, 0xb0, + 0x19, 0xc, 0x0, 0xa0, 0xc, 0x0, 0x60, 0x0, + 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, 0x2c, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x3, 0xd7, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+62C5 "担" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0xc, + 0x0, 0x96, 0x55, 0x5e, 0x10, 0x0, 0xc, 0x13, + 0x92, 0x0, 0xd, 0x0, 0x5, 0x5d, 0x54, 0x92, + 0x0, 0xd, 0x0, 0x0, 0xc, 0x1, 0x97, 0x55, + 0x5d, 0x0, 0x0, 0xc, 0x71, 0x92, 0x0, 0xd, + 0x0, 0x5, 0xbe, 0x0, 0x92, 0x0, 0xd, 0x0, + 0x1a, 0x1c, 0x0, 0x92, 0x0, 0xd, 0x0, 0x0, + 0xc, 0x0, 0xa7, 0x55, 0x5e, 0x0, 0x0, 0xc, + 0x0, 0x50, 0x0, 0x2, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x2, 0x70, 0x3, 0xbc, 0x6, 0x55, + 0x55, 0x55, 0x50, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+62C9 "拉" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0x70, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x2, 0x2c, 0x36, + 0x0, 0x16, 0x1, 0x0, 0x3, 0x2c, 0x22, 0x55, + 0x55, 0x58, 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x42, 0x0, 0x0, 0xc, 0x64, 0x23, 0x0, 0x97, + 0x0, 0x2, 0x9e, 0x10, 0xa, 0x0, 0xb1, 0x0, + 0x2d, 0x3c, 0x0, 0xa, 0x30, 0xb0, 0x0, 0x0, + 0xc, 0x0, 0x8, 0x73, 0x70, 0x0, 0x0, 0xc, + 0x0, 0x4, 0x27, 0x10, 0x0, 0x1, 0xd, 0x0, + 0x0, 0x7, 0x0, 0x50, 0x2, 0xbc, 0x6, 0x55, + 0x56, 0x56, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+62DB "招" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x25, 0x55, 0x55, 0x76, 0x0, 0xb, 0x0, + 0x6, 0x70, 0x7, 0x50, 0x55, 0xc6, 0x80, 0x83, + 0x0, 0x83, 0x0, 0xb, 0x0, 0xb, 0x0, 0xa, + 0x10, 0x0, 0xb0, 0x4, 0x60, 0x55, 0xd0, 0x0, + 0xc, 0x73, 0x80, 0x0, 0xa5, 0x1, 0x7b, 0xc0, + 0x46, 0x55, 0x55, 0x92, 0x8, 0xb, 0x0, 0xa1, + 0x0, 0xb, 0x0, 0x0, 0xb0, 0xa, 0x10, 0x0, + 0xb0, 0x0, 0xb, 0x0, 0xa1, 0x0, 0xb, 0x0, + 0x0, 0xb0, 0xa, 0x65, 0x55, 0xd0, 0x3, 0xc9, + 0x0, 0x90, 0x0, 0x8, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+62E1 "拡" */ + 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x20, 0xa, 0x0, 0x50, 0x0, 0xc, 0x12, + 0xd5, 0x55, 0x55, 0x61, 0x5, 0x5d, 0x54, 0xc0, + 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, 0xa, + 0x70, 0x0, 0x0, 0xc, 0x52, 0xc0, 0xd, 0x0, + 0x0, 0x0, 0x7d, 0x10, 0xc0, 0x38, 0x0, 0x0, + 0x2e, 0x5c, 0x0, 0xc0, 0x81, 0x0, 0x0, 0x1, + 0xc, 0x1, 0xa0, 0x80, 0x7, 0x0, 0x0, 0xc, + 0x5, 0x55, 0x30, 0x3, 0xa0, 0x0, 0xc, 0x9, + 0xd, 0xa8, 0x65, 0xd2, 0x5, 0xd8, 0x42, 0x3, + 0x0, 0x0, 0x50, 0x0, 0x10, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+62EC "括" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x0, 0x2, 0x7c, 0x10, 0x0, 0xc, + 0x0, 0x35, 0x7d, 0x41, 0x0, 0x17, 0x5d, 0x5a, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xc, 0x0, 0x30, 0x0, 0xc, 0x3, 0x65, 0x5d, + 0x56, 0x80, 0x0, 0xc, 0x54, 0x0, 0xc, 0x0, + 0x0, 0x16, 0xae, 0x10, 0x20, 0xc, 0x3, 0x0, + 0x19, 0x1c, 0x0, 0xc5, 0x55, 0x5d, 0x10, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x2, 0x2d, 0x0, + 0xc5, 0x55, 0x5d, 0x0, 0x1, 0xaa, 0x0, 0xc0, + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+62ED "拭" */ + 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x0, 0xd, 0x29, 0x30, 0x0, 0xc, + 0x0, 0x0, 0xd, 0x2, 0x80, 0x0, 0xc, 0x23, + 0x0, 0xc, 0x1, 0x50, 0x16, 0x5d, 0x54, 0x46, + 0x5d, 0x55, 0x50, 0x0, 0xc, 0x0, 0x0, 0xa, + 0x10, 0x0, 0x0, 0xd, 0x66, 0x55, 0x89, 0x20, + 0x0, 0x18, 0xbd, 0x0, 0xc, 0x6, 0x50, 0x0, + 0x18, 0xc, 0x0, 0xc, 0x3, 0x80, 0x0, 0x0, + 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xc, + 0x0, 0x1d, 0x63, 0x86, 0x41, 0x1, 0xc, 0xa, + 0xa4, 0x0, 0xd, 0xc0, 0x3, 0xd8, 0x0, 0x0, + 0x0, 0x1, 0xc2, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+62FF "拿" */ + 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb9, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x30, 0x66, 0x0, 0x0, 0x0, 0x17, 0x76, + 0x55, 0x86, 0xb9, 0x62, 0x4, 0x40, 0x85, 0x55, + 0x59, 0x13, 0x60, 0x0, 0x0, 0xc0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5a, 0x10, + 0x0, 0x0, 0x23, 0x45, 0x68, 0xac, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x2a, 0x0, 0x40, 0x0, 0x0, + 0x36, 0x55, 0x6c, 0x56, 0x92, 0x0, 0x4, 0x55, + 0x55, 0x6c, 0x55, 0x5a, 0x90, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+6301 "持" */ + 0x0, 0x4, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xc, + 0x1, 0x44, 0xc5, 0x49, 0x0, 0x5, 0x5d, 0x86, + 0x11, 0xb2, 0x11, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xb1, 0x0, 0x20, 0x0, 0xc, 0x6, 0x55, 0x86, + 0x56, 0x90, 0x0, 0xd, 0x62, 0x0, 0x7, 0x70, + 0x0, 0x7, 0xbc, 0x5, 0x55, 0x5a, 0x87, 0x90, + 0x6, 0xc, 0x1, 0x20, 0x7, 0x50, 0x0, 0x0, + 0xc, 0x0, 0x85, 0x7, 0x50, 0x0, 0x0, 0xc, + 0x0, 0x19, 0x7, 0x50, 0x0, 0x1, 0x1c, 0x0, + 0x0, 0x7, 0x50, 0x0, 0x2, 0xc8, 0x0, 0x0, + 0x7f, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+6307 "指" */ + 0x0, 0x5, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x8, 0x60, 0x3, 0x70, 0x0, 0xc, 0x0, + 0x83, 0x18, 0xa5, 0x0, 0x55, 0xd6, 0xb8, 0x75, + 0x10, 0x3, 0x1, 0xc, 0x0, 0x84, 0x0, 0x0, + 0x70, 0x0, 0xc0, 0x35, 0xc9, 0x99, 0xb9, 0x0, + 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, 0x4b, 0xe0, + 0x6, 0x75, 0x55, 0xc1, 0x1b, 0x2c, 0x0, 0x65, + 0x0, 0xc, 0x0, 0x0, 0xc0, 0x6, 0x85, 0x55, + 0xd0, 0x0, 0xc, 0x0, 0x65, 0x0, 0xc, 0x0, + 0x10, 0xd0, 0x6, 0x85, 0x55, 0xd0, 0x2, 0xba, + 0x0, 0x74, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6319 "挙" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x0, 0x91, 0x5, 0xb0, 0x0, 0x0, 0x5, + 0xb0, 0x5a, 0xa, 0x10, 0x0, 0x0, 0x0, 0x70, + 0x4, 0x34, 0x4, 0x30, 0x6, 0x55, 0xc5, 0x55, + 0x95, 0x57, 0x60, 0x0, 0x5, 0x80, 0x0, 0x66, + 0x0, 0x0, 0x0, 0x3a, 0x46, 0x9b, 0xa6, 0xb4, + 0x0, 0x5, 0x60, 0x0, 0xb0, 0x0, 0x7c, 0x80, + 0x31, 0x55, 0x55, 0xc5, 0x55, 0x71, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x7, 0x30, 0x7, 0x55, + 0x55, 0xc5, 0x55, 0x55, 0x40, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0x0, + + /* U+6355 "捕" */ + 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0xb2, 0x81, 0x0, 0x0, 0xb, + 0x0, 0x0, 0xb0, 0x36, 0x10, 0x0, 0xb, 0x45, + 0x55, 0xc5, 0x56, 0x90, 0x4, 0x4c, 0x41, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0xb, 0xa, 0x65, 0xc5, + 0x5c, 0x20, 0x0, 0xd, 0x59, 0x10, 0xb0, 0xb, + 0x0, 0x7, 0xbb, 0x9, 0x65, 0xc5, 0x5c, 0x0, + 0x7, 0xb, 0x9, 0x10, 0xb0, 0xb, 0x0, 0x0, + 0xb, 0x9, 0x65, 0xc5, 0x5c, 0x0, 0x0, 0xb, + 0x9, 0x10, 0xb0, 0xb, 0x0, 0x0, 0xb, 0x9, + 0x10, 0xb0, 0xb, 0x0, 0x4, 0xc7, 0xa, 0x10, + 0xb2, 0x8d, 0x0, 0x0, 0x10, 0x2, 0x0, 0x10, + 0x1, 0x0, + + /* U+6368 "捨" */ + 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x8, 0x57, 0x0, 0x0, 0x0, 0xc, 0x41, + 0x47, 0x2, 0x90, 0x0, 0x5, 0x5d, 0x55, 0x70, + 0x0, 0x8c, 0x72, 0x0, 0xc, 0x14, 0x25, 0xc5, + 0x63, 0x71, 0x0, 0xc, 0x43, 0x0, 0xb0, 0x2, + 0x20, 0x1, 0x8e, 0x24, 0x65, 0xc5, 0x56, 0x50, + 0xc, 0x4c, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc5, 0x85, 0x5d, 0x10, 0x0, 0xc, + 0x0, 0xb0, 0x0, 0xc, 0x0, 0x1, 0xc, 0x0, + 0xb0, 0x0, 0xc, 0x0, 0x4, 0xd8, 0x0, 0xd5, + 0x55, 0x5d, 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, + 0x1, 0x0, + + /* U+6388 "授" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xd, 0x0, 0x1, 0x47, 0xad, 0x40, 0x0, 0xb, + 0x1, 0x43, 0x30, 0x9, 0x20, 0x5, 0x5c, 0x84, + 0x90, 0xa2, 0x2a, 0x0, 0x0, 0xb, 0x0, 0x75, + 0x63, 0x71, 0x0, 0x0, 0xb, 0x27, 0x55, 0x55, + 0x85, 0xb0, 0x0, 0x1d, 0x5c, 0x0, 0x0, 0x5, + 0x30, 0x17, 0xab, 0x2, 0x55, 0x55, 0xa4, 0x0, + 0x17, 0xb, 0x0, 0x5, 0x2, 0xc1, 0x0, 0x0, + 0xb, 0x0, 0x3, 0x5b, 0x20, 0x0, 0x0, 0xb, + 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x2a, 0x48, 0x93, 0x0, 0x5, 0xd7, 0x16, 0x60, + 0x0, 0x4b, 0xc2, 0x0, 0x10, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+6392 "排" */ + 0x0, 0x5, 0x0, 0x4, 0x10, 0x40, 0x0, 0x0, + 0xc, 0x0, 0x9, 0x50, 0xd0, 0x0, 0x0, 0xb, + 0x0, 0x9, 0x20, 0xb0, 0x0, 0x5, 0x5c, 0x96, + 0x5b, 0x20, 0xc5, 0x84, 0x0, 0xb, 0x0, 0x9, + 0x20, 0xb0, 0x0, 0x0, 0xb, 0x11, 0x9, 0x20, + 0xb0, 0x10, 0x0, 0x2d, 0x52, 0x5b, 0x20, 0xc5, + 0x82, 0x1b, 0xab, 0x0, 0x9, 0x20, 0xb0, 0x0, + 0x3, 0xb, 0x0, 0x9, 0x20, 0xb0, 0x21, 0x0, + 0xb, 0x15, 0x5b, 0x20, 0xc5, 0x64, 0x0, 0xb, + 0x0, 0x9, 0x20, 0xb0, 0x0, 0x1, 0xb, 0x0, + 0x9, 0x20, 0xb0, 0x0, 0x3, 0xc7, 0x0, 0x9, + 0x20, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x10, 0x0, + + /* U+639B "掛" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xa3, 0x0, 0x1b, 0x0, 0xb2, 0x0, 0x0, 0xa1, + 0x0, 0x19, 0x0, 0xb0, 0x0, 0x0, 0xa2, 0x25, + 0x5b, 0x91, 0xb0, 0x0, 0x35, 0xc6, 0x40, 0x19, + 0x0, 0xb0, 0x0, 0x0, 0xa1, 0x0, 0x19, 0x13, + 0xb5, 0x0, 0x0, 0xa2, 0x35, 0x57, 0x54, 0xb4, + 0xb0, 0x3, 0xd4, 0x0, 0x1b, 0x0, 0xb0, 0xa0, + 0x6a, 0xb1, 0x15, 0x6b, 0x83, 0xb0, 0x0, 0x0, + 0xa1, 0x0, 0x19, 0x0, 0xb0, 0x0, 0x0, 0xa1, + 0x0, 0x19, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x2, + 0x5b, 0x53, 0xb0, 0x0, 0x8, 0xb0, 0x5b, 0x40, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63A1 "採" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0xd, 0x0, 0x14, 0x69, 0xcc, 0x10, 0x0, 0xb, + 0x3, 0x33, 0x0, 0x2, 0x40, 0x0, 0xb, 0x44, + 0x31, 0x90, 0x9, 0x60, 0x5, 0x5c, 0x52, 0xc2, + 0x85, 0x37, 0x0, 0x0, 0xb, 0x0, 0x40, 0x51, + 0x40, 0x0, 0x0, 0xb, 0x42, 0x0, 0x93, 0x2, + 0x40, 0x0, 0x6d, 0x24, 0x59, 0xf9, 0x55, 0x40, + 0x1e, 0x6b, 0x0, 0xb, 0xb8, 0x10, 0x0, 0x1, + 0xb, 0x0, 0x46, 0x92, 0xa0, 0x0, 0x0, 0xb, + 0x1, 0x80, 0x92, 0x69, 0x0, 0x0, 0xb, 0x7, + 0x0, 0x92, 0xb, 0xb2, 0x4, 0xd8, 0x20, 0x0, + 0x92, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+63A2 "探" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x75, 0x55, 0x55, 0x82, 0x0, 0xb, + 0x1, 0xb0, 0x0, 0x0, 0xa1, 0x0, 0xb, 0x44, + 0x25, 0x92, 0x51, 0x0, 0x5, 0x5c, 0x53, 0x1b, + 0x10, 0x3d, 0x30, 0x0, 0xb, 0x3, 0x81, 0x1a, + 0x3, 0x50, 0x0, 0xd, 0x62, 0x0, 0x1a, 0x0, + 0x50, 0x6, 0xbb, 0x5, 0x55, 0xec, 0x75, 0x63, + 0x8, 0xb, 0x0, 0x6, 0x9a, 0x70, 0x0, 0x0, + 0xb, 0x0, 0x1b, 0x1a, 0x46, 0x0, 0x0, 0xb, + 0x0, 0x91, 0x1a, 0xa, 0x70, 0x0, 0xb, 0x7, + 0x10, 0x1a, 0x0, 0xb6, 0x2, 0xb7, 0x20, 0x0, + 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63A5 "接" */ + 0x0, 0x4, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0xb, + 0x1, 0x55, 0x77, 0x58, 0x60, 0x5, 0x5c, 0x77, + 0x34, 0x0, 0xa1, 0x0, 0x0, 0xb, 0x0, 0xb, + 0x23, 0x70, 0x0, 0x0, 0xb, 0x5, 0x57, 0x68, + 0x55, 0xb1, 0x0, 0xc, 0x51, 0x1, 0xc0, 0x0, + 0x0, 0x16, 0xab, 0x0, 0x8, 0x50, 0x0, 0x50, + 0x18, 0xb, 0x35, 0x5c, 0x55, 0xc6, 0x62, 0x0, + 0xb, 0x0, 0x73, 0x2, 0xb0, 0x0, 0x0, 0xb, + 0x0, 0x57, 0x7c, 0x20, 0x0, 0x1, 0xb, 0x0, + 0x1, 0xa6, 0xb8, 0x0, 0x2, 0xc7, 0x3, 0x78, + 0x10, 0x7, 0xa0, 0x0, 0x10, 0x31, 0x0, 0x0, + 0x0, 0x10, + + /* U+63A7 "控" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x1, 0x82, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x10, 0x39, 0x0, 0x10, 0x5, 0x5d, 0x83, + 0x94, 0x44, 0x46, 0xb0, 0x0, 0xc, 0x5, 0x55, + 0x32, 0x4, 0x0, 0x0, 0xc, 0x0, 0x1c, 0x20, + 0x97, 0x0, 0x0, 0xd, 0x63, 0x91, 0x0, 0xb, + 0x50, 0x5, 0xad, 0x4, 0x0, 0x0, 0x26, 0x10, + 0x1a, 0x1c, 0x0, 0x55, 0xc6, 0x54, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xa2, 0x1, 0x60, 0x5, 0xb9, 0x6, 0x55, + 0x55, 0x55, 0x50, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63A8 "推" */ + 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x3d, 0x9, 0x20, 0x0, 0x0, 0xb, + 0x0, 0x76, 0x4, 0x70, 0x20, 0x5, 0x5c, 0x76, + 0xb5, 0x5a, 0x55, 0x80, 0x0, 0xb, 0x0, 0xf0, + 0xb, 0x0, 0x0, 0x0, 0xb, 0x7, 0xd0, 0xb, + 0x3, 0x20, 0x0, 0x1d, 0x45, 0xb5, 0x5c, 0x55, + 0x30, 0x19, 0x9b, 0x0, 0xb0, 0xb, 0x0, 0x0, + 0x5, 0xb, 0x0, 0xb5, 0x5c, 0x57, 0x80, 0x0, + 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, + 0xb5, 0x5c, 0x56, 0xc1, 0x3, 0xc6, 0x0, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63CF "描" */ + 0x0, 0x4, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, + 0xe, 0x10, 0x8, 0x60, 0xc2, 0x0, 0x0, 0xc, + 0x0, 0x8, 0x30, 0xc0, 0x20, 0x0, 0xc, 0x26, + 0x5a, 0x75, 0xd5, 0x81, 0x6, 0x5d, 0x54, 0x8, + 0x30, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x4, 0x10, + 0x40, 0x10, 0x0, 0xc, 0x53, 0xc5, 0x5a, 0x56, + 0xc0, 0x5, 0x9d, 0x10, 0xb0, 0xb, 0x1, 0xa0, + 0x9, 0x1c, 0x0, 0xc5, 0x5c, 0x56, 0xa0, 0x0, + 0xc, 0x0, 0xb0, 0xb, 0x1, 0xa0, 0x0, 0xc, + 0x0, 0xb0, 0xb, 0x1, 0xa0, 0x3, 0x2c, 0x0, + 0xc5, 0x5c, 0x56, 0xa0, 0x2, 0xc7, 0x0, 0xa0, + 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63D0 "提" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x85, 0x55, 0x5a, 0x0, 0x0, 0xb, + 0x0, 0x91, 0x0, 0xa, 0x0, 0x5, 0x5c, 0x84, + 0x96, 0x55, 0x5a, 0x0, 0x0, 0xb, 0x0, 0x91, + 0x0, 0xa, 0x0, 0x0, 0xb, 0x1, 0xa6, 0x55, + 0x5a, 0x0, 0x0, 0xd, 0x60, 0x30, 0x0, 0x0, + 0x50, 0x8, 0xab, 0x17, 0x55, 0x5c, 0x55, 0x62, + 0x6, 0xb, 0x2, 0xa0, 0xb, 0x0, 0x0, 0x0, + 0xb, 0x5, 0x70, 0xc, 0x56, 0x60, 0x0, 0xb, + 0x9, 0x63, 0xb, 0x0, 0x0, 0x1, 0x2b, 0x26, + 0x8, 0x9c, 0x0, 0x0, 0x2, 0xc6, 0x50, 0x0, + 0x4a, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63DB "換" */ + 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x9, 0x41, 0x20, 0x0, 0x0, 0x19, + 0x0, 0x38, 0x5b, 0xa0, 0x0, 0x5, 0x6b, 0x94, + 0x50, 0x26, 0x0, 0x0, 0x0, 0x19, 0x0, 0xa5, + 0x75, 0x5b, 0x20, 0x0, 0x19, 0x3, 0xb5, 0x65, + 0xa, 0x0, 0x0, 0x2d, 0x60, 0xb8, 0x1, 0xcb, + 0x0, 0x9, 0xc9, 0x0, 0xc2, 0x81, 0x6b, 0x0, + 0x5, 0x19, 0x0, 0x40, 0xc0, 0x4, 0x30, 0x0, + 0x19, 0x16, 0x56, 0xb7, 0x55, 0x81, 0x0, 0x19, + 0x0, 0x9, 0x25, 0x20, 0x0, 0x0, 0x19, 0x0, + 0x76, 0x0, 0xa6, 0x0, 0x4, 0xc7, 0x37, 0x20, + 0x0, 0x9, 0xd2, 0x0, 0x20, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+63EE "揮" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x93, 0x7, 0x55, 0x55, 0x56, 0x80, 0x0, 0x92, + 0xe, 0x10, 0x62, 0x7, 0x30, 0x0, 0x93, 0x13, + 0x0, 0xb1, 0x6, 0x0, 0x35, 0xb7, 0x45, 0x55, + 0xc5, 0x55, 0x20, 0x0, 0x92, 0x6, 0x55, 0xc5, + 0x5a, 0x20, 0x0, 0x93, 0x49, 0x20, 0xb0, 0xb, + 0x0, 0x1, 0xc6, 0x9, 0x65, 0xc5, 0x5c, 0x0, + 0x6c, 0xb2, 0x9, 0x65, 0xc5, 0x5c, 0x0, 0x10, + 0x92, 0x5, 0x0, 0xb0, 0x4, 0x0, 0x0, 0x92, + 0x26, 0x55, 0xc5, 0x58, 0x80, 0x0, 0x92, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x29, 0xe0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+63FA "揺" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, + 0xd, 0x0, 0x1, 0x48, 0xbd, 0xa0, 0x0, 0xb, + 0x2, 0x44, 0x31, 0x0, 0x80, 0x0, 0xb, 0x34, + 0x20, 0x91, 0x5, 0xa0, 0x5, 0x5c, 0x53, 0xc1, + 0x67, 0x8, 0x0, 0x0, 0xb, 0x0, 0x40, 0x1, + 0x22, 0x20, 0x0, 0xb, 0x53, 0x55, 0x5b, 0x56, + 0x50, 0x1, 0x7d, 0x10, 0x0, 0xb, 0x0, 0x20, + 0x1e, 0x5b, 0x6, 0x55, 0x5c, 0x55, 0x95, 0x1, + 0xb, 0x0, 0x40, 0xb, 0x0, 0x20, 0x0, 0xb, + 0x0, 0xc0, 0xb, 0x0, 0xc0, 0x0, 0x1b, 0x0, + 0xa0, 0xb, 0x0, 0xa0, 0x5, 0xe7, 0x1, 0xa5, + 0x57, 0x55, 0xb0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+643A "携" */ + 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x1d, 0x1b, 0x10, 0x0, 0x0, 0xb, + 0x0, 0x88, 0x5b, 0x67, 0x80, 0x5, 0x5c, 0x93, + 0xf0, 0xa, 0x3, 0x10, 0x0, 0xb, 0x6, 0xb5, + 0x5c, 0x55, 0x30, 0x0, 0xb, 0x22, 0xb5, 0x5c, + 0x59, 0x30, 0x0, 0x1d, 0x40, 0xb0, 0xa, 0x0, + 0x30, 0x19, 0xab, 0x0, 0xb5, 0x56, 0x55, 0x60, + 0x6, 0xb, 0x3, 0x68, 0x55, 0x96, 0x0, 0x0, + 0xb, 0x0, 0xd, 0x0, 0xb0, 0x40, 0x0, 0xb, + 0x0, 0x48, 0x1, 0x75, 0xd0, 0x0, 0xb, 0x1, + 0xb1, 0x0, 0x3, 0x80, 0x4, 0xc8, 0x38, 0x10, + 0x2, 0x9c, 0x20, 0x0, 0x10, 0x10, 0x0, 0x0, + 0x12, 0x0, + + /* U+64C1 "擁" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0xb0, + 0x25, 0x55, 0x96, 0x56, 0xa0, 0x0, 0xb0, 0x1, + 0xb0, 0x44, 0x60, 0x0, 0x25, 0xc6, 0x56, 0x22, + 0xa2, 0x73, 0x10, 0x0, 0xb0, 0x5, 0x4c, 0xc5, + 0x96, 0x70, 0x0, 0xb2, 0x68, 0xb6, 0xb0, 0xb0, + 0x0, 0x0, 0xc4, 0x5, 0x32, 0xc5, 0xc6, 0x60, + 0x3c, 0xd0, 0x37, 0x6a, 0xb0, 0xb0, 0x0, 0x13, + 0xb0, 0x56, 0xb1, 0xc5, 0xc6, 0x60, 0x0, 0xb0, + 0x2, 0x70, 0xb0, 0xb0, 0x0, 0x0, 0xb0, 0x9, + 0x0, 0xb0, 0xb0, 0x40, 0x18, 0xd0, 0x60, 0x0, + 0xd5, 0x65, 0x60, 0x0, 0x10, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+64C7 "擇" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x85, 0x55, 0x55, 0x90, 0x0, 0x1a, + 0x0, 0xa0, 0xb0, 0xa0, 0xa0, 0x0, 0xa, 0x20, + 0xc5, 0xc5, 0xc5, 0xb0, 0x5, 0x5c, 0x73, 0x60, + 0x1a, 0x0, 0x40, 0x0, 0xa, 0x0, 0x45, 0x5c, + 0x5a, 0x20, 0x0, 0xa, 0x50, 0x0, 0xb, 0x0, + 0x40, 0x0, 0x3d, 0x13, 0x69, 0x55, 0x86, 0x52, + 0x8, 0xaa, 0x0, 0x4, 0x80, 0x93, 0x0, 0x6, + 0x1a, 0x0, 0x76, 0x79, 0x67, 0x40, 0x0, 0xa, + 0x0, 0x0, 0xb, 0x0, 0x60, 0x0, 0xa, 0x7, + 0x55, 0x5c, 0x55, 0x52, 0x4, 0xa9, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x5, + 0x0, 0x0, + + /* U+64D4 "擔" */ + 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0xd, 0x0, 0xa, 0x60, 0x10, 0x0, 0x0, 0xb, + 0x0, 0x3a, 0x55, 0xd1, 0x0, 0x0, 0xb, 0x20, + 0xb5, 0x57, 0x65, 0xa0, 0x5, 0x5c, 0x65, 0xc1, + 0xa2, 0x37, 0x0, 0x0, 0xb, 0x0, 0xb5, 0x18, + 0x36, 0x30, 0x0, 0xb, 0x62, 0xb5, 0x56, 0x55, + 0x81, 0x0, 0x3d, 0x10, 0xb2, 0x55, 0x59, 0x0, + 0x9, 0x9b, 0x0, 0xa0, 0x0, 0x5, 0x0, 0x5, + 0xb, 0x3, 0x72, 0x65, 0x55, 0x10, 0x0, 0xb, + 0x8, 0x28, 0x65, 0x5b, 0x20, 0x1, 0xb, 0x7, + 0x8, 0x30, 0xa, 0x10, 0x2, 0xd7, 0x50, 0x8, + 0x75, 0x5a, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+64DA "據" */ + 0x0, 0x1, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x0, 0xb1, 0x4, 0x0, 0x0, 0x19, + 0x1, 0x0, 0xb5, 0x55, 0x20, 0x0, 0x19, 0x29, + 0x65, 0xb6, 0x55, 0xd1, 0x5, 0x6b, 0x6a, 0x10, + 0xb5, 0x83, 0x20, 0x0, 0x19, 0x9, 0x44, 0xb1, + 0x7, 0x0, 0x0, 0x1a, 0x49, 0x10, 0x37, 0x76, + 0x40, 0x0, 0x4c, 0xa, 0x45, 0xa8, 0x57, 0x60, + 0x9, 0xa9, 0xa, 0x5, 0x84, 0x1b, 0x20, 0x4, + 0x19, 0xa, 0x23, 0x8a, 0x90, 0x0, 0x0, 0x19, + 0x26, 0x56, 0x4a, 0x97, 0x0, 0x0, 0x19, 0x61, + 0x27, 0x60, 0xb4, 0xc2, 0x5, 0xc7, 0x42, 0x30, + 0x39, 0x90, 0x10, 0x0, 0x20, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+652F "支" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0x6, 0x10, 0x6, 0x55, 0x55, + 0xd5, 0x55, 0x57, 0x40, 0x0, 0x0, 0x0, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x25, 0x55, 0xd5, 0x59, + 0x10, 0x0, 0x0, 0x0, 0x40, 0x0, 0x4a, 0x0, + 0x0, 0x0, 0x0, 0x51, 0x0, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x7, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xdb, 0x20, 0x0, 0x0, 0x0, 0x1, 0x97, + 0x3, 0xca, 0x63, 0x10, 0x4, 0x67, 0x10, 0x0, + 0x4, 0xae, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6539 "改" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x5, 0x55, 0x5c, + 0x15, 0x70, 0x0, 0x0, 0x0, 0x0, 0xb0, 0xa1, + 0x0, 0x41, 0x0, 0x0, 0xb, 0xb, 0x55, 0xb6, + 0x30, 0x20, 0x0, 0xb6, 0x70, 0xa, 0x0, 0xb, + 0x65, 0x58, 0x55, 0x10, 0xb0, 0x0, 0xb1, 0x0, + 0x0, 0x25, 0xb, 0x0, 0xb, 0x10, 0x0, 0x0, + 0x95, 0x60, 0x0, 0xb1, 0x0, 0x2, 0x6, 0xc0, + 0x0, 0xb, 0x13, 0x75, 0x0, 0x8c, 0x20, 0x0, + 0xcc, 0x60, 0x0, 0x85, 0x1c, 0x40, 0x4, 0x10, + 0x4, 0x71, 0x0, 0x2d, 0x80, 0x0, 0x1, 0x10, + 0x0, 0x0, 0x0, + + /* U+653E "放" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x1, + 0xb0, 0x0, 0xd0, 0x0, 0x0, 0x25, 0x65, 0x55, + 0xa4, 0xb5, 0x59, 0x80, 0x0, 0x92, 0x0, 0x8, + 0x20, 0x57, 0x0, 0x0, 0x92, 0x3, 0xa, 0x20, + 0x75, 0x0, 0x0, 0xa6, 0x5c, 0x52, 0x60, 0xb1, + 0x0, 0x0, 0xb0, 0xb, 0x0, 0x80, 0xc0, 0x0, + 0x0, 0xb0, 0xb, 0x0, 0x68, 0x60, 0x0, 0x0, + 0xa0, 0xb, 0x0, 0x1f, 0x0, 0x0, 0x4, 0x60, + 0xc, 0x0, 0x98, 0x90, 0x0, 0x9, 0x6, 0xa8, + 0x8, 0x30, 0x8a, 0x10, 0x43, 0x0, 0x83, 0x61, + 0x0, 0x7, 0x91, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+653F "政" */ + 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x6, 0x55, + 0x65, 0xc3, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0xd5, 0x56, 0xb2, 0x0, 0x0, 0xb0, 0x4, + 0x70, 0xd, 0x0, 0x1, 0xb0, 0xb1, 0x28, 0x50, + 0xb, 0x0, 0x1, 0xa0, 0xc5, 0x55, 0x60, 0x38, + 0x0, 0x1, 0xa0, 0xb0, 0x20, 0x52, 0x75, 0x0, + 0x1, 0xa0, 0xb0, 0x0, 0x8, 0xc0, 0x0, 0x1, + 0xa0, 0xb0, 0x31, 0xa, 0x90, 0x0, 0x2, 0xc8, + 0xb6, 0x10, 0x4b, 0xc1, 0x0, 0x1d, 0x72, 0x0, + 0x6, 0x70, 0x3d, 0x40, 0x0, 0x0, 0x2, 0x62, + 0x0, 0x3, 0xc4, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+6545 "故" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0x30, 0xb0, 0x0, 0x40, 0x5, 0x55, 0xc5, 0x73, + 0xd5, 0x5d, 0x61, 0x0, 0x0, 0xb0, 0x6, 0x80, + 0xc, 0x0, 0x0, 0x0, 0xb0, 0x6, 0x50, 0x1b, + 0x0, 0x0, 0xc5, 0x79, 0x80, 0x34, 0x47, 0x0, + 0x0, 0xb0, 0x6, 0x50, 0x9, 0x92, 0x0, 0x0, + 0xb0, 0x6, 0x50, 0x9, 0xb0, 0x0, 0x0, 0xb0, + 0x6, 0x50, 0xb, 0xb0, 0x0, 0x0, 0xd5, 0x59, + 0x51, 0x92, 0x5b, 0x20, 0x0, 0x50, 0x1, 0x55, + 0x0, 0x5, 0xd2, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+6548 "效" */ + 0x0, 0x1, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x5, 0x60, 0x0, 0x1e, 0x20, 0x0, 0x0, 0x0, + 0xd1, 0x21, 0x48, 0x0, 0x0, 0x3, 0x65, 0x65, + 0x75, 0x92, 0x0, 0x60, 0x0, 0x2b, 0x7, 0x40, + 0xb5, 0x5d, 0x51, 0x0, 0x93, 0x0, 0xd4, 0x90, + 0xb, 0x0, 0x3, 0x60, 0x6, 0x36, 0x50, 0x29, + 0x0, 0x5, 0x14, 0x1c, 0x12, 0x34, 0x64, 0x0, + 0x0, 0x3, 0xc4, 0x0, 0x9, 0xb0, 0x0, 0x0, + 0x2, 0xba, 0x0, 0xa, 0x70, 0x0, 0x0, 0xa, + 0x8, 0x70, 0x3a, 0xa0, 0x0, 0x0, 0x81, 0x1, + 0x54, 0x60, 0x6b, 0x10, 0x6, 0x10, 0x0, 0x53, + 0x0, 0x7, 0xb1, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+6557 "敗" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x6, + 0x55, 0x55, 0x90, 0x7a, 0x0, 0x0, 0xb, 0x0, + 0x1, 0xb0, 0xa2, 0x0, 0x0, 0xb, 0x0, 0x1, + 0xa0, 0xc5, 0x57, 0xb2, 0xb, 0x55, 0x55, 0xa3, + 0x80, 0xc, 0x0, 0xb, 0x0, 0x1, 0xa7, 0x40, + 0xc, 0x0, 0xb, 0x55, 0x55, 0xa6, 0x50, 0x29, + 0x0, 0xb, 0x0, 0x1, 0xb0, 0x42, 0x75, 0x0, + 0xb, 0x55, 0x55, 0xa0, 0x7, 0xb0, 0x0, 0x7, + 0x11, 0x10, 0x40, 0x9, 0x80, 0x0, 0x0, 0xa6, + 0x1a, 0x30, 0x3a, 0xb1, 0x0, 0x5, 0x60, 0x2, + 0x72, 0x80, 0x3d, 0x20, 0x24, 0x0, 0x0, 0x44, + 0x0, 0x4, 0xd3, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+6559 "教" */ + 0x0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xb3, 0x2b, 0xc, 0x10, 0x0, 0x1, 0x55, 0xc5, + 0xd2, 0xa, 0x0, 0x50, 0x5, 0x55, 0xc8, 0xaa, + 0x67, 0x4a, 0x62, 0x0, 0x0, 0x38, 0x0, 0x73, + 0xa, 0x10, 0x1, 0x57, 0xb5, 0xd3, 0x44, 0xb, + 0x0, 0x0, 0x46, 0x16, 0x22, 0x6, 0xa, 0x0, + 0x4, 0x20, 0x85, 0x2, 0x6, 0x56, 0x0, 0x1, + 0x36, 0xc8, 0x52, 0x3, 0xd0, 0x0, 0x8, 0x72, + 0x83, 0x0, 0x7, 0xc2, 0x0, 0x0, 0x0, 0x83, + 0x0, 0x75, 0x1c, 0x20, 0x0, 0x27, 0xd1, 0x26, + 0x20, 0x3, 0xd4, 0x0, 0x0, 0x30, 0x10, 0x0, + 0x0, 0x0, + + /* U+6562 "敢" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x1, + 0x55, 0x58, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x48, 0x0, 0x83, 0x0, 0x0, 0x15, 0x55, 0xa6, + 0x86, 0xb5, 0x56, 0xa0, 0x0, 0xb0, 0xb, 0x0, + 0xa0, 0x1a, 0x0, 0x0, 0xb0, 0xb, 0x5, 0x80, + 0x38, 0x0, 0x0, 0xc5, 0x5c, 0x7, 0x50, 0x65, + 0x0, 0x0, 0xb0, 0xb, 0x13, 0x34, 0x92, 0x0, + 0x0, 0xc5, 0x5c, 0x0, 0x8, 0xb0, 0x0, 0x0, + 0xb0, 0xb, 0x33, 0x9, 0x70, 0x0, 0x16, 0xe9, + 0x7d, 0x10, 0x1b, 0xb0, 0x0, 0x8, 0x20, 0xb, + 0x0, 0x91, 0x4b, 0x10, 0x0, 0x0, 0xb, 0x27, + 0x10, 0x5, 0xc2, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0x0, + + /* U+6570 "数" */ + 0x0, 0x0, 0x30, 0x0, 0x11, 0x0, 0x0, 0x1, + 0x40, 0xc1, 0x62, 0x5b, 0x0, 0x0, 0x0, 0xb3, + 0xb1, 0x90, 0x93, 0x0, 0x0, 0x0, 0x31, 0xb3, + 0x41, 0xb0, 0x0, 0x60, 0x6, 0x5b, 0xe5, 0x56, + 0xb5, 0x5d, 0x51, 0x0, 0x48, 0xb9, 0x77, 0x50, + 0x1a, 0x0, 0x4, 0x60, 0xa0, 0x54, 0x50, 0x38, + 0x0, 0x11, 0x4, 0x90, 0x10, 0x52, 0x65, 0x0, + 0x6, 0x5b, 0x75, 0xc0, 0x17, 0xb1, 0x0, 0x0, + 0x29, 0x7, 0x50, 0xa, 0xb0, 0x0, 0x0, 0x26, + 0x8d, 0x20, 0xb, 0xa0, 0x0, 0x0, 0x6, 0x84, + 0xc2, 0x93, 0x8a, 0x10, 0x4, 0x62, 0x0, 0x36, + 0x10, 0x7, 0xc1, 0x0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, + + /* U+6574 "整" */ + 0x0, 0x0, 0x30, 0x0, 0x22, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x30, 0x86, 0x0, 0x0, 0x5, 0x65, + 0xc5, 0x63, 0xc5, 0x57, 0xa0, 0x0, 0x95, 0xc5, + 0xa3, 0xa0, 0x29, 0x0, 0x0, 0xa0, 0xb0, 0xa7, + 0x24, 0x84, 0x0, 0x0, 0xb7, 0xe5, 0x90, 0x9, + 0xb0, 0x0, 0x0, 0x2a, 0xc8, 0x60, 0x2a, 0xb2, + 0x0, 0x3, 0x70, 0xc0, 0x65, 0x60, 0x2c, 0xa1, + 0x12, 0x46, 0x65, 0x86, 0x55, 0x96, 0x10, 0x0, + 0x0, 0x20, 0x57, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xc0, 0x5a, 0x56, 0x80, 0x0, 0x0, 0x0, 0xb0, + 0x57, 0x0, 0x0, 0x0, 0x4, 0x55, 0xc5, 0x8a, + 0x55, 0x5b, 0x90, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6587 "文" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x48, 0x0, 0x0, 0x10, 0x5, 0x55, 0x65, + 0x55, 0x57, 0x5a, 0xa0, 0x0, 0x0, 0x50, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x66, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x2, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0x8a, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x8a, 0x70, 0x0, 0x0, 0x0, 0x1, 0x84, + 0x0, 0x7d, 0x84, 0x10, 0x3, 0x55, 0x0, 0x0, + 0x1, 0x8e, 0x80, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6599 "料" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0xc, 0x10, 0x0, 0x0, 0xd2, 0x0, 0x5, 0xb, + 0x9, 0x13, 0x20, 0xc0, 0x0, 0x3, 0x9b, 0x9, + 0x0, 0xd2, 0xc0, 0x0, 0x0, 0x6b, 0x40, 0x0, + 0x40, 0xc0, 0x0, 0x5, 0x5d, 0x5a, 0x31, 0x0, + 0xc0, 0x0, 0x0, 0x2f, 0x10, 0x4, 0x90, 0xc0, + 0x0, 0x0, 0x9e, 0x79, 0x0, 0xa0, 0xc0, 0x10, + 0x1, 0x8b, 0x9, 0x10, 0x0, 0xc6, 0xa0, 0x8, + 0x1b, 0x3, 0x55, 0x55, 0xd0, 0x0, 0x32, 0xb, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+65AD "断" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x20, 0xb2, 0x0, 0x12, 0x6b, 0x70, 0xb, 0x12, + 0xb0, 0x92, 0xc3, 0x10, 0x0, 0xb, 0xb, 0xc1, + 0x90, 0xb0, 0x0, 0x0, 0xb, 0x4, 0xc4, 0x0, + 0xb0, 0x0, 0x0, 0xb, 0x45, 0xe5, 0x93, 0xc5, + 0x57, 0xb1, 0xb, 0x4, 0xf4, 0x0, 0xb0, 0x1a, + 0x0, 0xb, 0x8, 0xc3, 0x90, 0xa0, 0x1a, 0x0, + 0xb, 0x17, 0xb0, 0xa3, 0x90, 0x1a, 0x0, 0xb, + 0x50, 0xb0, 0x4, 0x70, 0x1a, 0x0, 0xb, 0x0, + 0xa1, 0x8, 0x20, 0x1a, 0x0, 0xc, 0x55, 0x59, + 0x66, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x1, 0x60, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+65B0 "新" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x80, 0x0, 0x0, 0x39, 0xa0, 0x4, 0x55, + 0xb5, 0xb2, 0xb5, 0x41, 0x0, 0x0, 0x61, 0xa, + 0x20, 0xb0, 0x0, 0x0, 0x0, 0x2a, 0x8, 0x0, + 0xb0, 0x0, 0x0, 0x6, 0x57, 0x85, 0x87, 0xb5, + 0x56, 0xc3, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x1a, + 0x0, 0x3, 0x55, 0xc5, 0xa3, 0xb0, 0x1a, 0x0, + 0x0, 0x10, 0xb0, 0x0, 0xb0, 0x1a, 0x0, 0x0, + 0xd2, 0xb5, 0x41, 0xa0, 0x1a, 0x0, 0x4, 0x60, + 0xb0, 0xc6, 0x40, 0x1a, 0x0, 0x7, 0x22, 0xb0, + 0x28, 0x0, 0x1a, 0x0, 0x10, 0xa, 0x70, 0x60, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65B7 "斷" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x19, 0x2, 0x70, 0x32, 0x6b, 0x60, 0xb, 0x35, + 0x57, 0x73, 0xc2, 0x0, 0x0, 0xb, 0x4a, 0x16, + 0xa0, 0xb0, 0x0, 0x0, 0xb, 0x25, 0x67, 0x81, + 0xb0, 0x0, 0x10, 0xb, 0x55, 0x75, 0x54, 0xb5, + 0x87, 0x80, 0xb, 0x58, 0x56, 0x90, 0xb0, 0x92, + 0x0, 0xb, 0xa, 0x16, 0x40, 0xb0, 0x92, 0x0, + 0xb, 0x68, 0x79, 0xb1, 0xb0, 0x92, 0x0, 0xb, + 0x18, 0x4, 0x60, 0xa0, 0x92, 0x0, 0xb, 0x48, + 0x8a, 0x92, 0x80, 0x92, 0x0, 0xb, 0x0, 0x36, + 0x47, 0x20, 0x92, 0x0, 0x8, 0x55, 0x55, 0x46, + 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x10, 0x0, + + /* U+65B9 "方" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x29, 0x0, 0x0, 0x20, 0x16, 0x55, 0x55, + 0x85, 0x55, 0x57, 0xb1, 0x0, 0x0, 0x2, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, + 0x20, 0x0, 0x0, 0x0, 0x6, 0x95, 0x55, 0xe2, + 0x0, 0x0, 0x0, 0xa, 0x10, 0x1, 0xc0, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x3, 0xa0, 0x0, 0x0, + 0x0, 0x73, 0x0, 0x5, 0x80, 0x0, 0x0, 0x2, + 0x80, 0x0, 0x8, 0x50, 0x0, 0x0, 0x28, 0x0, + 0x22, 0xc, 0x20, 0x0, 0x3, 0x50, 0x0, 0x7, + 0xfa, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+65BC "於" */ + 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x3, + 0x52, 0x10, 0xb8, 0x0, 0x0, 0x16, 0x96, 0x57, + 0x61, 0xb2, 0x60, 0x0, 0x0, 0x92, 0x0, 0x6, + 0x40, 0xa1, 0x0, 0x0, 0x97, 0x59, 0x19, 0x0, + 0x2d, 0x20, 0x0, 0xa2, 0xb, 0x61, 0x63, 0x6, + 0xa0, 0x0, 0xb0, 0xb, 0x10, 0x1b, 0x80, 0x0, + 0x0, 0xb0, 0xb, 0x0, 0x0, 0x30, 0x0, 0x0, + 0xa0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x5, 0x40, + 0x38, 0x5, 0x95, 0x0, 0x0, 0x8, 0x17, 0xb4, + 0x0, 0x9, 0xe1, 0x0, 0x32, 0x3, 0x60, 0x0, + 0x0, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65BD "施" */ + 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x9, + 0x20, 0x7, 0x92, 0x24, 0x90, 0x15, 0x75, 0x5b, + 0x5b, 0x33, 0x33, 0x30, 0x0, 0xb0, 0x0, 0x71, + 0xd, 0x0, 0x0, 0x0, 0xb0, 0x32, 0x2a, 0xb, + 0x5, 0x20, 0x0, 0xb5, 0xc3, 0xb, 0x1d, 0x6c, + 0x10, 0x0, 0xb0, 0xa2, 0x6d, 0x4b, 0xb, 0x0, + 0x0, 0xb0, 0xb1, 0xb, 0xb, 0xb, 0x0, 0x0, + 0x90, 0xb0, 0xb, 0xb, 0x6c, 0x0, 0x4, 0x50, + 0xb0, 0xb, 0xc, 0x12, 0x50, 0x8, 0x32, 0xc0, + 0xb, 0x3, 0x0, 0x90, 0x23, 0xb, 0x50, 0xc, + 0xaa, 0xaa, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65C1 "旁" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x94, 0x0, 0x3, 0x0, 0x0, 0x65, + 0x65, 0x66, 0x65, 0x78, 0x0, 0x0, 0x0, 0x67, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x20, 0xa, 0x0, + 0x70, 0x2, 0x0, 0x3, 0x95, 0x55, 0x85, 0x55, + 0x5c, 0x60, 0x7, 0x20, 0x0, 0x59, 0x0, 0x14, + 0x10, 0x4, 0x65, 0x57, 0x78, 0x55, 0x57, 0x90, + 0x0, 0x0, 0xb, 0x30, 0x0, 0x30, 0x0, 0x0, + 0x0, 0xd, 0x55, 0x56, 0xd0, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x4, 0x90, 0x0, 0x0, 0x2, 0xa0, + 0x2, 0x8, 0x50, 0x0, 0x1, 0x66, 0x0, 0x2, + 0xcd, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+65C5 "旅" */ + 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x7, 0xa0, 0x0, 0x0, 0x0, 0x7, + 0x60, 0xb, 0x20, 0x1, 0x0, 0x15, 0x55, 0x5a, + 0x5b, 0x55, 0x59, 0x60, 0x0, 0xb0, 0x0, 0x62, + 0x0, 0x12, 0x0, 0x0, 0xb0, 0x4, 0x41, 0x27, + 0xa6, 0x0, 0x0, 0xb5, 0x5c, 0xc, 0x52, 0x0, + 0x0, 0x0, 0xb0, 0xa, 0xb, 0x4, 0xb, 0x30, + 0x0, 0xb0, 0x1a, 0xb, 0x8, 0x61, 0x0, 0x2, + 0x90, 0x29, 0xb, 0x8, 0x10, 0x0, 0x7, 0x30, + 0x47, 0xb, 0x2, 0xa0, 0x0, 0x8, 0x16, 0xb3, + 0xb, 0x54, 0x7a, 0x10, 0x41, 0x4, 0x50, 0xe, + 0x40, 0x7, 0xc1, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+65CF "族" */ + 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x48, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x56, 0x0, 0x5, 0x0, 0x25, 0x85, 0x67, + 0x98, 0x55, 0x57, 0x20, 0x0, 0xb0, 0x1, 0x6d, + 0x10, 0x1, 0x0, 0x0, 0xb5, 0x95, 0x58, 0x85, + 0x68, 0x0, 0x0, 0xb0, 0xb0, 0x70, 0xa1, 0x0, + 0x0, 0x0, 0xb0, 0xb1, 0x0, 0xa0, 0x2, 0x10, + 0x0, 0xb0, 0xb5, 0x55, 0xc7, 0x57, 0x50, 0x1, + 0x90, 0xb0, 0x0, 0xa6, 0x0, 0x0, 0x6, 0x30, + 0xb0, 0x7, 0x42, 0x70, 0x0, 0x8, 0x29, 0x90, + 0x48, 0x0, 0x96, 0x0, 0x41, 0x4, 0x26, 0x50, + 0x0, 0xb, 0x90, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+65E2 "既" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x55, + 0x59, 0x25, 0x57, 0x58, 0x70, 0xa1, 0x0, 0xb1, + 0x30, 0xc0, 0x0, 0xa, 0x10, 0xb, 0x2b, 0xc, + 0x0, 0x0, 0xa6, 0x55, 0xb3, 0x70, 0xc0, 0x0, + 0xa, 0x10, 0xb, 0x46, 0xb, 0x0, 0x10, 0xa6, + 0x55, 0xb6, 0x77, 0xb5, 0x77, 0xa, 0x10, 0x4, + 0x0, 0x6c, 0x20, 0x0, 0xa1, 0x14, 0x0, 0xa, + 0xa2, 0x0, 0xa, 0x10, 0x67, 0x2, 0xa9, 0x20, + 0x0, 0xa1, 0x65, 0xd1, 0x91, 0x92, 0x5, 0xb, + 0xc3, 0x3, 0x64, 0x9, 0x20, 0x80, 0x31, 0x0, + 0x53, 0x0, 0x6b, 0xad, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+65E5 "日" */ + 0x95, 0x55, 0x55, 0x5a, 0x2c, 0x0, 0x0, 0x0, + 0xc0, 0xc0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, + 0x0, 0xc0, 0xc0, 0x0, 0x0, 0xc, 0xd, 0x55, + 0x55, 0x55, 0xd0, 0xc0, 0x0, 0x0, 0xc, 0xc, + 0x0, 0x0, 0x0, 0xc0, 0xc0, 0x0, 0x0, 0xc, + 0xc, 0x0, 0x0, 0x0, 0xc0, 0xd5, 0x55, 0x55, + 0x5d, 0xa, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+65E6 "旦" */ + 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xb6, 0x55, 0x55, 0xd3, 0x0, 0x0, 0xb, 0x10, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0xa, 0x65, 0x55, 0x5d, 0x0, + 0x0, 0x0, 0xa1, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xa, 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0xb6, + 0x55, 0x55, 0xd0, 0x0, 0x0, 0xb, 0x10, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x11, + 0x75, 0x55, 0x55, 0x55, 0x55, 0x53, + + /* U+65E9 "早" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0x55, 0x55, 0xc4, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xb, 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0xc, 0x55, 0x55, 0x5c, 0x10, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb1, 0x0, 0x0, + 0xc, 0x55, 0x75, 0x5c, 0x10, 0x0, 0x0, 0x60, + 0xb, 0x10, 0x40, 0x0, 0x0, 0x0, 0x0, 0xb1, + 0x0, 0x8, 0x1, 0x75, 0x55, 0x5c, 0x65, 0x55, + 0x52, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x0, + + /* U+65F6 "时" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x85, 0x5a, 0x20, + 0x0, 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, + 0xc0, 0x50, 0xc0, 0xc, 0x46, 0x55, 0x5d, 0x57, + 0x1c, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0xc5, + 0x5d, 0x7, 0x40, 0xc, 0x0, 0xc, 0x0, 0xc0, + 0xe, 0x10, 0xc0, 0x0, 0xc0, 0xc, 0x0, 0x60, + 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xc0, + 0x0, 0xc5, 0x5d, 0x0, 0x0, 0xc, 0x0, 0x9, + 0x0, 0x30, 0x0, 0x11, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, + + /* U+6607 "昇" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x55, 0x55, 0x55, 0x8b, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x47, 0x0, 0x0, 0xd, 0x55, + 0x55, 0x55, 0x87, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x47, 0x0, 0x0, 0xc, 0x55, 0x75, 0x55, + 0x75, 0x0, 0x0, 0x2, 0x6a, 0xc2, 0xc, 0x10, + 0x0, 0x0, 0x33, 0x57, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x47, 0x0, 0xc, 0x3, 0x70, 0x5, + 0x55, 0x99, 0x55, 0x5d, 0x55, 0x50, 0x0, 0x0, + 0xa2, 0x0, 0xc, 0x0, 0x0, 0x0, 0x3, 0x80, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+660E "明" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x95, 0x55, 0xc2, 0xc5, 0x5d, 0xa, 0x10, 0xb, + 0xb, 0x0, 0xb0, 0xa1, 0x0, 0xb0, 0xb0, 0xb, + 0xa, 0x65, 0x5c, 0xc, 0x55, 0xb0, 0xa1, 0x0, + 0xb0, 0xb0, 0xb, 0xb, 0x0, 0xb, 0xb, 0x0, + 0xb0, 0xb3, 0x33, 0xc0, 0xc5, 0x5c, 0xc, 0x11, + 0x1b, 0xb, 0x0, 0x51, 0xb0, 0x0, 0xb0, 0x0, + 0x0, 0x84, 0x0, 0xb, 0x0, 0x0, 0x47, 0x0, + 0x10, 0xc0, 0x0, 0x44, 0x0, 0x4, 0xcc, 0x0, + 0x11, 0x0, 0x0, 0x1, 0x0, + + /* U+6613 "易" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1b, + 0x55, 0x55, 0x5d, 0x0, 0x0, 0x1b, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x1c, 0x55, 0x55, 0x5c, 0x0, + 0x0, 0x1b, 0x0, 0x0, 0xc, 0x0, 0x0, 0x1c, + 0x85, 0x55, 0x5b, 0x0, 0x0, 0x7, 0xa0, 0x0, + 0x0, 0x11, 0x0, 0x2b, 0x5b, 0x75, 0xc5, 0xa8, + 0x2, 0x90, 0x3b, 0x6, 0x70, 0x93, 0x4, 0x1, + 0xb1, 0xc, 0x10, 0xc0, 0x0, 0x48, 0x10, 0x95, + 0x0, 0xc0, 0x4, 0x20, 0x19, 0x51, 0x4, 0x90, + 0x0, 0x15, 0x61, 0x1, 0xae, 0x20, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x0, + + /* U+6614 "昔" */ + 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0x74, 0x0, 0xc0, 0x36, 0x0, 0x2, 0x65, 0xa8, + 0x55, 0xd5, 0x55, 0x0, 0x0, 0x0, 0x74, 0x0, + 0xc0, 0x0, 0x0, 0x15, 0x55, 0xa8, 0x55, 0xd5, + 0x5b, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x55, 0x55, 0x5a, 0x70, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, + 0xc, 0x55, 0x55, 0x5a, 0x40, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x8, 0x40, 0x0, 0x0, 0xc, 0x55, 0x55, + 0x5a, 0x40, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+661F "星" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x55, 0x55, 0x55, 0x8a, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0xd, 0x55, + 0x55, 0x55, 0x87, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x57, 0x0, 0x0, 0xb, 0x55, 0x65, 0x55, + 0x86, 0x0, 0x0, 0x9, 0x20, 0x2b, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x55, 0x6b, 0x55, 0x6d, 0x20, + 0x0, 0x82, 0x0, 0x29, 0x0, 0x0, 0x0, 0x2, + 0x50, 0x0, 0x29, 0x0, 0x82, 0x0, 0x3, 0x5, + 0x55, 0x6b, 0x55, 0x53, 0x0, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x0, 0x40, 0x6, 0x55, 0x55, 0x57, + 0x55, 0x56, 0x92, + + /* U+6620 "映" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb2, 0x0, 0x0, 0x75, 0x59, 0x0, + 0xb, 0x0, 0x0, 0xb, 0x0, 0xb0, 0xb5, 0xc5, + 0x5c, 0x0, 0xb0, 0xb, 0xa, 0xb, 0x0, 0xa0, + 0xb, 0x0, 0xb0, 0xa0, 0xb0, 0xa, 0x0, 0xb5, + 0x5b, 0xa, 0xb, 0x0, 0xa0, 0xb, 0x0, 0xb5, + 0xa5, 0xc5, 0x5b, 0xb1, 0xb0, 0xb, 0x0, 0x28, + 0x50, 0x0, 0xb, 0x0, 0xb0, 0x8, 0x46, 0x10, + 0x0, 0xb5, 0x5b, 0x1, 0xa0, 0x1a, 0x0, 0x9, + 0x0, 0x1, 0xa1, 0x0, 0x6a, 0x0, 0x0, 0x5, + 0x70, 0x0, 0x0, 0x8d, 0x10, 0x2, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+6625 "春" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf3, 0x0, 0x1, 0x0, 0x2, 0x55, + 0x56, 0xe5, 0x55, 0x5a, 0x30, 0x0, 0x0, 0x5, + 0x70, 0x0, 0x60, 0x0, 0x0, 0x55, 0x5d, 0x65, + 0x55, 0x51, 0x0, 0x5, 0x55, 0x6c, 0x55, 0x55, + 0x57, 0xc1, 0x0, 0x1, 0xb1, 0x0, 0x7, 0x0, + 0x0, 0x0, 0x1a, 0x61, 0x11, 0x18, 0x90, 0x0, + 0x4, 0x70, 0xd3, 0x33, 0x3d, 0x3c, 0xa3, 0x11, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x40, 0x0, 0x0, + 0xd5, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, + 0x0, 0x0, + + /* U+6628 "昨" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x70, 0x0, 0x0, 0x85, 0x5b, 0x20, + 0xd0, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x4a, 0x75, + 0x57, 0xb0, 0xb0, 0xb, 0x9, 0xc, 0x0, 0x0, + 0xb, 0x0, 0xb3, 0x40, 0xc0, 0x0, 0x0, 0xb5, + 0x5c, 0x20, 0xd, 0x55, 0xa2, 0xb, 0x0, 0xb0, + 0x0, 0xc0, 0x0, 0x0, 0xb0, 0xb, 0x0, 0xc, + 0x0, 0x33, 0xb, 0x0, 0xb0, 0x0, 0xd5, 0x56, + 0x50, 0xb5, 0x5d, 0x0, 0xc, 0x0, 0x0, 0xa, + 0x0, 0x40, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x0, + + /* U+662F "是" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xd5, 0x55, 0x5c, 0x50, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0xd5, + 0x55, 0x5c, 0x20, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0xa, 0x20, 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5b, + 0x20, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x7, + 0x30, 0x4, 0x65, 0x75, 0x5d, 0x55, 0x55, 0x40, + 0x0, 0x4, 0xd0, 0xc, 0x0, 0x22, 0x0, 0x0, + 0x8, 0x60, 0xd, 0x55, 0x65, 0x0, 0x0, 0xb, + 0x45, 0xc, 0x0, 0x0, 0x0, 0x0, 0x92, 0x5, + 0xbd, 0x20, 0x0, 0x0, 0x5, 0x30, 0x0, 0x17, + 0xbd, 0xef, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+663C "昼" */ + 0x0, 0x8, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x65, 0xb0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x42, 0x10, 0x0, 0x0, 0x39, 0x0, 0x0, + 0x9, 0x20, 0x0, 0x0, 0x98, 0x75, 0x55, 0x5d, + 0xa7, 0x0, 0x2, 0x67, 0x30, 0x0, 0xa, 0x6, + 0xb0, 0x16, 0x7, 0x75, 0x55, 0x5b, 0x0, 0x0, + 0x10, 0x7, 0x30, 0x0, 0xa, 0x0, 0x0, 0x0, + 0x7, 0x75, 0x55, 0x5b, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x8, 0x0, 0x3, 0x55, 0x55, + 0x55, 0x55, 0x56, 0x30, + + /* U+6642 "時" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, + 0x20, 0x0, 0xb2, 0x0, 0x0, 0xc5, 0x5d, 0x10, + 0xb, 0x0, 0x30, 0xb, 0x0, 0xb0, 0x55, 0xc5, + 0x57, 0x0, 0xb0, 0xb, 0x0, 0xb, 0x0, 0x0, + 0xb, 0x0, 0xb5, 0x55, 0xd5, 0x57, 0xa0, 0xb5, + 0x5b, 0x0, 0x0, 0x9, 0x10, 0xb, 0x0, 0xb4, + 0x55, 0x55, 0xc5, 0xa0, 0xb0, 0xb, 0x14, 0x10, + 0xb, 0x0, 0xb, 0x0, 0xb0, 0xc, 0x10, 0xb0, + 0x0, 0xc5, 0x5c, 0x0, 0x41, 0xb, 0x0, 0x8, + 0x0, 0x30, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x10, 0x0, + + /* U+6669 "晩" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0xb5, 0x5c, 0x4, + 0xb5, 0x6b, 0x10, 0xb, 0x1, 0x90, 0xa0, 0x8, + 0x40, 0x0, 0xb0, 0x19, 0x7a, 0x56, 0x85, 0x92, + 0xb, 0x1, 0xb2, 0xb0, 0x91, 0xb, 0x0, 0xc5, + 0x69, 0xb, 0x9, 0x10, 0xb0, 0xb, 0x1, 0x90, + 0xd5, 0xb6, 0x5c, 0x0, 0xb0, 0x19, 0x4, 0x17, + 0xc0, 0x10, 0xb, 0x1, 0xa0, 0x4, 0x4c, 0x0, + 0x0, 0xd5, 0x6a, 0x0, 0x90, 0xc0, 0x4, 0x6, + 0x0, 0x0, 0x65, 0xc, 0x0, 0x60, 0x0, 0x0, + 0x64, 0x0, 0xba, 0x9d, 0x10, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+666E "普" */ + 0x0, 0x0, 0x40, 0x0, 0x22, 0x0, 0x0, 0x0, + 0x4, 0xb0, 0x8, 0x30, 0x0, 0x2, 0x55, 0x5d, + 0x55, 0x95, 0x7c, 0x10, 0x1, 0x0, 0xc0, 0x2a, + 0x5, 0x0, 0x0, 0xa, 0xc, 0x2, 0xa1, 0xb0, + 0x0, 0x0, 0x75, 0xc0, 0x2a, 0x71, 0x0, 0x35, + 0x56, 0x5d, 0x56, 0xb7, 0x5c, 0x70, 0x0, 0x10, + 0x0, 0x0, 0x20, 0x0, 0x0, 0xa, 0x65, 0x55, + 0x5d, 0x30, 0x0, 0x0, 0x92, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x9, 0x65, 0x55, 0x5d, 0x0, 0x0, + 0x0, 0x92, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xa, + 0x65, 0x55, 0x5d, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x10, 0x0, + + /* U+666F "景" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x55, 0xd1, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb, 0x55, 0x88, + 0x55, 0xa0, 0x0, 0x3, 0x33, 0x33, 0x3c, 0x33, + 0x35, 0xa0, 0x3, 0x24, 0x22, 0x22, 0x22, 0x62, + 0x20, 0x0, 0x8, 0x85, 0x55, 0x56, 0xc0, 0x0, + 0x0, 0x8, 0x40, 0x0, 0x1, 0xa0, 0x0, 0x0, + 0x6, 0x65, 0x6c, 0x55, 0x70, 0x0, 0x0, 0x1, + 0xc2, 0x1a, 0x5, 0x40, 0x0, 0x0, 0x59, 0x20, + 0x1a, 0x0, 0x6c, 0x20, 0x15, 0x20, 0x5, 0xa8, + 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x40, 0x0, + 0x0, 0x0, + + /* U+6674 "晴" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0xb3, 0x2, 0x10, 0xb5, 0x5d, 0x35, + 0x5c, 0x55, 0x64, 0xb, 0x0, 0xb0, 0x0, 0xb1, + 0x6, 0x0, 0xb0, 0xb, 0x5, 0x5c, 0x65, 0x51, + 0xb, 0x33, 0xb5, 0x55, 0xb5, 0x55, 0xa0, 0xb2, + 0x2b, 0x2, 0x0, 0x0, 0x40, 0xb, 0x0, 0xb0, + 0xb5, 0x55, 0x5c, 0x0, 0xb0, 0xb, 0xb, 0x55, + 0x55, 0xb0, 0xb, 0x33, 0xb0, 0xb0, 0x0, 0xb, + 0x0, 0xb2, 0x2b, 0xb, 0x55, 0x55, 0xb0, 0x5, + 0x0, 0x10, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x49, 0xa0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x41, 0x0, + + /* U+667A "智" */ + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, 0xb0, + 0x3, 0x1, 0x0, 0x1, 0x6, 0x69, 0x86, 0x1b, + 0x55, 0x79, 0x5, 0x7, 0x30, 0xb, 0x0, 0x37, + 0x55, 0x5b, 0x57, 0x6b, 0x0, 0x37, 0x0, 0xb, + 0x74, 0xb, 0x55, 0x78, 0x0, 0x74, 0xa, 0x6b, + 0x0, 0x36, 0x5, 0x43, 0x0, 0x21, 0x4, 0x0, + 0x31, 0xd, 0x55, 0x55, 0x5d, 0x20, 0x0, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x0, 0xc, 0x55, 0x55, + 0x5c, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xd, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x1, 0x0, + + /* U+6687 "暇" */ + 0x0, 0x11, 0x75, 0x83, 0x55, 0x92, 0xb, 0x5c, + 0x49, 0xa, 0x0, 0xa, 0x0, 0xa0, 0xa1, 0x90, + 0xa0, 0x0, 0xa0, 0xa, 0xa, 0x1b, 0x5c, 0x15, + 0x5c, 0x0, 0xb5, 0xc1, 0x90, 0x40, 0x0, 0x10, + 0xa, 0xa, 0x19, 0x3, 0x45, 0x58, 0x30, 0xa0, + 0xa1, 0xb5, 0x40, 0x40, 0xb1, 0xa, 0xa, 0x19, + 0x2, 0x5, 0x1b, 0x0, 0xb5, 0xc2, 0xb5, 0x71, + 0x69, 0x30, 0x7, 0x1, 0x19, 0x0, 0x4, 0xe0, + 0x0, 0x0, 0x1, 0x90, 0x3, 0x84, 0xc3, 0x0, + 0x0, 0x28, 0x4, 0x40, 0x4, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6691 "暑" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x56, 0xc0, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x2, 0xa0, 0x0, 0x0, 0xb, 0x55, 0xd6, + 0x56, 0x8b, 0x10, 0x0, 0x15, 0x55, 0xd6, 0xa3, + 0xc4, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x6b, 0x11, + 0x50, 0x6, 0x55, 0x55, 0x9d, 0x85, 0x56, 0x70, + 0x0, 0x0, 0x7a, 0xc6, 0x55, 0x90, 0x0, 0x0, + 0x58, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x23, 0x0, + 0xd5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd5, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+6696 "暖" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x1, 0x45, 0x68, 0xab, 0x30, 0xb5, 0x5d, 0x23, + 0x6, 0x2, 0x90, 0xb, 0x0, 0xb0, 0x93, 0x74, + 0x73, 0x0, 0xb0, 0xb, 0x28, 0x66, 0x58, 0x95, + 0xb, 0x0, 0xb0, 0x4, 0x70, 0x0, 0x0, 0xc5, + 0x5b, 0x46, 0x98, 0x55, 0x5b, 0x1b, 0x0, 0xb0, + 0xa, 0x10, 0x0, 0x0, 0xb0, 0xb, 0x0, 0xc6, + 0x56, 0xd0, 0xb, 0x0, 0xb0, 0x64, 0x70, 0xb3, + 0x0, 0xc5, 0x5b, 0x19, 0x3, 0xc5, 0x0, 0xa, + 0x0, 0x7, 0x0, 0x8a, 0xa1, 0x0, 0x0, 0x3, + 0x3, 0x82, 0x5, 0xda, 0x20, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x20, + + /* U+6697 "暗" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0xb5, 0x5d, 0x16, + 0x56, 0x75, 0x93, 0xc, 0x0, 0xb0, 0x23, 0x0, + 0xa3, 0x0, 0xb0, 0xb, 0x0, 0xc1, 0xa, 0x0, + 0xb, 0x0, 0xb1, 0x26, 0x26, 0x32, 0x80, 0xc5, + 0x5b, 0x33, 0x33, 0x33, 0x33, 0xb, 0x0, 0xb0, + 0x75, 0x55, 0x5a, 0x0, 0xb0, 0xb, 0xb, 0x0, + 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb5, 0x55, 0x5b, + 0x0, 0xc5, 0x5b, 0xb, 0x0, 0x0, 0xb0, 0x4, + 0x0, 0x10, 0xb5, 0x55, 0x5c, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+66C7 "曇" */ + 0x0, 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0xa, + 0x55, 0x55, 0x55, 0xc1, 0x0, 0x0, 0xa5, 0x55, + 0x55, 0x5b, 0x0, 0x0, 0xa, 0x55, 0x55, 0x55, + 0xb0, 0x0, 0x0, 0x53, 0x33, 0x33, 0x39, 0x20, + 0x0, 0x32, 0x11, 0xa2, 0x11, 0x11, 0x40, 0x39, + 0x77, 0x6b, 0x56, 0x77, 0x5c, 0x28, 0x27, 0x72, + 0x91, 0x37, 0x62, 0x0, 0x0, 0x11, 0x13, 0x11, + 0x44, 0x0, 0x0, 0x4, 0x43, 0x33, 0x33, 0x33, + 0x30, 0x55, 0x55, 0x79, 0x55, 0x55, 0x66, 0x0, + 0x0, 0x29, 0x20, 0x6, 0x40, 0x0, 0x0, 0x8d, + 0x98, 0x76, 0x5c, 0x30, 0x0, 0x2, 0x20, 0x0, + 0x0, 0x10, 0x0, + + /* U+66DC "曜" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x34, 0x65, 0xb4, 0x65, 0xb0, 0xc5, 0x6b, 0x37, + 0xa, 0x26, 0xa, 0xb, 0x1, 0x90, 0x60, 0xa0, + 0x61, 0xa0, 0xb0, 0x19, 0x16, 0x5a, 0x37, 0x5b, + 0xb, 0x56, 0xa9, 0x22, 0x69, 0x10, 0x60, 0xb0, + 0x19, 0x8, 0x60, 0xc2, 0x12, 0xb, 0x1, 0x91, + 0xc5, 0x5c, 0x56, 0x60, 0xb0, 0x19, 0x7c, 0x22, + 0xb2, 0x80, 0xb, 0x56, 0xb1, 0xc3, 0x3b, 0x33, + 0x10, 0xb0, 0x13, 0xc, 0x55, 0xc5, 0xa2, 0x2, + 0x0, 0x0, 0xb0, 0xa, 0x0, 0x30, 0x0, 0x0, + 0xd, 0x55, 0x75, 0x68, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, + + /* U+66F2 "曲" */ + 0x0, 0x3, 0x0, 0x30, 0x0, 0x0, 0x0, 0xc1, + 0xc, 0x10, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, + 0x8, 0x55, 0xc5, 0x5c, 0x55, 0xa1, 0xd0, 0xb, + 0x0, 0xb0, 0xc, 0xc, 0x0, 0xb0, 0xb, 0x0, + 0xc0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0xc, 0x55, + 0xc5, 0x5c, 0x55, 0xc0, 0xc0, 0xb, 0x0, 0xb0, + 0xc, 0xc, 0x0, 0xb0, 0xb, 0x0, 0xc0, 0xc0, + 0xb, 0x0, 0xb0, 0xc, 0xc, 0x55, 0xb5, 0x5b, + 0x55, 0xd0, 0xc0, 0x0, 0x0, 0x0, 0x9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+66F4 "更" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x55, 0x55, 0x56, 0x55, 0x56, 0xc1, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x19, 0x55, + 0x5d, 0x55, 0x5b, 0x0, 0x0, 0x1b, 0x0, 0xc, + 0x0, 0x1a, 0x0, 0x0, 0xc, 0x55, 0x5d, 0x55, + 0x6a, 0x0, 0x0, 0xb, 0x0, 0xc, 0x0, 0x1a, + 0x0, 0x0, 0x1c, 0x55, 0x5d, 0x55, 0x6a, 0x0, + 0x0, 0x5, 0x10, 0x38, 0x0, 0x4, 0x0, 0x0, + 0x0, 0x33, 0x75, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, + 0x7b, 0x62, 0x0, 0x0, 0x1, 0x57, 0x50, 0x1, + 0x6a, 0xdd, 0xe4, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+66F8 "書" */ + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x20, 0x0, 0x0, 0x45, 0x56, + 0xb5, 0x5c, 0x41, 0x3, 0x65, 0x55, 0x6b, 0x55, + 0xb7, 0x90, 0x0, 0x45, 0x56, 0xb5, 0x5b, 0x10, + 0x0, 0x0, 0x0, 0x29, 0x0, 0x32, 0x0, 0x3, + 0x55, 0x56, 0xb5, 0x56, 0x60, 0x4, 0x55, 0x55, + 0x69, 0x55, 0x58, 0x80, 0x0, 0x85, 0x55, 0x55, + 0x59, 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa1, + 0x0, 0x0, 0xd5, 0x55, 0x55, 0x5c, 0x10, 0x0, + 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xd5, + 0x55, 0x55, 0x5c, 0x10, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x20, 0x0, + + /* U+66FE "曾" */ + 0x0, 0x20, 0x0, 0x11, 0x0, 0x0, 0x3a, 0x0, + 0x96, 0x0, 0x20, 0x7, 0x2, 0x60, 0x12, 0xb5, + 0x55, 0xb6, 0x55, 0x88, 0xb0, 0x82, 0x91, 0x59, + 0x56, 0xb0, 0x39, 0x92, 0x80, 0x56, 0xb5, 0x56, + 0xb7, 0x55, 0x86, 0x60, 0x0, 0x0, 0x0, 0x22, + 0x9, 0x55, 0x55, 0x5b, 0x40, 0x9, 0x10, 0x0, + 0x9, 0x10, 0x9, 0x65, 0x55, 0x5b, 0x10, 0x9, + 0x10, 0x0, 0x9, 0x20, 0x9, 0x55, 0x55, 0x5b, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+66FF "替" */ + 0x0, 0x3, 0x0, 0x1, 0x20, 0x0, 0x0, 0xd, + 0x10, 0x2, 0xb0, 0x0, 0x5, 0x5d, 0x77, 0x46, + 0xb7, 0x70, 0x0, 0xb, 0x1, 0x3, 0x80, 0x20, + 0x25, 0x7b, 0x65, 0x59, 0xb5, 0x73, 0x0, 0x86, + 0x90, 0xa, 0x17, 0x0, 0x4, 0x60, 0x55, 0x81, + 0x5, 0xa4, 0x43, 0x75, 0x59, 0x55, 0x5a, 0x42, + 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x29, 0x0, 0x0, 0xc5, 0x55, 0x55, + 0x69, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x6a, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x0, + + /* U+6700 "最" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x6, 0x85, 0x55, 0x55, 0xd2, 0x0, 0x0, 0x6, + 0x95, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x6, 0x60, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6, 0x95, 0x55, + 0x55, 0xd0, 0x0, 0x4, 0x56, 0x55, 0x55, 0x55, + 0x58, 0xd1, 0x0, 0x29, 0x0, 0xb0, 0x0, 0x3, + 0x0, 0x0, 0x2b, 0x55, 0xc4, 0x85, 0x5d, 0x30, + 0x0, 0x2b, 0x55, 0xc0, 0x50, 0x39, 0x0, 0x0, + 0x29, 0x0, 0xb0, 0x28, 0xb1, 0x0, 0x0, 0x2b, + 0x67, 0xd5, 0x1a, 0x90, 0x0, 0xa, 0xc7, 0x30, + 0xb0, 0x56, 0x99, 0x10, 0x0, 0x0, 0x0, 0xb5, + 0x30, 0x6, 0xb2, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+6703 "會" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x71, 0x60, 0x0, 0x0, 0x0, 0x1, 0xa5, + 0x0, 0x5a, 0x61, 0x0, 0x0, 0x57, 0x25, 0x55, + 0x51, 0x6c, 0xb1, 0x4, 0xb, 0x55, 0x59, 0x55, + 0xb3, 0x0, 0x0, 0xb, 0x57, 0xb, 0x56, 0x91, + 0x0, 0x0, 0xb, 0x6, 0xb, 0x60, 0x91, 0x0, + 0x0, 0x8, 0x55, 0x55, 0x56, 0x70, 0x0, 0x0, + 0x3, 0xa5, 0x55, 0x5c, 0x30, 0x0, 0x0, 0x2, + 0xb5, 0x55, 0x5c, 0x10, 0x0, 0x0, 0x2, 0x90, + 0x0, 0xa, 0x10, 0x0, 0x0, 0x3, 0xb5, 0x55, + 0x5c, 0x10, 0x0, 0x0, 0x1, 0x30, 0x0, 0x4, + 0x0, 0x0, + + /* U+6708 "月" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, + 0x55, 0x55, 0xc1, 0x0, 0xc, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0xd, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xd5, 0x55, 0x55, 0xc0, 0x0, 0x2a, 0x0, 0x0, + 0xc, 0x0, 0x5, 0x70, 0x0, 0x0, 0xc0, 0x0, + 0xa1, 0x0, 0x0, 0xc, 0x0, 0x37, 0x0, 0x1, + 0x11, 0xd0, 0x26, 0x0, 0x0, 0x5, 0xe9, 0x2, + 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+6709 "有" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x15, 0x55, + 0x58, 0xc5, 0x55, 0x5a, 0xc1, 0x1, 0x0, 0xc, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x40, 0x0, 0x0, 0x2, 0xe5, 0x55, 0x55, + 0xe0, 0x0, 0x0, 0x19, 0xc0, 0x0, 0x0, 0xc0, + 0x0, 0x1, 0x80, 0xc5, 0x55, 0x55, 0xc0, 0x0, + 0x15, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0xd5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x5c, 0x90, 0x0, 0x0, 0x0, 0x10, 0x0, 0x2, + 0x0, 0x0, + + /* U+670B "朋" */ + 0x0, 0x75, 0x59, 0x20, 0x85, 0x59, 0x20, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, 0xb0, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0xc, 0x55, 0xc0, 0xc, + 0x55, 0xc0, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb, + 0x0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, + 0xc5, 0x5c, 0x0, 0xc5, 0x5c, 0x0, 0xa, 0x0, + 0xb0, 0xa, 0x0, 0xb0, 0x0, 0xa0, 0xb, 0x3, + 0x70, 0xb, 0x0, 0x36, 0x0, 0xb0, 0x82, 0x0, + 0xb0, 0x7, 0x2, 0x6d, 0x18, 0x0, 0xc, 0x1, + 0x40, 0x4, 0x66, 0x0, 0x4c, 0xd0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x10, 0x0, + + /* U+670D "服" */ + 0x0, 0x95, 0x5a, 0x9, 0x55, 0x5a, 0x10, 0x0, + 0xb0, 0xb, 0xb, 0x0, 0xc, 0x0, 0x0, 0xb0, + 0xb, 0xb, 0x0, 0xc, 0x0, 0x0, 0xc5, 0x5b, + 0xb, 0x4, 0x89, 0x0, 0x0, 0xb0, 0xb, 0xb, + 0x0, 0x51, 0x0, 0x0, 0xb0, 0xb, 0xc, 0x65, + 0x5a, 0x50, 0x0, 0xc5, 0x5b, 0xb, 0x42, 0xc, + 0x0, 0x0, 0xb0, 0xb, 0xb, 0x7, 0x29, 0x0, + 0x0, 0xa0, 0xb, 0xb, 0x6, 0xb2, 0x0, 0x4, + 0x60, 0xb, 0xb, 0x4, 0xd1, 0x0, 0x8, 0x2, + 0x1b, 0xb, 0x37, 0x1c, 0x61, 0x14, 0x1, 0xc7, + 0xd, 0x30, 0x1, 0x71, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+671B "望" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x8, 0x55, 0x59, 0x10, 0x0, 0x5, + 0x14, 0xc, 0x0, 0xb, 0x0, 0x16, 0xb5, 0x57, + 0x2d, 0x55, 0x5c, 0x0, 0x0, 0xb0, 0x0, 0xc, + 0x0, 0xb, 0x0, 0x0, 0xb0, 0x25, 0x3c, 0x55, + 0x5c, 0x0, 0x0, 0xca, 0x60, 0x75, 0x2, 0x3c, + 0x0, 0x0, 0x40, 0x3, 0x60, 0x0, 0x67, 0x0, + 0x3, 0x65, 0x57, 0x75, 0x55, 0x6b, 0x10, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x10, 0x0, 0x0, 0x46, + 0x55, 0xd5, 0x56, 0x90, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x15, 0x55, 0x55, 0xd5, + 0x55, 0x5b, 0x90, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+671D "朝" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x42, 0x22, 0x70, 0x4, 0x55, + 0xc5, 0x75, 0x93, 0x22, 0xc0, 0x0, 0x0, 0xb0, + 0x0, 0x91, 0x0, 0xb0, 0x0, 0xa5, 0x95, 0xc0, + 0x93, 0x11, 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0x94, + 0x33, 0xb0, 0x0, 0xc5, 0x55, 0xb0, 0x91, 0x0, + 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0xa1, 0x0, 0xb0, + 0x0, 0xc5, 0xc5, 0x90, 0xb5, 0x55, 0xb0, 0x0, + 0x0, 0xb0, 0x31, 0xb0, 0x0, 0xb0, 0x16, 0x55, + 0xc5, 0x55, 0x80, 0x0, 0xb0, 0x0, 0x0, 0xb0, + 0x8, 0x10, 0x0, 0xb0, 0x0, 0x0, 0xc0, 0x43, + 0x0, 0x4c, 0x80, 0x0, 0x0, 0x20, 0x10, 0x0, + 0x1, 0x0, + + /* U+671F "期" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0xd0, 0x16, 0x44, 0x81, 0x0, 0x1a, + 0x0, 0xc5, 0x1b, 0x11, 0xc0, 0x3, 0x6c, 0x55, + 0xd5, 0x3b, 0x0, 0xc0, 0x0, 0x1c, 0x55, 0xc0, + 0x1c, 0x55, 0xc0, 0x0, 0x1a, 0x0, 0xc0, 0x1a, + 0x0, 0xc0, 0x0, 0x1c, 0x55, 0xc0, 0x1a, 0x0, + 0xc0, 0x0, 0x1a, 0x0, 0xc0, 0x2b, 0x22, 0xc0, + 0x3, 0x6c, 0x55, 0xda, 0x5a, 0x33, 0xc0, 0x0, + 0x6, 0x13, 0x0, 0x66, 0x0, 0xc0, 0x0, 0x2c, + 0x24, 0xa0, 0xb1, 0x0, 0xc0, 0x0, 0xa1, 0x0, + 0x75, 0x60, 0x10, 0xc0, 0x6, 0x0, 0x0, 0x35, + 0x0, 0x2b, 0xa0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+6728 "木" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x3, 0x0, 0x7, 0x55, 0x57, 0xe7, + 0x55, 0x5b, 0x50, 0x0, 0x0, 0xb, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2b, 0xc3, 0x60, 0x0, + 0x0, 0x0, 0x0, 0xb3, 0xc1, 0xa1, 0x0, 0x0, + 0x0, 0x6, 0x70, 0xc1, 0x3b, 0x0, 0x0, 0x0, + 0x48, 0x0, 0xc1, 0x6, 0xd3, 0x0, 0x3, 0x70, + 0x0, 0xc1, 0x0, 0x7f, 0xa0, 0x23, 0x0, 0x0, + 0xc1, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+672A "未" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x50, 0x0, 0x0, 0x46, 0x55, + 0xc7, 0x56, 0x71, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x5, 0x0, 0x6, 0x55, 0x58, 0xf9, 0x55, 0x58, + 0x40, 0x0, 0x0, 0xc, 0xd5, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x86, 0xa2, 0x81, 0x0, 0x0, 0x0, + 0x6, 0x70, 0xa2, 0x1c, 0x20, 0x0, 0x0, 0x65, + 0x0, 0xa2, 0x2, 0xe8, 0x10, 0x16, 0x20, 0x0, + 0xa3, 0x0, 0x2c, 0x80, 0x0, 0x0, 0x0, 0xb3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+672B "末" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x5, 0x0, 0x7, 0x55, 0x55, + 0xc7, 0x55, 0x58, 0x40, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x80, 0x0, 0x0, 0x55, 0x5a, 0xfa, 0x55, 0x52, + 0x0, 0x0, 0x0, 0x1c, 0xb4, 0x60, 0x0, 0x0, + 0x0, 0x0, 0xb3, 0xa2, 0x74, 0x0, 0x0, 0x0, + 0x9, 0x40, 0xa2, 0xb, 0x60, 0x0, 0x0, 0x83, + 0x0, 0xa2, 0x0, 0xcc, 0x60, 0x26, 0x10, 0x0, + 0xa3, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0xb3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+672C "本" */ + 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x2, 0x55, 0x55, + 0x6c, 0x55, 0x58, 0xb0, 0x0, 0x10, 0x0, 0xea, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x6, 0xaa, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0x3a, 0x18, 0x0, + 0x0, 0x0, 0x0, 0xa3, 0x2a, 0x7, 0x50, 0x0, + 0x0, 0x7, 0x50, 0x2a, 0x0, 0xb7, 0x0, 0x0, + 0x66, 0x55, 0x6c, 0x59, 0x7c, 0xd3, 0x5, 0x20, + 0x0, 0x2a, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, + 0x0, 0x0, + + /* U+672D "札" */ + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xc0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x3, + 0xa0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2, 0xa0, + 0x60, 0xd0, 0x0, 0x0, 0x6, 0x57, 0xc5, 0x50, + 0xd0, 0x0, 0x0, 0x0, 0x7, 0xb0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0xc, 0xca, 0x30, 0xd0, 0x0, + 0x0, 0x0, 0x3a, 0xa3, 0xe0, 0xd0, 0x0, 0x0, + 0x0, 0x93, 0xa0, 0x30, 0xd0, 0x0, 0x0, 0x3, + 0x42, 0xa0, 0x0, 0xd0, 0x0, 0x30, 0x4, 0x2, + 0xa0, 0x0, 0xd0, 0x0, 0x60, 0x0, 0x3, 0xa0, + 0x0, 0xc0, 0x0, 0xa2, 0x0, 0x3, 0xa0, 0x0, + 0x9c, 0xaa, 0xd3, 0x0, 0x1, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+673A "机" */ + 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x2, 0x0, 0x40, 0x0, 0x0, 0xc, + 0x0, 0x1c, 0x55, 0xd1, 0x0, 0x0, 0xc, 0x4, + 0x1b, 0x0, 0xc0, 0x0, 0x5, 0x6e, 0x55, 0x1b, + 0x0, 0xc0, 0x0, 0x0, 0x4d, 0x0, 0x1b, 0x0, + 0xc0, 0x0, 0x0, 0x8d, 0x94, 0x1b, 0x0, 0xc0, + 0x0, 0x0, 0xac, 0xc, 0x1a, 0x0, 0xc0, 0x0, + 0x3, 0x5c, 0x0, 0x29, 0x0, 0xc0, 0x0, 0x7, + 0xc, 0x0, 0x56, 0x0, 0xc0, 0x0, 0x22, 0xc, + 0x0, 0xa1, 0x0, 0xc0, 0x50, 0x0, 0xc, 0x2, + 0x70, 0x0, 0xc0, 0x70, 0x0, 0xd, 0x7, 0x0, + 0x0, 0xba, 0xd3, 0x0, 0x8, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+6750 "材" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x6, + 0x0, 0x0, 0xd1, 0x60, 0x35, 0x5e, 0x55, 0x24, + 0x46, 0xf4, 0x40, 0x0, 0x1f, 0x50, 0x0, 0x9, + 0xf0, 0x0, 0x0, 0x7f, 0x4b, 0x0, 0x2c, 0xd0, + 0x0, 0x0, 0xbc, 0x9, 0x10, 0xa2, 0xd0, 0x0, + 0x5, 0x5c, 0x0, 0x7, 0x50, 0xd0, 0x0, 0x7, + 0xc, 0x0, 0x55, 0x0, 0xd0, 0x0, 0x40, 0xc, + 0x3, 0x20, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x10, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x10, 0x0, + 0x5c, 0xd0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, + 0x10, 0x0, + + /* U+6751 "村" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, + 0xd, 0x20, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x5, + 0x0, 0x0, 0xd1, 0x40, 0x25, 0x5f, 0x55, 0x25, + 0x55, 0xe5, 0x40, 0x0, 0x4f, 0x20, 0x3, 0x0, + 0xd0, 0x0, 0x0, 0x8f, 0x69, 0x6, 0x60, 0xd0, + 0x0, 0x0, 0x9d, 0xb, 0x10, 0xe0, 0xd0, 0x0, + 0x6, 0x3d, 0x0, 0x0, 0x40, 0xd0, 0x0, 0x6, + 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x30, 0xd, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x5c, 0xe0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2, + 0x10, 0x0, + + /* U+675F "束" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x10, 0x5, 0x65, + 0x55, 0x5d, 0x55, 0x55, 0xb4, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x29, 0x55, 0x5d, + 0x55, 0x6b, 0x0, 0x0, 0x1b, 0x0, 0xc, 0x0, + 0x2a, 0x0, 0x0, 0x1b, 0x0, 0xc, 0x0, 0x2a, + 0x0, 0x0, 0x1c, 0x55, 0x8d, 0x65, 0x7a, 0x0, + 0x0, 0x28, 0x5, 0xbc, 0x60, 0x13, 0x0, 0x0, + 0x0, 0x2c, 0x1c, 0x18, 0x0, 0x0, 0x0, 0x2, + 0xb1, 0xc, 0x4, 0xa2, 0x0, 0x0, 0x49, 0x0, + 0x1c, 0x0, 0x4e, 0xa3, 0x5, 0x40, 0x0, 0x1c, + 0x0, 0x1, 0x60, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+6761 "条" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, + 0xb8, 0x55, 0x5c, 0xb0, 0x0, 0x0, 0x7, 0x35, + 0x10, 0x4d, 0x0, 0x0, 0x0, 0x44, 0x0, 0x95, + 0xc2, 0x0, 0x0, 0x1, 0x20, 0x0, 0x9f, 0x70, + 0x0, 0x0, 0x0, 0x2, 0x79, 0x47, 0x9d, 0xa7, + 0x63, 0x4, 0x54, 0x0, 0xe, 0x0, 0x58, 0x70, + 0x0, 0x17, 0x55, 0x5e, 0x55, 0x96, 0x0, 0x0, + 0x0, 0x54, 0xd, 0x21, 0x0, 0x0, 0x0, 0x2, + 0xd3, 0xd, 0x7, 0x80, 0x0, 0x0, 0x2a, 0x10, + 0xd, 0x0, 0x8c, 0x0, 0x3, 0x50, 0x5, 0xda, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+6765 "来" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x17, 0x0, 0x2, 0x66, 0x55, + 0xc7, 0x55, 0x75, 0x10, 0x0, 0x8, 0x60, 0xa2, + 0x7, 0xa0, 0x0, 0x0, 0x0, 0xe0, 0xa2, 0x1a, + 0x0, 0x0, 0x25, 0x55, 0x75, 0xc7, 0x95, 0x5a, + 0x90, 0x1, 0x0, 0x8, 0xf6, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0xa2, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0xa2, 0x3a, 0x0, 0x0, 0x0, 0xa, + 0x20, 0xa2, 0x5, 0xc3, 0x0, 0x1, 0x81, 0x0, + 0xa3, 0x0, 0x4e, 0xa0, 0x24, 0x0, 0x0, 0xb3, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+676F "杯" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0x0, 0x0, 0x42, 0x0, 0xb, 0x4, + 0x55, 0x9a, 0x55, 0x30, 0x0, 0xb0, 0x40, 0xa, + 0x20, 0x0, 0x15, 0x5d, 0x56, 0x0, 0xb0, 0x0, + 0x0, 0x1, 0xf4, 0x0, 0x7d, 0x20, 0x0, 0x0, + 0x7f, 0x68, 0xb, 0xb0, 0x30, 0x0, 0x9, 0xb0, + 0xa8, 0x2b, 0x2, 0x90, 0x6, 0x2b, 0x3, 0x50, + 0xb0, 0x7, 0xa2, 0x40, 0xb2, 0x50, 0xb, 0x0, + 0x5, 0x20, 0xb, 0x10, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x2, 0x0, 0x0, + + /* U+6771 "東" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0x0, 0x2, 0x10, 0x3, 0x65, + 0x55, 0x5c, 0x55, 0x59, 0x80, 0x0, 0x2, 0x0, + 0x1b, 0x0, 0x40, 0x0, 0x0, 0xd, 0x55, 0x5c, + 0x55, 0xd3, 0x0, 0x0, 0xc, 0x0, 0x1b, 0x0, + 0xc0, 0x0, 0x0, 0xd, 0x55, 0x5c, 0x55, 0xd0, + 0x0, 0x0, 0xd, 0x55, 0x6c, 0x55, 0xd0, 0x0, + 0x0, 0x7, 0x3, 0xdb, 0x50, 0x40, 0x0, 0x0, + 0x0, 0xc, 0x3b, 0x44, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x1b, 0x9, 0x50, 0x0, 0x0, 0x9, 0x30, + 0x1b, 0x0, 0xac, 0x51, 0x4, 0x60, 0x0, 0x1b, + 0x0, 0x5, 0xa2, 0x1, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+6790 "析" */ + 0x0, 0x5, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0xd, 0x0, 0x24, 0x46, 0x9a, 0x40, 0x0, 0xc, + 0x0, 0x39, 0x0, 0x0, 0x0, 0x5, 0x5d, 0x69, + 0x39, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x39, + 0x0, 0x0, 0x10, 0x0, 0x5e, 0x10, 0x3b, 0x55, + 0x85, 0xb2, 0x0, 0xac, 0xa4, 0x38, 0x0, 0xc0, + 0x0, 0x0, 0x9c, 0x28, 0x48, 0x0, 0xc0, 0x0, + 0x6, 0x2c, 0x0, 0x56, 0x0, 0xc0, 0x0, 0x5, + 0xc, 0x0, 0x83, 0x0, 0xc0, 0x0, 0x0, 0xc, + 0x0, 0xb0, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x6, + 0x40, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x25, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x10, 0x0, + + /* U+6797 "林" */ + 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xa, + 0x10, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xa, 0x33, + 0x0, 0xb1, 0x18, 0x0, 0x5, 0x5d, 0x64, 0x34, + 0xf8, 0x44, 0x10, 0x0, 0xf, 0x20, 0x5, 0xf7, + 0x0, 0x0, 0x0, 0x5f, 0x94, 0xa, 0xc7, 0x10, + 0x0, 0x0, 0xab, 0x2c, 0x27, 0xb2, 0x90, 0x0, + 0x4, 0x5a, 0x11, 0x80, 0xb1, 0x94, 0x0, 0x6, + 0xa, 0x15, 0x20, 0xb1, 0x1e, 0x60, 0x20, 0xa, + 0x33, 0x0, 0xb1, 0x3, 0x30, 0x0, 0xa, 0x10, + 0x0, 0xb1, 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, + 0xb1, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x40, + 0x0, 0x0, + + /* U+679C "果" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x55, 0x59, 0x55, 0xc3, 0x0, 0x0, 0xc, + 0x0, 0x1b, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x55, + 0x6c, 0x55, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x1b, + 0x0, 0xc0, 0x0, 0x0, 0xd, 0x55, 0x6c, 0x55, + 0xd0, 0x0, 0x0, 0x9, 0x0, 0x1b, 0x0, 0x70, + 0x0, 0x3, 0x55, 0x55, 0x6c, 0x55, 0x5b, 0xb1, + 0x1, 0x0, 0x4, 0xcd, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0x2b, 0x74, 0x0, 0x0, 0x0, 0x3, + 0xa0, 0x1b, 0xb, 0x80, 0x0, 0x0, 0x66, 0x0, + 0x2b, 0x0, 0x9e, 0x92, 0x5, 0x10, 0x0, 0x2b, + 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+67D0 "某" */ + 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0xd, 0x0, 0x0, 0x5, 0x55, + 0xd5, 0x55, 0x5d, 0x5a, 0x50, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xd5, 0x85, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x10, 0xa1, 0x0, 0x3, 0x30, + 0x7, 0x55, 0x5b, 0xe9, 0x55, 0x56, 0x60, 0x0, + 0x0, 0x39, 0xa3, 0x60, 0x0, 0x0, 0x0, 0x2, + 0xa0, 0xa1, 0x58, 0x0, 0x0, 0x0, 0x48, 0x0, + 0xa2, 0x4, 0xd8, 0x40, 0x15, 0x30, 0x0, 0xb2, + 0x0, 0x19, 0x60, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+67E5 "查" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x20, 0x0, 0x10, 0x6, 0x55, 0x57, + 0xe6, 0x55, 0x59, 0x40, 0x0, 0x1, 0xbd, 0x25, + 0x0, 0x0, 0x0, 0x1, 0xa2, 0xc0, 0x57, 0x0, + 0x0, 0x2, 0x91, 0xb, 0x0, 0x4c, 0x72, 0x5, + 0x49, 0x65, 0x55, 0x56, 0xc7, 0x41, 0x0, 0xa2, + 0x0, 0x0, 0x29, 0x0, 0x0, 0x9, 0x65, 0x55, + 0x56, 0x90, 0x0, 0x0, 0x92, 0x0, 0x0, 0x29, + 0x0, 0x0, 0xa, 0x65, 0x55, 0x56, 0xa0, 0x0, + 0x0, 0x91, 0x0, 0x0, 0x15, 0x10, 0x4, 0x55, + 0x55, 0x55, 0x55, 0x5e, 0x30, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+67F1 "柱" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x4b, 0x0, 0x0, 0x0, 0xc, 0x13, + 0x23, 0x36, 0x34, 0xb1, 0x6, 0x5d, 0x55, 0x22, + 0x1c, 0x11, 0x10, 0x0, 0x3d, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x8d, 0xa3, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xac, 0x3a, 0x35, 0x5d, 0x59, 0x80, + 0x5, 0x4c, 0x0, 0x10, 0xc, 0x0, 0x0, 0x6, + 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x10, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc, 0x0, 0x30, 0x0, 0xd, 0x5, 0x55, + 0x58, 0x56, 0x92, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+67FB "査" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x2, 0x80, 0x4, 0x65, 0x55, + 0xdd, 0x95, 0x55, 0x51, 0x0, 0x0, 0x9, 0x6c, + 0x37, 0x0, 0x0, 0x0, 0x0, 0x95, 0xc, 0x4, + 0xb4, 0x0, 0x0, 0x58, 0x20, 0xa, 0x0, 0x4a, + 0xe6, 0x4, 0x11, 0xc5, 0x55, 0x55, 0xe0, 0x10, + 0x0, 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x1, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x1, + 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x1, 0xb0, + 0x0, 0x0, 0xc0, 0x10, 0x5, 0x55, 0xc5, 0x55, + 0x55, 0xd6, 0xf5, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+67FF "柿" */ + 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x2b, 0x0, 0x10, 0x0, 0xc, 0x14, + 0x65, 0x58, 0x55, 0xb2, 0x5, 0x5d, 0x65, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x4d, 0x0, 0x75, 0x5d, + 0x55, 0x80, 0x0, 0x9d, 0xb3, 0xc0, 0xc, 0x2, + 0xa0, 0x0, 0x9c, 0x35, 0xc0, 0xc, 0x2, 0xa0, + 0x5, 0x3c, 0x0, 0xc0, 0xc, 0x2, 0xa0, 0x6, + 0xc, 0x0, 0xc0, 0xc, 0x2, 0xa0, 0x10, 0xc, + 0x0, 0xc0, 0xc, 0x2a, 0x80, 0x0, 0xd, 0x0, + 0x20, 0xc, 0x2, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+6811 "树" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xc, + 0x4, 0x55, 0x91, 0xc, 0x0, 0x0, 0xc, 0x22, + 0x0, 0xc0, 0xc, 0x41, 0x5, 0x5d, 0x66, 0x3, + 0x95, 0x5d, 0x53, 0x0, 0x3d, 0x0, 0x57, 0x40, + 0xc, 0x0, 0x0, 0x7d, 0xa2, 0x6c, 0x53, 0xc, + 0x0, 0x0, 0xac, 0x28, 0x4d, 0xc, 0xc, 0x0, + 0x3, 0x4c, 0x0, 0xa8, 0x58, 0xc, 0x0, 0x6, + 0xc, 0x5, 0x33, 0x90, 0xc, 0x0, 0x10, 0xc, + 0x24, 0x0, 0x20, 0xc, 0x0, 0x0, 0xc, 0x10, + 0x0, 0x11, 0x1c, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x6, 0xe9, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x20, 0x0, + + /* U+6821 "校" */ + 0x0, 0x1, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x56, 0x0, 0x40, 0x0, 0xc, 0x15, + 0x65, 0x55, 0x56, 0x81, 0x5, 0x5e, 0x54, 0x8, + 0x61, 0x61, 0x0, 0x0, 0x4e, 0x60, 0x2b, 0x0, + 0x2d, 0x40, 0x0, 0x9d, 0x86, 0x80, 0x0, 0x34, + 0x90, 0x0, 0x9c, 0x4, 0x4, 0x0, 0xd5, 0x0, + 0x5, 0x3c, 0x0, 0x5, 0x3, 0xb0, 0x0, 0x6, + 0xc, 0x0, 0x1, 0x6b, 0x20, 0x0, 0x10, 0xc, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x6, 0x7a, 0x91, 0x0, 0x0, 0xd, 0x4, 0x72, + 0x0, 0x5d, 0xc3, 0x0, 0x3, 0x21, 0x0, 0x0, + 0x0, 0x20, + + /* U+682A "株" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x1, 0xd, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x3c, 0xc, 0x0, 0x0, 0x0, 0xc, 0x23, + 0x7a, 0x5d, 0x59, 0x60, 0x6, 0x6d, 0x54, 0xa0, + 0xc, 0x0, 0x0, 0x0, 0x4d, 0x1, 0x20, 0xc, + 0x0, 0x10, 0x0, 0x9d, 0xb5, 0x65, 0x8d, 0x65, + 0x94, 0x0, 0x9c, 0x34, 0x1, 0xdc, 0x50, 0x0, + 0x6, 0x2c, 0x0, 0x9, 0x4c, 0x71, 0x0, 0x5, + 0xc, 0x0, 0x38, 0xc, 0x1a, 0x0, 0x0, 0xc, + 0x1, 0x80, 0xc, 0x6, 0xb2, 0x0, 0xd, 0x16, + 0x0, 0xc, 0x0, 0x84, 0x0, 0xd, 0x10, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+6839 "根" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x85, 0x55, 0x5c, 0x10, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x1, 0x1c, 0x24, + 0xc0, 0x0, 0xc, 0x0, 0x4, 0x4d, 0x33, 0xc5, + 0x55, 0x5c, 0x0, 0x0, 0x4d, 0x10, 0xc0, 0x0, + 0xc, 0x0, 0x0, 0x9c, 0xa3, 0xc5, 0x65, 0x5c, + 0x0, 0x0, 0x9c, 0x37, 0xc0, 0x60, 0x7, 0x70, + 0x5, 0x2c, 0x0, 0xc0, 0x61, 0x68, 0x10, 0x5, + 0xc, 0x0, 0xc0, 0x1b, 0x10, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x8, 0x50, 0x0, 0x0, 0xd, 0x0, + 0xc2, 0x61, 0xb9, 0x10, 0x0, 0xd, 0x0, 0xd9, + 0x0, 0x9, 0xd3, 0x0, 0x2, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+683C "格" */ + 0x0, 0x3, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, + 0xd, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x2d, 0x55, 0x5a, 0x0, 0x0, 0xb, 0x23, + 0x87, 0x0, 0x85, 0x0, 0x5, 0x6d, 0x56, 0x43, + 0x53, 0xa0, 0x0, 0x0, 0x4d, 0x3, 0x0, 0x9c, + 0x10, 0x0, 0x0, 0x9c, 0xa2, 0x2, 0xbb, 0x40, + 0x0, 0x0, 0x8b, 0x25, 0x47, 0x0, 0x9c, 0x72, + 0x5, 0x2b, 0x24, 0x95, 0x55, 0x5b, 0x60, 0x5, + 0xb, 0x0, 0xa1, 0x0, 0x29, 0x0, 0x0, 0xb, + 0x0, 0xa1, 0x0, 0x29, 0x0, 0x0, 0xc, 0x0, + 0xa1, 0x0, 0x29, 0x0, 0x0, 0xc, 0x0, 0xa6, + 0x55, 0x6a, 0x0, 0x0, 0x4, 0x0, 0x30, 0x0, + 0x2, 0x0, + + /* U+6843 "桃" */ + 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x9, 0x4a, 0x40, 0x0, 0x0, 0xb, + 0x0, 0x9, 0x29, 0x10, 0x0, 0x0, 0xb, 0x32, + 0x9, 0x29, 0x13, 0x30, 0x5, 0x5d, 0x53, 0x79, + 0x29, 0x2b, 0x40, 0x0, 0x4d, 0x0, 0xc9, 0x29, + 0x71, 0x0, 0x0, 0x8c, 0xa2, 0x29, 0x29, 0x10, + 0x0, 0x0, 0xab, 0x36, 0xb, 0x29, 0x84, 0x0, + 0x4, 0x4b, 0x3, 0x9b, 0x19, 0x2b, 0x40, 0x7, + 0xb, 0xa, 0xb, 0x9, 0x10, 0x20, 0x11, 0xb, + 0x0, 0x29, 0x9, 0x10, 0x40, 0x0, 0xc, 0x0, + 0x91, 0x9, 0x20, 0x80, 0x0, 0xc, 0x6, 0x30, + 0x6, 0xca, 0xd2, 0x0, 0x6, 0x21, 0x0, 0x0, + 0x0, 0x0, + + /* U+6848 "案" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x75, + 0x55, 0x86, 0x55, 0x5a, 0x60, 0x3, 0xb0, 0x4, + 0xa0, 0x0, 0x9, 0x0, 0x1, 0x55, 0x5c, 0x55, + 0x58, 0x59, 0x60, 0x0, 0x0, 0x94, 0x0, 0xa4, + 0x0, 0x0, 0x0, 0x0, 0x14, 0x7d, 0xc6, 0x10, + 0x0, 0x0, 0x1, 0x57, 0x83, 0x6, 0xd4, 0x0, + 0x0, 0x32, 0x0, 0x2c, 0x0, 0x3, 0x70, 0x3, + 0x55, 0x57, 0xdc, 0x85, 0x55, 0x61, 0x0, 0x0, + 0x2b, 0x3a, 0x56, 0x0, 0x0, 0x0, 0x5, 0x80, + 0x2a, 0x5, 0xb7, 0x30, 0x4, 0x62, 0x0, 0x2b, + 0x0, 0x18, 0xb2, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+689D "條" */ + 0x0, 0x3, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, + 0x1f, 0x20, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x58, + 0x0, 0xc, 0x75, 0x5a, 0x10, 0x0, 0xb1, 0x50, + 0x39, 0x50, 0x78, 0x0, 0x3, 0xf1, 0xc0, 0x80, + 0x87, 0x90, 0x0, 0x8, 0xb0, 0xb1, 0x0, 0x8d, + 0x60, 0x0, 0x41, 0xb0, 0xb0, 0x28, 0x41, 0x8d, + 0x92, 0x0, 0xb0, 0xb3, 0x30, 0x1c, 0x1, 0x40, + 0x0, 0xb0, 0xb4, 0x65, 0x6b, 0x57, 0x80, 0x0, + 0xb0, 0xc0, 0x14, 0x1a, 0x10, 0x0, 0x0, 0xb0, + 0x70, 0xa7, 0x1a, 0x2a, 0x20, 0x0, 0xb0, 0x5, + 0x60, 0x1a, 0x3, 0xd0, 0x0, 0xb0, 0x23, 0x5, + 0xd8, 0x0, 0x40, 0x0, 0x20, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+68B0 "械" */ + 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xa4, 0x0, 0x0, 0xd, 0x28, 0x0, 0x0, 0x92, + 0x0, 0x0, 0xb, 0x6, 0x30, 0x0, 0x93, 0x34, + 0x44, 0x4c, 0x45, 0x90, 0x36, 0xc6, 0x44, 0x12, + 0xb, 0x0, 0x0, 0x0, 0xd8, 0x19, 0x2c, 0xb, + 0x3, 0x50, 0x1, 0xf5, 0xa9, 0x1a, 0xa, 0x8, + 0x50, 0x6, 0xb2, 0x7b, 0x5c, 0x8b, 0xc, 0x0, + 0x7, 0x92, 0xa, 0xa, 0x8, 0x86, 0x0, 0x41, + 0x92, 0xa, 0xa, 0x5, 0xd0, 0x10, 0x0, 0x92, + 0x17, 0xb, 0x9, 0xc0, 0x50, 0x0, 0xa2, 0x60, + 0x8, 0x83, 0x4a, 0x80, 0x0, 0xa4, 0x30, 0x26, + 0x10, 0x6, 0xe0, 0x0, 0x30, 0x0, 0x20, 0x0, + 0x0, 0x10, + + /* U+68EE "森" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x2, 0x0, 0x5, 0x55, + 0x57, 0xe7, 0x55, 0x5b, 0x20, 0x0, 0x0, 0x2c, + 0xd3, 0x50, 0x0, 0x0, 0x0, 0x1, 0xb1, 0xc0, + 0x69, 0x10, 0x0, 0x0, 0x38, 0x0, 0xc0, 0x7, + 0xe9, 0x50, 0x4, 0x39, 0x30, 0xb0, 0xd, 0x17, + 0x20, 0x25, 0x5b, 0x69, 0x35, 0x5d, 0x58, 0x80, + 0x0, 0x1f, 0x20, 0x0, 0xdc, 0x50, 0x0, 0x0, + 0x9c, 0x88, 0x7, 0x7b, 0x81, 0x0, 0x4, 0x6a, + 0x16, 0x39, 0xb, 0x2c, 0x10, 0x25, 0xa, 0x23, + 0x60, 0xc, 0x6, 0xc1, 0x10, 0xa, 0x22, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+690D "植" */ + 0x0, 0x6, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, + 0x3, 0x55, 0xc5, 0x58, 0x90, 0x2, 0x2c, 0x73, + 0x0, 0xb0, 0x0, 0x0, 0x4, 0x4d, 0x31, 0x75, + 0xc5, 0x5a, 0x0, 0x0, 0x4d, 0x20, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0x9c, 0xa4, 0xb5, 0x55, 0x5b, + 0x0, 0x0, 0x9c, 0x13, 0xb0, 0x0, 0xb, 0x0, + 0x5, 0x3c, 0x0, 0xb5, 0x55, 0x5b, 0x0, 0x5, + 0xc, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xc, + 0x0, 0xb5, 0x55, 0x5b, 0x0, 0x0, 0xc, 0x0, + 0xb0, 0x0, 0xb, 0x50, 0x0, 0xc, 0x36, 0x65, + 0x55, 0x56, 0x62, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+691C "検" */ + 0x0, 0x4, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0xb9, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x3, 0xb3, 0x50, 0x0, 0x1, 0x1c, 0x43, + 0x1a, 0x0, 0x6b, 0x30, 0x4, 0x4d, 0x34, 0x76, + 0x55, 0x87, 0xb3, 0x0, 0x4e, 0x22, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x9d, 0xa5, 0xa5, 0x5c, 0x5c, + 0x30, 0x0, 0x9c, 0x14, 0xb0, 0xa, 0xb, 0x0, + 0x5, 0x3c, 0x0, 0xb5, 0x6b, 0x5c, 0x0, 0x5, + 0xc, 0x0, 0x70, 0x6b, 0x14, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc1, 0xa0, 0x0, 0x0, 0xd, 0x0, + 0x9, 0x40, 0x4c, 0x30, 0x0, 0xd, 0x2, 0x72, + 0x0, 0x5, 0xc3, 0x0, 0x2, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+695A "楚" */ + 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0xc, 0x0, 0x0, 0x2, 0x55, + 0xc6, 0x83, 0x5c, 0x59, 0x30, 0x0, 0x4, 0xf2, + 0x0, 0x7e, 0x0, 0x0, 0x0, 0xb, 0xc6, 0x72, + 0x9b, 0x77, 0x0, 0x0, 0x82, 0xc0, 0x48, 0xb, + 0xa, 0x20, 0x5, 0x20, 0xb0, 0x50, 0xb, 0x0, + 0x0, 0x1, 0x65, 0x55, 0x58, 0x55, 0x5e, 0x30, + 0x0, 0x0, 0x60, 0xb, 0x0, 0x42, 0x0, 0x0, + 0x5, 0xb0, 0xc, 0x55, 0x86, 0x0, 0x0, 0xc, + 0x70, 0xb, 0x0, 0x0, 0x0, 0x0, 0x73, 0x8, + 0x6b, 0x0, 0x0, 0x0, 0x4, 0x30, 0x0, 0x39, + 0xbc, 0xce, 0xb1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+696D "業" */ + 0x0, 0x0, 0x4, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x76, 0xc, 0x10, 0xc0, 0xb2, 0x0, 0x0, 0xa, + 0x4b, 0x0, 0xb7, 0x30, 0x0, 0x4, 0x56, 0x6c, + 0x55, 0xd5, 0x56, 0xb0, 0x1, 0x0, 0x63, 0x0, + 0x72, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x60, + 0x35, 0x0, 0x0, 0x45, 0x55, 0xa7, 0x55, 0x55, + 0x0, 0x0, 0x15, 0x55, 0xb7, 0x55, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x82, 0x0, 0x3, 0x10, 0x4, + 0x55, 0x58, 0xe9, 0x65, 0x56, 0x50, 0x0, 0x0, + 0x3b, 0xa3, 0x92, 0x0, 0x0, 0x0, 0x7, 0x80, + 0x92, 0xa, 0xa5, 0x20, 0x4, 0x72, 0x0, 0x93, + 0x0, 0x4b, 0xc2, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+6975 "極" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0xb, + 0x0, 0x55, 0x55, 0xb8, 0x0, 0x3, 0x3c, 0x71, + 0x0, 0x18, 0x20, 0x0, 0x2, 0x2c, 0x26, 0x58, + 0x3a, 0x55, 0x81, 0x0, 0x3d, 0x38, 0x1a, 0x19, + 0x1, 0xb0, 0x0, 0x8c, 0x9d, 0x1a, 0x19, 0x56, + 0x60, 0x0, 0xab, 0x1c, 0x1a, 0x19, 0xe, 0x10, + 0x4, 0x5b, 0x8, 0x6c, 0x19, 0x1a, 0x90, 0x7, + 0xb, 0x9, 0x18, 0x19, 0x60, 0xb0, 0x10, 0xb, + 0x4, 0x3, 0x3a, 0x30, 0x0, 0x0, 0xc, 0x0, + 0x2, 0xc5, 0x0, 0x0, 0x0, 0xc, 0x25, 0x55, + 0x55, 0x55, 0xd2, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+697D "楽" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x2, 0x71, + 0x1b, 0x66, 0x5b, 0x6, 0x80, 0x0, 0x3c, 0xb, + 0x0, 0x1a, 0x37, 0x0, 0x0, 0x1, 0xc, 0x55, + 0x6c, 0x20, 0x0, 0x0, 0x16, 0x4b, 0x0, 0x1b, + 0x7b, 0x40, 0x6, 0xa1, 0xc, 0x55, 0x6a, 0x2, + 0xa0, 0x0, 0x0, 0x5, 0xa, 0x14, 0x0, 0x20, + 0x5, 0x65, 0x55, 0x9d, 0x75, 0x57, 0x80, 0x0, + 0x0, 0x6, 0xbc, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x69, 0xc, 0xa, 0x30, 0x0, 0x0, 0x18, 0x50, + 0xc, 0x1, 0xbb, 0x61, 0x5, 0x50, 0x0, 0xd, + 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, + + /* U+6982 "概" */ + 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x5, 0x57, 0x24, 0x55, 0x93, 0x0, 0x9, + 0xa, 0x9, 0x0, 0xb, 0x0, 0x2, 0x3b, 0x7a, + 0x9, 0x8, 0x2a, 0x0, 0x2, 0x4a, 0x2a, 0x5b, + 0xb, 0x19, 0x0, 0x0, 0x6c, 0x2a, 0x9, 0x2a, + 0x28, 0x0, 0x0, 0xaa, 0xcc, 0x9, 0x79, 0x8a, + 0x95, 0x0, 0x99, 0x3c, 0x57, 0x0, 0x88, 0x0, + 0x6, 0x39, 0xa, 0x15, 0x0, 0xcb, 0x0, 0x6, + 0x19, 0xa, 0xa, 0x55, 0x7a, 0x0, 0x10, 0x19, + 0xb, 0x92, 0x4a, 0xa, 0x3, 0x0, 0x1a, 0x6, + 0x10, 0x92, 0xa, 0x6, 0x0, 0x1a, 0x0, 0x16, + 0x10, 0xa, 0xa9, 0x0, 0x3, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+69CB "構" */ + 0x0, 0x20, 0x0, 0x4, 0x0, 0x30, 0x0, 0x0, + 0x84, 0x0, 0xc, 0x0, 0xc1, 0x20, 0x0, 0x82, + 0x15, 0x5c, 0x55, 0xc6, 0x60, 0x0, 0x82, 0x44, + 0x5c, 0x55, 0xc9, 0x30, 0x25, 0xb6, 0x51, 0xa, + 0x0, 0xa0, 0x40, 0x0, 0xd9, 0x55, 0x56, 0x97, + 0x65, 0x60, 0x1, 0xf4, 0xa5, 0x55, 0xa8, 0x58, + 0x20, 0x6, 0xc2, 0x38, 0x20, 0x74, 0xa, 0x0, + 0x8, 0x82, 0x8, 0x65, 0xa8, 0x5b, 0x0, 0x32, + 0x82, 0x8, 0x20, 0x74, 0xa, 0x50, 0x10, 0x82, + 0x5b, 0x65, 0x55, 0x5b, 0x61, 0x0, 0x82, 0x8, + 0x20, 0x0, 0xa, 0x0, 0x0, 0x92, 0x9, 0x20, + 0x2, 0x8d, 0x0, 0x0, 0x10, 0x2, 0x0, 0x0, + 0x1, 0x0, + + /* U+69D8 "様" */ + 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x0, 0x0, + 0xc, 0x0, 0x3, 0xb0, 0xb, 0x10, 0x0, 0xa, + 0x0, 0x45, 0xb5, 0x86, 0xb2, 0x0, 0xa, 0x23, + 0x0, 0xb, 0x0, 0x0, 0x5, 0x6c, 0x54, 0x25, + 0x5c, 0x57, 0x70, 0x0, 0x4d, 0x50, 0x0, 0xb, + 0x0, 0x10, 0x0, 0x8a, 0xa4, 0x65, 0x5b, 0x55, + 0x94, 0x0, 0xaa, 0x20, 0x0, 0xb, 0x20, 0x80, + 0x4, 0x4a, 0x4, 0x59, 0x7b, 0x47, 0x50, 0x6, + 0xa, 0x0, 0xa, 0x1b, 0x72, 0x0, 0x0, 0xa, + 0x0, 0x47, 0xb, 0xb, 0x0, 0x0, 0xb, 0x1, + 0x80, 0xb, 0x5, 0xc3, 0x0, 0xb, 0x25, 0x4, + 0xac, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+6A02 "樂" */ + 0x0, 0x21, 0x0, 0x32, 0x0, 0x30, 0x0, 0x0, + 0x86, 0x1, 0x72, 0x20, 0xa5, 0x0, 0x0, 0xa2, + 0x3a, 0x55, 0xc1, 0x83, 0x20, 0x7, 0x38, 0x7a, + 0x0, 0xa7, 0x2a, 0x40, 0x9, 0x7a, 0xa, 0x55, + 0xa9, 0x78, 0x0, 0x0, 0x73, 0xa, 0x0, 0xa0, + 0x83, 0x0, 0x6, 0x75, 0xaa, 0x55, 0xa6, 0x55, + 0xb0, 0x8, 0x62, 0xa4, 0x45, 0x3a, 0x62, 0x90, + 0x6, 0x55, 0x55, 0xaa, 0x55, 0x5a, 0x70, 0x0, + 0x0, 0xb, 0xb7, 0x60, 0x0, 0x0, 0x0, 0x1, + 0xa4, 0x66, 0x48, 0x0, 0x0, 0x0, 0x58, 0x10, + 0x66, 0x4, 0xd8, 0x50, 0x15, 0x20, 0x0, 0x66, + 0x0, 0x17, 0x70, 0x0, 0x0, 0x0, 0x21, 0x0, + 0x0, 0x0, + + /* U+6A19 "標" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x3, 0x65, 0x75, 0x75, 0xa2, 0x0, 0xa, + 0x0, 0x0, 0x90, 0x90, 0x0, 0x5, 0x5c, 0x86, + 0xa5, 0xb5, 0xb5, 0xa0, 0x0, 0x2b, 0x0, 0xa0, + 0x90, 0x92, 0x80, 0x0, 0x7d, 0x60, 0xc5, 0xb5, + 0xb6, 0x80, 0x0, 0xaa, 0x94, 0x70, 0x0, 0x2, + 0x20, 0x3, 0x5a, 0x10, 0x55, 0x55, 0x58, 0x20, + 0x6, 0xa, 0x4, 0x55, 0x55, 0x55, 0x85, 0x12, + 0xa, 0x1, 0x23, 0xb, 0x10, 0x0, 0x0, 0xb, + 0x0, 0xb5, 0xb, 0x38, 0x0, 0x0, 0xb, 0x8, + 0x20, 0xb, 0x4, 0xb0, 0x0, 0xb, 0x40, 0x5, + 0xb8, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+6A21 "模" */ + 0x0, 0x4, 0x0, 0x3, 0x0, 0x40, 0x0, 0x0, + 0xd, 0x0, 0xb, 0x20, 0xd0, 0x10, 0x0, 0xb, + 0x4, 0x5c, 0x55, 0xc5, 0xa1, 0x4, 0x4c, 0x85, + 0xa, 0x0, 0xa0, 0x0, 0x1, 0x3c, 0x10, 0x95, + 0x55, 0x5b, 0x10, 0x0, 0x6d, 0x20, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0xab, 0xa4, 0xb5, 0x55, 0x5c, + 0x0, 0x1, 0x7b, 0x16, 0xb5, 0x55, 0x5c, 0x0, + 0x6, 0xb, 0x0, 0x60, 0x93, 0x5, 0x0, 0x12, + 0xb, 0x16, 0x55, 0xc7, 0x55, 0xb2, 0x0, 0xb, + 0x0, 0x1, 0xb4, 0x20, 0x0, 0x0, 0xc, 0x0, + 0xa, 0x30, 0xa5, 0x0, 0x0, 0xc, 0x2, 0x83, + 0x0, 0xa, 0xd3, 0x0, 0x2, 0x22, 0x0, 0x0, + 0x0, 0x0, + + /* U+6A23 "樣" */ + 0x0, 0x4, 0x0, 0x3, 0x0, 0x32, 0x0, 0x0, + 0xc, 0x0, 0x5, 0x80, 0x94, 0x0, 0x0, 0xb, + 0x2, 0x55, 0x7a, 0x57, 0x50, 0x5, 0x5c, 0x76, + 0x45, 0x5c, 0x59, 0x20, 0x0, 0x2c, 0x0, 0x0, + 0xa, 0x0, 0x10, 0x0, 0x6d, 0x53, 0x55, 0x69, + 0x55, 0x92, 0x0, 0xab, 0x85, 0x0, 0x3c, 0x0, + 0x0, 0x2, 0x7b, 0x13, 0x55, 0x5a, 0x0, 0x40, + 0x7, 0xb, 0x0, 0x2, 0xc, 0x19, 0x60, 0x12, + 0xb, 0x5, 0x5e, 0x5b, 0x91, 0x0, 0x0, 0xb, + 0x0, 0x79, 0xb, 0x38, 0x0, 0x0, 0xc, 0x4, + 0x90, 0xb, 0x7, 0xa2, 0x0, 0xc, 0x25, 0x5, + 0xbc, 0x0, 0x51, 0x0, 0x2, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+6A2A "横" */ + 0x0, 0x13, 0x0, 0x2, 0x1, 0x20, 0x0, 0x0, + 0x1b, 0x0, 0xa, 0x2, 0xb0, 0x0, 0x0, 0x19, + 0x3, 0x5b, 0x56, 0xb7, 0x50, 0x5, 0x6b, 0xa4, + 0x9, 0x2, 0x90, 0x0, 0x0, 0x59, 0x16, 0x58, + 0x86, 0x85, 0x91, 0x0, 0x8b, 0x0, 0x20, 0xa0, + 0x3, 0x0, 0x0, 0xba, 0xb2, 0xc4, 0xb5, 0x5c, + 0x20, 0x2, 0x89, 0x32, 0xa0, 0xa0, 0xa, 0x0, + 0x7, 0x29, 0x0, 0xc5, 0xb5, 0x5c, 0x0, 0x5, + 0x19, 0x0, 0xa0, 0xa0, 0xa, 0x0, 0x0, 0x19, + 0x0, 0xb8, 0x56, 0x57, 0x0, 0x0, 0x1a, 0x0, + 0x5b, 0x10, 0x76, 0x0, 0x0, 0x2a, 0x6, 0x60, + 0x0, 0x7, 0x80, 0x0, 0x13, 0x20, 0x0, 0x0, + 0x0, 0x30, + + /* U+6A39 "樹" */ + 0x0, 0x31, 0x0, 0x21, 0x0, 0x3, 0x0, 0x0, + 0x92, 0x0, 0x67, 0x0, 0xb, 0x0, 0x0, 0x92, + 0x25, 0x99, 0x83, 0xa, 0x0, 0x25, 0xb8, 0x70, + 0x66, 0x0, 0xa, 0x40, 0x0, 0xb2, 0x5, 0x77, + 0x84, 0x5c, 0x50, 0x0, 0xe4, 0x6, 0x55, 0x80, + 0xa, 0x0, 0x3, 0xf8, 0x7a, 0x0, 0xa6, 0x2a, + 0x0, 0x8, 0xa2, 0x4b, 0x55, 0xa1, 0xba, 0x0, + 0x16, 0x92, 0x6, 0x0, 0x90, 0x2a, 0x0, 0x40, + 0x92, 0x7, 0x13, 0x70, 0xa, 0x0, 0x0, 0x92, + 0x3, 0x47, 0x32, 0xa, 0x0, 0x0, 0x92, 0x6a, + 0x85, 0x10, 0xb, 0x0, 0x0, 0x92, 0x20, 0x0, + 0x2, 0xbb, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6A4B "橋" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, + 0x94, 0x3, 0x57, 0xaa, 0x85, 0x0, 0x0, 0x92, + 0x0, 0x0, 0xc0, 0x1, 0x0, 0x25, 0xb8, 0x74, + 0x5b, 0x75, 0x86, 0x40, 0x0, 0xb2, 0x0, 0x76, + 0x0, 0x87, 0x10, 0x0, 0xe5, 0x17, 0x4b, 0x55, + 0xc5, 0xa1, 0x3, 0xf7, 0x80, 0xb, 0x55, 0xb0, + 0x0, 0x8, 0xa2, 0x33, 0x13, 0x0, 0x41, 0x40, + 0x17, 0x92, 0xc, 0x45, 0x44, 0x55, 0xb0, 0x50, + 0x92, 0xb, 0x9, 0x55, 0xc1, 0x90, 0x0, 0x92, + 0xb, 0x9, 0x55, 0xa1, 0x90, 0x0, 0x92, 0xb, + 0x4, 0x0, 0x31, 0x90, 0x0, 0x92, 0xb, 0x0, + 0x0, 0x6c, 0x60, 0x0, 0x10, 0x1, 0x0, 0x0, + 0x1, 0x0, + + /* U+6A5F "機" */ + 0x0, 0x41, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0xb0, 0xb2, 0x68, 0x0, 0x0, 0xa1, + 0x4, 0x36, 0xb0, 0x83, 0x20, 0x25, 0xc9, 0x6b, + 0x78, 0xb9, 0x8b, 0x40, 0x0, 0xc1, 0x1, 0x71, + 0xb1, 0x46, 0x0, 0x0, 0xf3, 0x5, 0x29, 0xb2, + 0x65, 0x60, 0x4, 0xf8, 0x6a, 0x57, 0xb7, 0x92, + 0x80, 0x9, 0xb1, 0x40, 0xb0, 0x91, 0x56, 0x20, + 0x26, 0xa1, 0x25, 0xc5, 0xa7, 0x57, 0x80, 0x40, + 0xa1, 0x0, 0xc0, 0x47, 0x2c, 0x0, 0x0, 0xa1, + 0x5, 0x5a, 0xb, 0xc2, 0x30, 0x0, 0xa1, 0x18, + 0x1, 0x78, 0xc4, 0x70, 0x0, 0xa3, 0x50, 0x5, + 0x10, 0x18, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B21 "次" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x2, + 0x40, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, 0xa6, + 0x10, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x38, 0x40, + 0x88, 0x55, 0x57, 0x70, 0x0, 0x0, 0x50, 0xb0, + 0x40, 0xa, 0x60, 0x0, 0x5, 0x17, 0x20, 0xe2, + 0x24, 0x0, 0x0, 0x7, 0x25, 0x1, 0xb3, 0x0, + 0x0, 0x0, 0x44, 0x10, 0x3, 0x85, 0x0, 0x0, + 0x6, 0xd0, 0x0, 0x7, 0x47, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0xb, 0x4, 0x50, 0x0, 0x0, 0xe0, + 0x0, 0x74, 0x0, 0xb1, 0x0, 0x0, 0xf0, 0x5, + 0x50, 0x0, 0x3d, 0x30, 0x0, 0x21, 0x62, 0x0, + 0x0, 0x4, 0xb2, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B32 "欲" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x55, 0x15, 0x0, 0x78, 0x0, 0x0, 0x0, 0xa1, + 0x7, 0x90, 0xb1, 0x0, 0x0, 0x7, 0x13, 0x50, + 0x40, 0xc5, 0x55, 0xa0, 0x10, 0xa, 0x70, 0x6, + 0x30, 0x5, 0x60, 0x0, 0x38, 0x3c, 0x46, 0xe, + 0x4, 0x0, 0x1, 0x90, 0x2, 0x80, 0x1c, 0x0, + 0x0, 0x6, 0x30, 0x4, 0x0, 0x39, 0x30, 0x0, + 0x10, 0xc5, 0x5d, 0x0, 0x65, 0x60, 0x0, 0x0, + 0xa0, 0xb, 0x0, 0xb0, 0x90, 0x0, 0x0, 0xa0, + 0xb, 0x3, 0x80, 0x74, 0x0, 0x0, 0xc5, 0x5c, + 0x19, 0x0, 0xd, 0x30, 0x0, 0x60, 0x4, 0x60, + 0x0, 0x4, 0xc2, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B4C "歌" */ + 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x16, + 0x55, 0x56, 0xa3, 0x79, 0x0, 0x0, 0x1, 0x0, + 0x18, 0x30, 0xb1, 0x0, 0x0, 0x4, 0xa5, 0xa8, + 0x31, 0xc5, 0x56, 0x70, 0x4, 0xa5, 0xa8, 0x36, + 0x14, 0x7, 0x40, 0x3, 0x40, 0x47, 0x43, 0xe, + 0x2, 0x0, 0x26, 0x55, 0x58, 0xa2, 0xf, 0x0, + 0x0, 0x2, 0x0, 0x3a, 0x10, 0x2a, 0x40, 0x0, + 0xb, 0x65, 0xba, 0x10, 0x67, 0x70, 0x0, 0xb, + 0x10, 0xaa, 0x10, 0x91, 0x80, 0x0, 0xb, 0x65, + 0x7a, 0x11, 0x90, 0x57, 0x0, 0x1, 0x0, 0x3b, + 0x18, 0x10, 0xd, 0x40, 0x0, 0x0, 0x4b, 0x62, + 0x0, 0x3, 0x90, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B50 "歐" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x9, + 0x55, 0x55, 0xa0, 0xc2, 0x0, 0x0, 0xa, 0x3, + 0x12, 0x30, 0xb0, 0x0, 0x0, 0xa, 0xa, 0x48, + 0x65, 0x95, 0x57, 0x80, 0xa, 0x9, 0x5, 0x48, + 0x5, 0x8, 0x20, 0xa, 0xa, 0x58, 0x53, 0xe, + 0x12, 0x0, 0xa, 0x1, 0x0, 0x0, 0xd, 0x10, + 0x0, 0xa, 0x87, 0x9a, 0x96, 0xb, 0x40, 0x0, + 0xa, 0x83, 0x79, 0x63, 0x39, 0x70, 0x0, 0xa, + 0x87, 0x7a, 0x93, 0x75, 0x80, 0x0, 0xa, 0x61, + 0x16, 0x21, 0xb0, 0x49, 0x0, 0xb, 0x0, 0x4, + 0x18, 0x30, 0xc, 0x70, 0x8, 0x55, 0x55, 0x93, + 0x0, 0x1, 0xb2, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B61 "歡" */ + 0x0, 0x10, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x48, 0xc, 0x31, 0x79, 0x0, 0x0, 0x6, 0x89, + 0x5c, 0x52, 0x92, 0x0, 0x0, 0x6, 0x58, 0x56, + 0x71, 0xc5, 0x57, 0x80, 0xb, 0xb, 0x91, 0xa2, + 0x62, 0x9, 0x30, 0x8, 0x86, 0x85, 0x66, 0xe, + 0x12, 0x0, 0x0, 0xc1, 0x80, 0x31, 0x1d, 0x0, + 0x0, 0x7, 0xa5, 0xb5, 0x62, 0x2b, 0x20, 0x0, + 0x27, 0xa4, 0xc4, 0x70, 0x56, 0x60, 0x0, 0x2, + 0xa5, 0xc5, 0x70, 0x92, 0x90, 0x0, 0x2, 0x70, + 0xb0, 0x10, 0xa0, 0x57, 0x0, 0x3, 0xa5, 0x95, + 0x99, 0x20, 0xc, 0x60, 0x3, 0x60, 0x0, 0x62, + 0x0, 0x2, 0xb2, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B62 "止" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0xc, + 0x0, 0x3, 0x0, 0x0, 0xc, 0x0, 0xd, 0x55, + 0x59, 0x20, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x15, 0x5d, 0x55, + 0x5d, 0x55, 0x5a, 0xb0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6B63 "正" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x55, 0x55, 0x55, 0x55, 0x5b, 0x90, 0x0, 0x10, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0xc, 0x0, + 0x1, 0x0, 0x0, 0xb, 0x0, 0xd, 0x55, 0x7a, + 0x0, 0x0, 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0xc, 0x0, 0x6, 0x50, 0x17, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x50, + + /* U+6B64 "此" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x92, + 0x0, 0xb0, 0x1, 0x20, 0x0, 0xd0, 0x92, 0x0, + 0xb0, 0x1c, 0x90, 0x0, 0xb0, 0x96, 0x86, 0xb3, + 0x93, 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0xb0, 0x92, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0xb0, 0x92, 0x2, 0xb0, 0x0, 0x30, 0x0, 0xb0, + 0xa9, 0x62, 0xb0, 0x0, 0x60, 0x16, 0xea, 0x50, + 0x0, 0xc0, 0x0, 0xc2, 0x1a, 0x30, 0x0, 0x0, + 0x5a, 0xaa, 0x91, + + /* U+6B65 "步" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x20, 0xd, 0x55, 0x6b, 0x0, 0x0, 0xc, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc, + 0x0, 0x0, 0x20, 0x7, 0x5b, 0x55, 0x5b, 0x55, + 0x57, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xa0, 0xc, 0x0, 0xa, 0x30, + 0x0, 0xb, 0x30, 0xc, 0x0, 0x9a, 0x0, 0x0, + 0x75, 0x0, 0xc, 0xa, 0x80, 0x0, 0x4, 0x50, + 0x0, 0x8, 0xb5, 0x0, 0x0, 0x2, 0x0, 0x2, + 0x89, 0x10, 0x0, 0x0, 0x0, 0x25, 0x66, 0x10, + 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B69 "歩" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x2b, 0x0, + 0xc0, 0x2, 0x40, 0x0, 0x2, 0xa0, 0xc, 0x55, + 0x54, 0x0, 0x0, 0x1a, 0x0, 0xc0, 0x0, 0x4, + 0x5, 0x65, 0x85, 0x5b, 0x55, 0x56, 0x92, 0x0, + 0x1, 0x0, 0xe0, 0x44, 0x0, 0x0, 0x2, 0xe2, + 0xc, 0x0, 0x5b, 0x30, 0x0, 0xb3, 0x0, 0xc0, + 0xa, 0x8d, 0x0, 0x82, 0x0, 0xd, 0xb, 0xb2, + 0x20, 0x20, 0x0, 0x0, 0x7c, 0x60, 0x0, 0x0, + 0x0, 0x3, 0x98, 0x10, 0x0, 0x0, 0x1, 0x57, + 0x50, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6B6F "歯" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x50, 0xd, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x80, 0xd, 0x55, 0xb1, 0x0, 0x0, 0x4, 0x80, + 0xc, 0x0, 0x0, 0x0, 0x4, 0x57, 0xa5, 0x5d, + 0x55, 0x5b, 0x80, 0x1, 0x0, 0x10, 0x8, 0x2, + 0x0, 0x0, 0x0, 0xb0, 0x57, 0xb, 0xb, 0x27, + 0x10, 0x0, 0xb0, 0x7, 0xb, 0x43, 0x2c, 0x0, + 0x0, 0xb3, 0x65, 0xae, 0x76, 0x7c, 0x0, 0x0, + 0xb0, 0x5, 0x8b, 0x87, 0xc, 0x0, 0x0, 0xb0, + 0x47, 0xb, 0x9, 0x9c, 0x0, 0x0, 0xb4, 0x40, + 0xa, 0x0, 0x2c, 0x0, 0x2, 0xa5, 0x55, 0x55, + 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B72 "歲" */ + 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x40, 0x66, 0x0, 0x50, 0x0, 0x0, 0x4, + 0x60, 0x68, 0x55, 0x50, 0x10, 0x6, 0x57, 0x85, + 0x88, 0x55, 0x57, 0xa0, 0x0, 0x0, 0x0, 0x6, + 0x63, 0x90, 0x0, 0x0, 0xb5, 0x55, 0x58, 0x95, + 0x79, 0x50, 0x0, 0xc0, 0x0, 0x21, 0x90, 0x24, + 0x0, 0x0, 0xc3, 0x6a, 0x72, 0xb0, 0x89, 0x0, + 0x0, 0xc2, 0x5a, 0x23, 0xa3, 0xc0, 0x0, 0x2, + 0xa7, 0x2a, 0xb6, 0x6e, 0x30, 0x0, 0x4, 0x64, + 0xf, 0x60, 0xad, 0x20, 0x40, 0x8, 0x0, 0x95, + 0x1a, 0x42, 0xd4, 0x80, 0x15, 0x47, 0x24, 0x71, + 0x0, 0x2c, 0xf0, 0x10, 0x10, 0x20, 0x0, 0x0, + 0x0, 0x10, + + /* U+6B73 "歳" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x50, 0x58, 0x0, 0x60, 0x0, 0x0, 0x4, + 0x70, 0x49, 0x55, 0x51, 0x10, 0x6, 0x57, 0x85, + 0x78, 0x55, 0x58, 0xa0, 0x0, 0x0, 0x0, 0x5, + 0x83, 0xa0, 0x0, 0x0, 0xa5, 0x55, 0x57, 0xa5, + 0x78, 0x60, 0x0, 0xb0, 0x0, 0x13, 0xa0, 0x14, + 0x0, 0x0, 0xb6, 0x5b, 0x54, 0xb0, 0x7b, 0x0, + 0x0, 0xa2, 0x3a, 0x40, 0x94, 0xd1, 0x0, 0x1, + 0x98, 0x3a, 0x57, 0x4f, 0x30, 0x0, 0x4, 0x84, + 0xa, 0x4, 0x9d, 0x20, 0x40, 0x7, 0x12, 0xa9, + 0x19, 0x43, 0xd3, 0x70, 0x6, 0x0, 0x4, 0x60, + 0x0, 0x2c, 0xe0, 0x10, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x20, + + /* U+6B77 "歷" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, + 0x95, 0x55, 0x55, 0x55, 0x5b, 0x50, 0x1, 0xa0, + 0x15, 0xc2, 0x1, 0x78, 0x0, 0x1, 0xa3, 0x5a, + 0x0, 0x4c, 0x20, 0x0, 0x1, 0xa5, 0x7b, 0xa3, + 0x6c, 0x58, 0x50, 0x1, 0xa0, 0xab, 0x20, 0x5e, + 0x60, 0x0, 0x2, 0x92, 0x99, 0xa1, 0x8a, 0x2a, + 0x0, 0x3, 0x87, 0x29, 0x6, 0xa, 0x5, 0x70, + 0x4, 0x70, 0x15, 0x12, 0x74, 0x0, 0x0, 0x6, + 0x30, 0x51, 0x2, 0x80, 0x50, 0x0, 0x8, 0x0, + 0xa0, 0x2, 0xa5, 0x52, 0x0, 0x7, 0x0, 0xa0, + 0x2, 0x80, 0x0, 0x0, 0x42, 0x55, 0xc5, 0x56, + 0xa5, 0x59, 0xb0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B7B "死" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x55, 0x55, 0x55, 0x55, 0x5a, 0xc0, 0x1, 0x3, + 0xa0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x7, 0x60, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x40, + 0xc0, 0x4, 0x60, 0x0, 0x1c, 0x56, 0xe1, 0xc0, + 0x2c, 0x40, 0x0, 0x85, 0x5, 0x80, 0xc3, 0x80, + 0x0, 0x1, 0x88, 0x3a, 0x20, 0xc3, 0x0, 0x0, + 0x7, 0x3, 0x6c, 0x0, 0xc0, 0x0, 0x0, 0x10, + 0x0, 0x94, 0x0, 0xc0, 0x0, 0x40, 0x0, 0x4, + 0x80, 0x0, 0xc0, 0x0, 0x70, 0x0, 0x38, 0x0, + 0x0, 0xc2, 0x11, 0xd2, 0x4, 0x50, 0x0, 0x0, + 0x59, 0x99, 0x70, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B8A "殊" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x6, 0x2c, 0x0, 0x0, 0x5, 0x99, + 0x55, 0x3a, 0x2a, 0x1, 0x0, 0x0, 0x84, 0x0, + 0x67, 0x6b, 0x59, 0x40, 0x0, 0xb6, 0x75, 0x80, + 0x2a, 0x0, 0x0, 0x0, 0xb0, 0x77, 0x20, 0x2a, + 0x0, 0x40, 0x3, 0x90, 0xa4, 0x55, 0xbc, 0x65, + 0x92, 0x7, 0x57, 0xc0, 0x2, 0xda, 0x60, 0x0, + 0x13, 0x5, 0x90, 0xa, 0x4a, 0x80, 0x0, 0x0, + 0x8, 0x20, 0x56, 0x2a, 0x38, 0x0, 0x0, 0x19, + 0x3, 0x80, 0x2a, 0xa, 0x80, 0x0, 0x71, 0x26, + 0x0, 0x2a, 0x1, 0xb4, 0x5, 0x10, 0x20, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B8B "残" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x0, 0xc2, 0x60, 0x0, 0x5, 0x99, + 0x55, 0x10, 0xc0, 0x69, 0x0, 0x0, 0x83, 0x0, + 0x0, 0xc0, 0x6, 0x0, 0x0, 0xa0, 0x4, 0x35, + 0xd5, 0x57, 0x40, 0x0, 0xb5, 0x5d, 0x10, 0xb0, + 0x0, 0x0, 0x5, 0x80, 0x38, 0x0, 0xb6, 0x57, + 0x60, 0x8, 0x49, 0x64, 0x54, 0x94, 0x7, 0x10, + 0x21, 0x4, 0xa0, 0x0, 0x57, 0x4b, 0x0, 0x0, + 0x2, 0x80, 0x0, 0x1d, 0xb0, 0x0, 0x0, 0x9, + 0x0, 0x0, 0x4e, 0x50, 0x12, 0x0, 0x63, 0x0, + 0x18, 0x60, 0xc5, 0x60, 0x4, 0x30, 0x4, 0x50, + 0x0, 0x1b, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x30, + + /* U+6BB5 "段" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x43, 0x8b, 0x27, 0x55, 0x91, 0x0, 0x0, 0xc2, + 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, + 0xc, 0x0, 0xb0, 0x0, 0x0, 0xc5, 0x68, 0xa, + 0x0, 0xc0, 0x10, 0x0, 0xb0, 0x0, 0x72, 0x0, + 0x59, 0x80, 0x0, 0xc5, 0x68, 0x55, 0x44, 0x78, + 0x0, 0x0, 0xb0, 0x0, 0x6, 0x0, 0xa3, 0x0, + 0x0, 0xb0, 0x2, 0x24, 0x42, 0xb0, 0x0, 0x14, + 0xd9, 0x73, 0x0, 0xbb, 0x30, 0x0, 0x19, 0xc0, + 0x0, 0x0, 0xbd, 0x10, 0x0, 0x0, 0xb0, 0x0, + 0x3a, 0x33, 0xd6, 0x0, 0x0, 0xb0, 0x35, 0x40, + 0x0, 0x1a, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6BCD "母" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x65, 0x55, 0x55, 0xb5, 0x0, 0x0, 0xc, + 0x11, 0x50, 0x0, 0xa2, 0x0, 0x0, 0xd, 0x0, + 0x87, 0x0, 0xb1, 0x0, 0x0, 0xd, 0x0, 0x17, + 0x0, 0xc0, 0x0, 0x15, 0x5d, 0x55, 0x55, 0x55, + 0xe7, 0xc0, 0x0, 0x2a, 0x2, 0x30, 0x0, 0xd0, + 0x0, 0x0, 0x48, 0x0, 0xb5, 0x0, 0xd0, 0x0, + 0x0, 0x67, 0x0, 0x49, 0x1, 0xc0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x2, 0xb3, 0x60, 0x0, 0x86, + 0x55, 0x55, 0x57, 0xb5, 0x50, 0x0, 0x0, 0x0, + 0x2, 0x7, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xbf, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+6BCE "毎" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x6, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x55, 0x56, 0x20, 0x0, 0x84, 0x0, + 0x0, 0x0, 0x30, 0x0, 0x4, 0x26, 0x85, 0x5c, + 0x55, 0xd3, 0x0, 0x0, 0x8, 0x30, 0x1a, 0x0, + 0xc0, 0x0, 0x0, 0xa, 0x10, 0x38, 0x0, 0xc0, + 0x50, 0x16, 0x5d, 0x55, 0x89, 0x55, 0xd6, 0x71, + 0x0, 0xc, 0x0, 0x75, 0x0, 0xc0, 0x0, 0x0, + 0xb, 0x0, 0x83, 0x0, 0xc0, 0x0, 0x0, 0x5b, + 0x55, 0x96, 0x55, 0xd8, 0x80, 0x0, 0x1, 0x0, + 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x8d, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+6BCF "每" */ + 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x5, 0x0, 0x0, 0xc, + 0x65, 0x55, 0x55, 0x58, 0x30, 0x0, 0x85, 0x0, + 0x0, 0x0, 0x30, 0x0, 0x5, 0x56, 0x95, 0x75, + 0x55, 0xd3, 0x0, 0x12, 0x7, 0x40, 0x87, 0x0, + 0xc0, 0x0, 0x0, 0x9, 0x30, 0x8, 0x0, 0xc0, + 0x60, 0x16, 0x5c, 0x66, 0x55, 0x55, 0xd5, 0x71, + 0x0, 0xc, 0x0, 0xa4, 0x0, 0xd0, 0x0, 0x0, + 0xc, 0x0, 0x2a, 0x0, 0xc0, 0x0, 0x0, 0x3c, + 0x55, 0x55, 0x55, 0xd8, 0xa0, 0x0, 0x1, 0x0, + 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x8d, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+6BD4 "比" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, + 0xc, 0x30, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0xc, 0x30, + 0xc0, 0x0, 0xc, 0x0, 0xb7, 0x0, 0xc5, 0x5a, + 0x3c, 0x9, 0x30, 0x0, 0xc0, 0x0, 0xc, 0x60, + 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0xc, 0x0, 0x0, 0x40, 0xc0, 0x15, 0x2c, 0x0, + 0x0, 0x60, 0xdb, 0x70, 0xc, 0x31, 0x14, 0xc0, + 0x62, 0x0, 0x4, 0xaa, 0xaa, 0x60, + + /* U+6BDB "毛" */ + 0x0, 0x0, 0x0, 0x1, 0x5c, 0x30, 0x0, 0x0, + 0x14, 0x57, 0xb9, 0x74, 0x20, 0x0, 0x0, 0x20, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x50, 0x0, 0x0, 0x24, 0x55, 0xd5, + 0x55, 0x62, 0x0, 0x0, 0x31, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x1, 0x29, + 0x80, 0x4, 0x55, 0x55, 0xd5, 0x54, 0x21, 0x0, + 0x1, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x50, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0xbc, 0xbb, 0xbc, 0xc1, + + /* U+6C0F "氏" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x8e, 0x80, 0x0, 0xa5, 0x56, 0xd5, 0x31, + 0x0, 0x0, 0xb1, 0x0, 0xb1, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xb5, 0x55, + 0xb7, 0x55, 0x6e, 0x30, 0xb1, 0x0, 0x56, 0x0, + 0x0, 0x0, 0xb1, 0x0, 0x2b, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0xc, 0x30, 0x0, 0x0, 0xb1, 0x0, + 0x34, 0xd0, 0x0, 0x30, 0xb1, 0x66, 0x0, 0x8b, + 0x10, 0x70, 0xcd, 0x40, 0x0, 0x7, 0xe9, 0x70, + 0x62, 0x0, 0x0, 0x0, 0x2a, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+6C11 "民" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, + 0x55, 0x55, 0x55, 0xc1, 0x0, 0xc, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x55, 0x5a, 0x55, 0x5d, 0x0, + 0x0, 0xc0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x9, 0x20, 0x0, 0x53, 0x0, 0xc5, 0x55, + 0x99, 0x55, 0x55, 0x40, 0xc, 0x0, 0x1, 0xb0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0xa, 0x40, 0x0, + 0x0, 0xc, 0x1, 0x50, 0x2d, 0x20, 0x5, 0x0, + 0xd8, 0x80, 0x0, 0x4d, 0x41, 0x80, 0xc, 0x50, + 0x0, 0x0, 0x2b, 0xfc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x30, + + /* U+6C14 "气" */ + 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x55, 0x55, 0x55, 0x7d, 0x10, 0x0, 0x65, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x90, 0x65, 0x55, + 0x57, 0x90, 0x0, 0x7, 0x10, 0x0, 0x0, 0x3, + 0x0, 0x0, 0x21, 0x36, 0x55, 0x55, 0x5c, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0x70, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc2, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x30, + + /* U+6C17 "気" */ + 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xc0, 0x0, 0x0, 0x2, 0x0, 0x0, 0xa, + 0x75, 0x55, 0x55, 0x59, 0x40, 0x0, 0x28, 0x55, + 0x55, 0x55, 0xa2, 0x0, 0x0, 0x90, 0x10, 0x0, + 0x0, 0x10, 0x0, 0x5, 0x16, 0x55, 0x55, 0x55, + 0xe0, 0x0, 0x1, 0x0, 0x0, 0xa, 0x60, 0xc0, + 0x0, 0x0, 0x4, 0x20, 0x3c, 0x0, 0xb0, 0x0, + 0x0, 0x0, 0x49, 0xc1, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0xa, 0xc7, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x93, 0xc, 0x60, 0x83, 0x30, 0x0, 0x27, 0x10, + 0x2, 0x60, 0x2c, 0x51, 0x1, 0x30, 0x0, 0x0, + 0x0, 0x6, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, + + /* U+6C34 "水" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb4, 0x0, 0x7a, 0x0, 0x5, 0x55, 0xa4, 0xb7, + 0x5, 0x80, 0x0, 0x1, 0x0, 0xd1, 0xb7, 0x63, + 0x0, 0x0, 0x0, 0x3, 0xa0, 0xb2, 0x80, 0x0, + 0x0, 0x0, 0x9, 0x40, 0xb1, 0x83, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0xb1, 0x1c, 0x0, 0x0, 0x0, + 0x83, 0x0, 0xb1, 0x6, 0xb0, 0x0, 0x3, 0x60, + 0x0, 0xb1, 0x0, 0x9d, 0x40, 0x15, 0x0, 0x11, + 0xc1, 0x0, 0x8, 0x60, 0x0, 0x0, 0x2b, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C37 "氷" */ + 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0xa2, 0x0, 0x10, 0x0, 0x0, 0x6a, 0x10, + 0xa3, 0x0, 0xd4, 0x0, 0x0, 0x6, 0x80, 0xa8, + 0x9, 0x30, 0x0, 0x4, 0x55, 0x66, 0xa8, 0x72, + 0x0, 0x0, 0x1, 0x0, 0x85, 0xa4, 0x70, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0xa2, 0xa1, 0x0, 0x0, + 0x0, 0x7, 0x50, 0xa2, 0x3c, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0xa2, 0x9, 0xb0, 0x0, 0x0, 0xa1, + 0x0, 0xa2, 0x0, 0xbd, 0x50, 0x8, 0x10, 0x22, + 0xc2, 0x0, 0x8, 0x20, 0x20, 0x0, 0x18, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C38 "永" */ + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, + 0x5a, 0x10, 0x1, 0x0, 0x0, 0x0, 0x10, 0xe, + 0x0, 0x2e, 0x10, 0x0, 0x0, 0x12, 0xd, 0x40, + 0xa2, 0x0, 0x3, 0x65, 0xa9, 0xc, 0x77, 0x20, + 0x0, 0x0, 0x0, 0xc1, 0xc, 0x55, 0x0, 0x0, + 0x0, 0x4, 0x80, 0xc, 0xb, 0x0, 0x0, 0x0, + 0xb, 0x0, 0xc, 0x5, 0xb0, 0x0, 0x0, 0x73, + 0x0, 0xc, 0x0, 0x9c, 0x20, 0x4, 0x40, 0x3, + 0x4c, 0x0, 0x8, 0xc2, 0x2, 0x0, 0x2, 0xd7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C42 "求" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd2, 0x29, 0x20, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x3, 0xc0, 0x0, 0x5, 0x55, 0x55, + 0xe5, 0x55, 0x7d, 0x30, 0x1, 0x0, 0x0, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x56, 0x0, 0xd5, 0x0, + 0x65, 0x0, 0x0, 0xa, 0x90, 0xd7, 0x5, 0xb3, + 0x0, 0x0, 0x1, 0x60, 0xd2, 0xa5, 0x0, 0x0, + 0x0, 0x0, 0x36, 0xd0, 0x93, 0x0, 0x0, 0x0, + 0x39, 0x40, 0xd0, 0x1d, 0x30, 0x0, 0x3c, 0xa0, + 0x0, 0xd0, 0x3, 0xe8, 0x10, 0x6, 0x0, 0x32, + 0xe0, 0x0, 0x2d, 0x90, 0x0, 0x0, 0x3c, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C5A "汚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x6, 0x55, 0x65, 0x5a, 0x10, 0x0, 0x3a, + 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x1, 0x20, + 0x6, 0x50, 0x0, 0x0, 0x27, 0x0, 0x76, 0x5b, + 0x75, 0x55, 0xb1, 0x7, 0x73, 0x20, 0xb, 0x0, + 0x0, 0x0, 0x0, 0x46, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x0, 0x4b, 0x55, 0x5c, 0x40, + 0x0, 0x44, 0x0, 0x0, 0x0, 0xd, 0x0, 0x7, + 0xe0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x39, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x30, 0x86, 0x0, 0x0, 0xa0, 0x0, 0x0, + 0x3e, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+6C60 "池" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x49, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x31, + 0xa0, 0xb0, 0x2, 0x0, 0x9, 0x10, 0x41, 0xa0, + 0xb4, 0x4c, 0x30, 0x3, 0xb1, 0x44, 0xb4, 0xc0, + 0xa, 0x0, 0x0, 0x26, 0x22, 0xa0, 0xb0, 0xb, + 0x0, 0x0, 0x7, 0x1, 0xa0, 0xb0, 0xb, 0x0, + 0x0, 0x35, 0x1, 0xa0, 0xb2, 0x4c, 0x0, 0x6, + 0xe1, 0x1, 0xa0, 0xb0, 0x76, 0x20, 0x0, 0xd0, + 0x1, 0xa0, 0x70, 0x0, 0x60, 0x0, 0xe0, 0x1, + 0xb0, 0x0, 0x0, 0xb4, 0x0, 0xa0, 0x0, 0x8a, + 0xaa, 0xaa, 0x91, + + /* U+6C7A "決" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x75, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x1, 0x5, + 0x76, 0xc5, 0x5c, 0x0, 0x7, 0x20, 0x40, 0x1, + 0xa0, 0xc, 0x0, 0x1, 0xe0, 0x60, 0x1, 0xa0, + 0xc, 0x0, 0x0, 0x43, 0x30, 0x2, 0x90, 0xc, + 0x0, 0x0, 0x8, 0x26, 0x57, 0xb5, 0x5a, 0x93, + 0x0, 0x27, 0x0, 0x7, 0x56, 0x0, 0x0, 0x5, + 0xe3, 0x0, 0xc, 0x9, 0x10, 0x0, 0x0, 0xc0, + 0x0, 0x57, 0x2, 0xc0, 0x0, 0x0, 0xe0, 0x1, + 0xa0, 0x0, 0x7c, 0x20, 0x0, 0x70, 0x28, 0x0, + 0x0, 0x7, 0xf4, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x10, + + /* U+6C88 "沈" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, + 0x50, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x3, 0x7, + 0x55, 0xc5, 0x57, 0x80, 0x14, 0x0, 0x4c, 0x1, + 0xa0, 0x7, 0x20, 0x9, 0x54, 0x11, 0x2, 0xa0, + 0x0, 0x0, 0x1, 0x25, 0x0, 0x4, 0xe5, 0x0, + 0x0, 0x0, 0x6, 0x0, 0x7, 0xb4, 0x0, 0x0, + 0x0, 0x62, 0x0, 0xc, 0x74, 0x0, 0x0, 0x14, + 0xc0, 0x0, 0x39, 0x64, 0x0, 0x10, 0x7, 0xb0, + 0x0, 0xa1, 0x64, 0x0, 0x50, 0x4, 0xa0, 0x7, + 0x20, 0x65, 0x0, 0x61, 0x5, 0xa0, 0x62, 0x0, + 0x3c, 0x99, 0xc4, 0x0, 0x23, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C92 "沒" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x73, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x96, 0x55, 0x5d, 0x0, 0x0, 0x2, 0x13, + 0x80, 0x0, 0x1b, 0x0, 0x7, 0x0, 0x56, 0x10, + 0x0, 0x38, 0x0, 0x4, 0xb0, 0x73, 0x0, 0x3, + 0xd2, 0x0, 0x0, 0x55, 0x15, 0x65, 0x55, 0x6c, + 0x0, 0x0, 0x8, 0x0, 0x60, 0x0, 0x86, 0x0, + 0x0, 0x46, 0x0, 0x43, 0x1, 0xb0, 0x0, 0x6, + 0xf1, 0x0, 0xa, 0x1b, 0x20, 0x0, 0x0, 0xc0, + 0x0, 0x3, 0xf5, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x3b, 0x6c, 0x60, 0x0, 0x0, 0x80, 0x38, 0x71, + 0x1, 0x9f, 0xb2, 0x0, 0x2, 0x20, 0x0, 0x0, + 0x1, 0x20, + + /* U+6CB9 "油" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x5, + 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x42, 0x20, 0xb, + 0x0, 0x40, 0x23, 0x0, 0x5b, 0x55, 0xc5, 0x5d, + 0x10, 0xb5, 0x14, 0xb0, 0xb, 0x0, 0xb0, 0x2, + 0x36, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0x80, + 0xb5, 0x5c, 0x55, 0xc0, 0x0, 0x54, 0xb, 0x0, + 0xb0, 0xb, 0x1, 0x6d, 0x0, 0xb0, 0xb, 0x0, + 0xb0, 0x3, 0xc0, 0xb, 0x0, 0xb0, 0xb, 0x0, + 0x3b, 0x0, 0xb5, 0x5c, 0x55, 0xc0, 0x3, 0xb0, + 0xa, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6CBB "治" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x53, 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0xe, + 0x10, 0x8, 0x40, 0x0, 0x0, 0x0, 0x4, 0x4, + 0x27, 0x0, 0x53, 0x0, 0x4, 0x0, 0x32, 0x80, + 0x0, 0xb, 0x50, 0x6, 0xa0, 0x6a, 0xc8, 0x65, + 0x55, 0xd0, 0x0, 0x80, 0x61, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x6, 0x10, 0x95, 0x55, 0x5b, 0x0, + 0x0, 0xa, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x4, + 0xb7, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x95, + 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb4, 0x0, + 0xc5, 0x55, 0x5b, 0x0, 0x0, 0x93, 0x0, 0xa0, + 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CC1 "況" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x82, 0x1, 0xa5, 0x55, 0x5b, 0x20, 0x0, 0x1d, + 0x0, 0xa0, 0x0, 0xb, 0x0, 0x0, 0x2, 0x3, + 0xa0, 0x0, 0xb, 0x0, 0x6, 0x0, 0x40, 0xa0, + 0x0, 0xb, 0x0, 0x4, 0xb0, 0x50, 0xc5, 0x55, + 0x5c, 0x0, 0x0, 0x64, 0x21, 0x77, 0x3b, 0x5, + 0x0, 0x0, 0x8, 0x0, 0x8, 0x1b, 0x0, 0x0, + 0x0, 0x37, 0x0, 0xa, 0xb, 0x0, 0x0, 0x6, + 0xe2, 0x0, 0xa, 0xb, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x74, 0xb, 0x0, 0x50, 0x0, 0xf0, 0x3, + 0x80, 0xb, 0x0, 0x80, 0x0, 0xa0, 0x46, 0x0, + 0x7, 0xa9, 0xc2, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CCA "泊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, + 0x0, 0x0, 0x5b, 0x0, 0x0, 0x1, 0xd0, 0x0, + 0x8, 0x10, 0x0, 0x0, 0x5, 0x3, 0x95, 0x85, + 0x55, 0xb0, 0x40, 0x2, 0x2b, 0x0, 0x0, 0x1a, + 0x3, 0xb0, 0x50, 0xb0, 0x0, 0x1, 0xa0, 0x9, + 0x16, 0xb, 0x0, 0x0, 0x1a, 0x0, 0x6, 0x10, + 0xc5, 0x55, 0x56, 0xa0, 0x0, 0x90, 0xb, 0x0, + 0x0, 0x1a, 0x4, 0xb6, 0x0, 0xb0, 0x0, 0x1, + 0xa0, 0xa, 0x30, 0xb, 0x0, 0x0, 0x1a, 0x0, + 0xb2, 0x0, 0xc5, 0x55, 0x56, 0xa0, 0x9, 0x30, + 0xb, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6CD5 "法" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x91, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3a, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x2, 0x34, + 0x65, 0xc5, 0x5a, 0x30, 0x26, 0x0, 0x50, 0x0, + 0xb0, 0x0, 0x0, 0x8, 0x71, 0x40, 0x0, 0xb0, + 0x0, 0x0, 0x1, 0x46, 0x0, 0x0, 0xb0, 0x0, + 0x60, 0x0, 0x7, 0x36, 0x56, 0xd5, 0x55, 0x51, + 0x0, 0x63, 0x0, 0x7, 0x90, 0x0, 0x0, 0x18, + 0xd0, 0x0, 0x2b, 0x0, 0x30, 0x0, 0x1, 0xb0, + 0x0, 0x91, 0x0, 0x57, 0x0, 0x3, 0xa0, 0x19, + 0x44, 0x55, 0x5c, 0x70, 0x2, 0x80, 0x2e, 0x95, + 0x20, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CE2 "波" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x1, 0x4a, + 0x55, 0xc5, 0x5b, 0x70, 0x27, 0x0, 0x5b, 0x0, + 0xb0, 0x17, 0x0, 0x8, 0x73, 0x2b, 0x0, 0xb0, + 0x0, 0x0, 0x1, 0x27, 0xb, 0x56, 0xa5, 0x6a, + 0x0, 0x0, 0x16, 0xb, 0x5, 0x0, 0x84, 0x0, + 0x0, 0x81, 0xb, 0x6, 0x11, 0xa0, 0x0, 0x29, + 0xb0, 0x28, 0x0, 0xaa, 0x10, 0x0, 0x3, 0x90, + 0x72, 0x0, 0xab, 0x0, 0x0, 0x5, 0x91, 0x70, + 0x9, 0x45, 0xc3, 0x0, 0x3, 0x76, 0x5, 0x71, + 0x0, 0x3d, 0x80, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CE3 "泣" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x82, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x3c, + 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x3, 0x5, + 0x55, 0x65, 0x5d, 0x30, 0x16, 0x0, 0x31, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x52, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x54, 0x20, 0x70, 0x2, 0xb0, + 0x0, 0x0, 0x8, 0x0, 0xa2, 0x5, 0x60, 0x0, + 0x0, 0x28, 0x0, 0x77, 0x8, 0x10, 0x0, 0x6, + 0xe3, 0x0, 0x49, 0x9, 0x0, 0x0, 0x0, 0xd1, + 0x0, 0x12, 0x7, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0x42, 0x1, 0x80, 0x0, 0xa0, 0x65, 0x55, + 0x55, 0x55, 0x51, + + /* U+6CE8 "注" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x70, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x6a, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x4, 0x40, + 0x0, 0x20, 0x5, 0x50, 0x22, 0x0, 0x56, 0x55, + 0xd5, 0x55, 0x40, 0xb, 0x53, 0x30, 0x0, 0xc0, + 0x0, 0x0, 0x3, 0x67, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x8, 0x4, 0x55, 0xd5, 0x6d, 0x10, + 0x0, 0x55, 0x1, 0x0, 0xc0, 0x0, 0x0, 0x17, + 0xe0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x4, 0xb0, 0x0, + 0x0, 0xc0, 0x2, 0x70, 0x4, 0xa0, 0x65, 0x55, + 0x55, 0x55, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CF3 "泳" */ + 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x82, 0x0, 0x6, 0xd2, 0x0, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x2, 0x32, + 0x65, 0xe1, 0x1, 0x0, 0x17, 0x0, 0x50, 0x0, + 0xe1, 0xb, 0x40, 0x7, 0x93, 0x20, 0x40, 0xc5, + 0x73, 0x0, 0x0, 0x47, 0x46, 0xd2, 0xc9, 0x10, + 0x0, 0x0, 0x8, 0x0, 0xb0, 0xc7, 0x10, 0x0, + 0x0, 0x55, 0x4, 0x70, 0xc2, 0x80, 0x0, 0x7, + 0xf1, 0xa, 0x10, 0xc0, 0xb3, 0x0, 0x0, 0xe0, + 0x37, 0x0, 0xc0, 0x3e, 0x30, 0x3, 0xd1, 0x60, + 0x11, 0xc0, 0x6, 0xa1, 0x1, 0xa0, 0x0, 0x4d, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+6D0B "洋" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x60, 0x0, 0x92, 0x0, 0xd2, 0x0, 0x0, 0x69, + 0x0, 0x4b, 0x4, 0x70, 0x0, 0x0, 0x5, 0x20, + 0x3, 0x7, 0x5, 0x40, 0x12, 0x0, 0x45, 0x55, + 0xd5, 0x55, 0x40, 0xb, 0x50, 0x50, 0x0, 0xc0, + 0x2, 0x0, 0x2, 0x64, 0x23, 0x65, 0xd5, 0x59, + 0x10, 0x0, 0x8, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0x0, 0xc0, 0x1, 0x60, 0x5, + 0xb4, 0x36, 0x55, 0xd5, 0x55, 0x50, 0x0, 0xe1, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+6D17 "洗" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, + 0x60, 0x0, 0x40, 0xb2, 0x0, 0x0, 0x0, 0x87, + 0x2, 0xd0, 0xb0, 0x0, 0x0, 0x0, 0x12, 0x35, + 0x95, 0xc5, 0x5d, 0x20, 0x15, 0x0, 0x49, 0x0, + 0xb0, 0x0, 0x0, 0x7, 0x81, 0x54, 0x0, 0xb0, + 0x0, 0x0, 0x0, 0x55, 0x35, 0x55, 0xc5, 0x56, + 0xb0, 0x0, 0x7, 0x1, 0x1b, 0xa, 0x10, 0x0, + 0x0, 0x17, 0x0, 0x29, 0xa, 0x10, 0x0, 0x5, + 0xb4, 0x0, 0x57, 0xa, 0x10, 0x0, 0x0, 0xd2, + 0x0, 0xa2, 0xa, 0x10, 0x40, 0x0, 0xf1, 0x4, + 0x90, 0xa, 0x10, 0x80, 0x0, 0xe0, 0x57, 0x0, + 0x6, 0xb9, 0xd4, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D32 "洲" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x83, 0x0, 0xb0, 0x2, 0x0, 0xd0, 0x0, 0x1b, + 0x0, 0xb0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x40, + 0xb0, 0xa, 0x0, 0xb0, 0x7, 0x10, 0x50, 0xa0, + 0xa, 0x0, 0xb0, 0x3, 0xc1, 0x45, 0xb6, 0xa, + 0x70, 0xb0, 0x0, 0x26, 0x66, 0xa5, 0x6a, 0x84, + 0xb0, 0x0, 0x8, 0x62, 0x91, 0x1a, 0x10, 0xb0, + 0x0, 0x36, 0x4, 0x70, 0xa, 0x0, 0xb0, 0x6, + 0xe2, 0x8, 0x20, 0xa, 0x0, 0xb0, 0x0, 0xd0, + 0xa, 0x0, 0xa, 0x0, 0xb0, 0x0, 0xf0, 0x63, + 0x0, 0xb, 0x0, 0xb0, 0x0, 0x92, 0x40, 0x0, + 0x1, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D3B "活" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x72, 0x0, 0x0, 0x15, 0xac, 0x0, 0x0, 0x2d, + 0x4, 0x57, 0xd6, 0x32, 0x0, 0x0, 0x3, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x24, 0x0, 0x30, 0x0, + 0xb0, 0x0, 0x20, 0x9, 0x64, 0x46, 0x55, 0xc5, + 0x55, 0x91, 0x1, 0x56, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x0, 0x16, 0x2, 0x0, 0xb0, 0x3, 0x0, + 0x0, 0x72, 0xc, 0x55, 0x55, 0x5e, 0x10, 0x18, + 0xd0, 0xc, 0x0, 0x0, 0xb, 0x0, 0x1, 0xb0, + 0xc, 0x0, 0x0, 0xb, 0x0, 0x3, 0xb0, 0xc, + 0x55, 0x55, 0x5c, 0x0, 0x2, 0x80, 0xc, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x2, 0x0, + + /* U+6D3E "派" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0x0, 0x26, 0xbc, 0x0, 0x0, 0xd, + 0x9, 0x65, 0x42, 0x0, 0x0, 0x0, 0x0, 0x39, + 0x20, 0x1, 0x6c, 0x0, 0x38, 0x1, 0x39, 0x2a, + 0x67, 0x20, 0x0, 0x9, 0x55, 0x9, 0x2b, 0x4, + 0x5, 0x40, 0x1, 0x7, 0xa, 0x1b, 0x6, 0x69, + 0x20, 0x0, 0x35, 0xb, 0xb, 0x9, 0x20, 0x0, + 0x0, 0xa0, 0xb, 0xb, 0x8, 0x10, 0x0, 0x19, + 0xd0, 0x19, 0xb, 0x3, 0x80, 0x0, 0x3, 0xb0, + 0x72, 0xb, 0x0, 0xa4, 0x0, 0x5, 0xa0, 0x70, + 0xc, 0x83, 0x1e, 0x80, 0x1, 0x56, 0x0, 0x9, + 0x10, 0x3, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D41 "流" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x60, 0x0, 0x9, 0x50, 0x1, 0x0, 0x0, 0x4b, + 0x27, 0x59, 0x75, 0x59, 0x40, 0x0, 0x4, 0x0, + 0x1d, 0x20, 0x0, 0x0, 0x32, 0x0, 0x40, 0x93, + 0x0, 0x70, 0x0, 0xc, 0x32, 0x37, 0x73, 0x34, + 0x98, 0x0, 0x3, 0x26, 0x7, 0x74, 0x20, 0x8, + 0x0, 0x0, 0x7, 0xa, 0x29, 0x30, 0xb0, 0x0, + 0x0, 0x63, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x26, + 0xc0, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x6, 0xa0, + 0xb, 0xb, 0x0, 0xb0, 0x30, 0x5, 0x90, 0x55, + 0xb, 0x0, 0xb0, 0x60, 0x6, 0x93, 0x60, 0xb, + 0x0, 0xb9, 0xc0, 0x0, 0x12, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+6D45 "浅" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x56, 0x0, 0x0, 0xd2, 0x50, 0x0, 0x0, 0xd, + 0x20, 0x0, 0xc0, 0x86, 0x0, 0x0, 0x2, 0x4, + 0x0, 0xc0, 0x4, 0x20, 0x7, 0x20, 0x33, 0x45, + 0xd5, 0x56, 0x50, 0x2, 0xe0, 0x61, 0x10, 0xb0, + 0x0, 0x20, 0x0, 0x41, 0x60, 0x2, 0xc5, 0x57, + 0x90, 0x0, 0x6, 0x36, 0x43, 0xb0, 0x7, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x83, 0x8a, 0x0, 0x4, + 0xb8, 0x0, 0x0, 0x3e, 0x80, 0x0, 0x0, 0x95, + 0x0, 0x1, 0xad, 0x30, 0x50, 0x0, 0xb4, 0x0, + 0x57, 0x11, 0xc4, 0x90, 0x0, 0x93, 0x13, 0x0, + 0x0, 0x1b, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+6D74 "浴" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x1d, 0x2, 0x70, 0x0, 0x0, 0x4c, + 0x0, 0xa3, 0x0, 0x3e, 0x20, 0x0, 0x3, 0x45, + 0x30, 0xa5, 0x7, 0x40, 0x17, 0x0, 0x62, 0x4, + 0xb6, 0x0, 0x0, 0x7, 0xa2, 0x30, 0xc, 0x13, + 0x60, 0x0, 0x0, 0x47, 0x0, 0xa2, 0x0, 0x69, + 0x10, 0x0, 0x9, 0x8, 0x70, 0x0, 0xb, 0xe2, + 0x0, 0x37, 0x51, 0xc5, 0x55, 0x5c, 0x0, 0x6, + 0xd2, 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x0, 0xf0, + 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x2, 0xf0, 0x0, + 0xd5, 0x55, 0x5b, 0x0, 0x1, 0xc0, 0x0, 0xc0, + 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D77 "海" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, + 0x70, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x94, + 0x9, 0x75, 0x55, 0x5a, 0x40, 0x0, 0x12, 0x19, + 0x0, 0x0, 0x0, 0x0, 0x29, 0x4, 0x6a, 0x55, + 0x55, 0xa5, 0x0, 0x9, 0x25, 0x1c, 0x7, 0x30, + 0x91, 0x0, 0x0, 0x14, 0xc, 0x1, 0x80, 0xa0, + 0x20, 0x0, 0x64, 0x7c, 0x55, 0x55, 0xc5, 0x81, + 0x0, 0x80, 0x38, 0x7, 0x20, 0xb0, 0x0, 0x2a, + 0x80, 0x65, 0x3, 0x60, 0xb0, 0x0, 0x6, 0x60, + 0xb6, 0x55, 0x55, 0xd5, 0x90, 0x8, 0x60, 0x0, + 0x1, 0x11, 0xb0, 0x0, 0x5, 0x50, 0x0, 0x0, + 0x6f, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+6D88 "消" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x6, + 0x20, 0x31, 0x2, 0xc0, 0x43, 0x0, 0x1e, 0x0, + 0xc3, 0x1a, 0xb, 0x20, 0x0, 0x40, 0x35, 0x51, + 0xa5, 0x10, 0x6, 0x10, 0x13, 0x85, 0x6c, 0x69, + 0x20, 0x3d, 0x5, 0xc, 0x0, 0x0, 0xc0, 0x0, + 0x50, 0x70, 0xd5, 0x55, 0x5d, 0x0, 0x0, 0x35, + 0xc, 0x0, 0x0, 0xc0, 0x0, 0x9, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x48, 0xb0, 0xd, 0x55, 0x55, + 0xd0, 0x0, 0x68, 0x0, 0xc0, 0x0, 0xc, 0x0, + 0x6, 0x70, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x67, + 0x0, 0xc0, 0x4, 0xbc, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x1, 0x10, + + /* U+6DBC "涼" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x50, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x69, + 0x0, 0x0, 0x16, 0x0, 0x60, 0x0, 0x6, 0x6, + 0x65, 0x55, 0x55, 0x51, 0x13, 0x0, 0x40, 0x65, + 0x55, 0x57, 0x0, 0x9, 0x60, 0x50, 0xb0, 0x0, + 0xb, 0x0, 0x1, 0x94, 0x20, 0xb0, 0x0, 0xb, + 0x0, 0x0, 0x8, 0x0, 0xb5, 0x57, 0x5c, 0x0, + 0x0, 0x26, 0x0, 0x50, 0x1a, 0x3, 0x0, 0x6, + 0xc1, 0x0, 0xa3, 0x1a, 0x33, 0x0, 0x0, 0xd0, + 0x3, 0xa0, 0x1a, 0x9, 0x50, 0x0, 0xd0, 0x18, + 0x0, 0x19, 0x1, 0xe0, 0x0, 0xc0, 0x50, 0x6, + 0xb8, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x40, + 0x0, 0x0, + + /* U+6DF1 "深" */ + 0x0, 0x70, 0x4, 0x0, 0x0, 0x2, 0x10, 0x0, + 0x59, 0xa, 0x55, 0x55, 0x5b, 0x50, 0x0, 0x2, + 0x56, 0x47, 0x3, 0x43, 0x0, 0x32, 0x3, 0x10, + 0xa1, 0x10, 0x6b, 0x0, 0xc, 0x35, 0x6, 0x0, + 0xc2, 0x7, 0x0, 0x2, 0x16, 0x0, 0x0, 0xc0, + 0x2, 0x40, 0x0, 0x53, 0x16, 0x5b, 0xf8, 0x55, + 0x50, 0x0, 0xa0, 0x0, 0x2b, 0xc5, 0x10, 0x0, + 0x29, 0xb0, 0x0, 0xb1, 0xc0, 0xa0, 0x0, 0x4, + 0x90, 0x9, 0x20, 0xc0, 0x4c, 0x20, 0x6, 0x81, + 0x61, 0x0, 0xc0, 0x7, 0x80, 0x4, 0x60, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6DF7 "混" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x64, 0x2, 0x0, 0x0, 0x4, 0x0, 0x0, 0xd, + 0x17, 0x85, 0x55, 0x5d, 0x0, 0x0, 0x2, 0x47, + 0x85, 0x55, 0x5b, 0x0, 0x29, 0x0, 0x56, 0x50, + 0x0, 0xb, 0x0, 0x7, 0x72, 0x37, 0x50, 0x0, + 0xb, 0x0, 0x0, 0x17, 0x5, 0x65, 0x58, 0x57, + 0x0, 0x0, 0x7, 0xa, 0x20, 0xc, 0x6, 0x10, + 0x0, 0x63, 0xb, 0x5a, 0x3b, 0x88, 0x10, 0x18, + 0xf0, 0xb, 0x0, 0xd, 0x20, 0x0, 0x0, 0xc0, + 0xb, 0x0, 0xb, 0x0, 0x50, 0x1, 0xd0, 0xb, + 0x66, 0x2b, 0x0, 0x90, 0x0, 0x80, 0x8, 0x40, + 0xc, 0xab, 0xb0, + + /* U+6E05 "清" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x1, + 0x91, 0x0, 0x0, 0xc0, 0x2, 0x0, 0x0, 0x59, + 0x26, 0x55, 0xc5, 0x58, 0x40, 0x0, 0x2, 0x3, + 0x55, 0xc5, 0x77, 0x0, 0x28, 0x4, 0x1, 0x10, + 0xb0, 0x0, 0x10, 0x7, 0x85, 0x55, 0x55, 0xa5, + 0x56, 0xb0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x4, + 0x0, 0x0, 0x33, 0xb, 0x55, 0x55, 0x5c, 0x0, + 0x0, 0x80, 0xb, 0x55, 0x55, 0x5b, 0x0, 0x28, + 0xb0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x4, 0xa0, + 0xb, 0x55, 0x55, 0x5b, 0x0, 0x5, 0x80, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x5, 0x70, 0xb, 0x0, + 0x5, 0xc9, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x20, 0x0, + + /* U+6E07 "渇" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x73, 0x9, 0x65, 0x55, 0x5c, 0x0, 0x0, 0x1d, + 0x9, 0x20, 0x0, 0xb, 0x0, 0x0, 0x2, 0x2b, + 0x65, 0x55, 0x5b, 0x0, 0x16, 0x0, 0x59, 0x20, + 0x0, 0xb, 0x0, 0x6, 0x91, 0x59, 0x85, 0x55, + 0x5b, 0x0, 0x0, 0x56, 0x3, 0xc4, 0x0, 0x0, + 0x10, 0x0, 0x8, 0x7, 0x85, 0x55, 0x57, 0xb0, + 0x0, 0x54, 0x5a, 0x30, 0x35, 0x3, 0x80, 0x6, + 0xe2, 0x27, 0x67, 0x62, 0x4, 0x70, 0x0, 0xc0, + 0x7, 0x60, 0x5, 0x14, 0x70, 0x0, 0xd0, 0x3, + 0xa9, 0x9a, 0x25, 0x60, 0x0, 0x70, 0x0, 0x0, + 0x0, 0x7e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, + + /* U+6E08 "済" */ + 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0x72, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, 0x1d, + 0x6, 0x65, 0x95, 0x88, 0x70, 0x0, 0x3, 0x0, + 0x60, 0x2, 0xb0, 0x0, 0x15, 0x0, 0x40, 0x1a, + 0x1b, 0x10, 0x0, 0x7, 0x80, 0x40, 0x7, 0xf4, + 0x0, 0x0, 0x0, 0x65, 0x2, 0x87, 0x2a, 0xb6, + 0x41, 0x0, 0x8, 0x46, 0x80, 0x0, 0xa9, 0x60, + 0x0, 0x45, 0x3, 0xa5, 0x55, 0xd0, 0x0, 0x7, + 0xe0, 0x4, 0x70, 0x0, 0xb0, 0x0, 0x0, 0xd0, + 0x7, 0x75, 0x55, 0xc0, 0x0, 0x1, 0xd0, 0xa, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x90, 0x54, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x40, 0x0, + + /* U+6E09 "渉" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x73, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x61, 0xa1, 0x0, 0x0, 0x0, 0x2, 0x30, + 0xa0, 0xa6, 0x59, 0x0, 0x26, 0x0, 0x50, 0xa0, + 0xa1, 0x0, 0x0, 0x8, 0x72, 0x55, 0xc5, 0xb6, + 0x56, 0xa0, 0x1, 0x47, 0x1, 0x10, 0x93, 0x0, + 0x0, 0x0, 0x17, 0x0, 0xd1, 0xa1, 0x19, 0x20, + 0x0, 0x82, 0x4, 0x70, 0xa1, 0x31, 0xd0, 0x18, + 0xd0, 0x9, 0x0, 0xa4, 0xd2, 0x30, 0x2, 0xb0, + 0x23, 0x0, 0x6c, 0x10, 0x0, 0x4, 0xb0, 0x0, + 0x8, 0x90, 0x0, 0x0, 0x2, 0x70, 0x6, 0x83, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E1B "減" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, + 0x60, 0x0, 0x0, 0xc, 0x48, 0x0, 0x0, 0x78, + 0x0, 0x0, 0xb, 0x6, 0x50, 0x0, 0x4, 0x3b, + 0x55, 0x5c, 0x65, 0x92, 0x22, 0x0, 0x4b, 0x0, + 0x9, 0x10, 0x0, 0xb, 0x43, 0x2b, 0x46, 0xba, + 0x22, 0x70, 0x3, 0x56, 0xa, 0x0, 0x17, 0x36, + 0x70, 0x0, 0x16, 0xa, 0x95, 0xc7, 0x6b, 0x10, + 0x0, 0x72, 0xa, 0x90, 0xa2, 0xb9, 0x0, 0x18, + 0xc0, 0xa, 0x90, 0xa0, 0xe2, 0x0, 0x3, 0xa0, + 0x36, 0x95, 0xa6, 0xc5, 0x40, 0x4, 0x90, 0x91, + 0x0, 0x38, 0xc, 0x80, 0x3, 0x82, 0x50, 0x3, + 0x70, 0x3, 0xf3, 0x0, 0x2, 0x0, 0x2, 0x0, + 0x0, 0x12, + + /* U+6E21 "渡" */ + 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, + 0x91, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x59, + 0x9, 0x55, 0x87, 0x55, 0xb1, 0x10, 0x1, 0x1b, + 0x7, 0x10, 0x80, 0x0, 0x1a, 0x10, 0x4b, 0xa, + 0x0, 0xa1, 0x40, 0x6, 0x65, 0xc, 0x5c, 0x55, + 0xc5, 0x40, 0x0, 0x6, 0xb, 0xa, 0x55, 0xb0, + 0x0, 0x0, 0x16, 0xb, 0x5, 0x0, 0x40, 0x0, + 0x0, 0x81, 0x19, 0x37, 0x55, 0xd4, 0x0, 0x18, + 0xd0, 0x46, 0x5, 0x15, 0x90, 0x0, 0x2, 0xb0, + 0x82, 0x0, 0xbb, 0x0, 0x0, 0x4, 0xb0, 0x90, + 0x7, 0x9b, 0x60, 0x0, 0x1, 0x66, 0x25, 0x73, + 0x0, 0x7e, 0xa1, 0x0, 0x1, 0x21, 0x0, 0x0, + 0x0, 0x10, + + /* U+6E29 "温" */ + 0x0, 0x81, 0x7, 0x55, 0x55, 0x91, 0x0, 0x0, + 0x47, 0xa, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, + 0x4b, 0x55, 0x55, 0xb0, 0x0, 0x17, 0x3, 0x1a, + 0x0, 0x0, 0x90, 0x0, 0x7, 0x55, 0xa, 0x0, + 0x0, 0xa0, 0x0, 0x0, 0x7, 0xa, 0x55, 0x55, + 0xa0, 0x0, 0x0, 0x35, 0x20, 0x0, 0x0, 0x3, + 0x0, 0x0, 0x81, 0xb5, 0xb5, 0x5c, 0x5d, 0x0, + 0x28, 0xc0, 0xb0, 0xa0, 0xa, 0xb, 0x0, 0x4, + 0xa0, 0xb0, 0xa0, 0xa, 0xb, 0x0, 0x5, 0x90, + 0xb0, 0xa0, 0xa, 0xb, 0x0, 0x5, 0x95, 0xc5, + 0xb5, 0x5c, 0x5d, 0xb1, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6E2F "港" */ + 0x0, 0x0, 0x0, 0x20, 0x3, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x94, 0xb, 0x10, 0x0, 0x0, 0x49, + 0x0, 0x92, 0xb, 0x5, 0x0, 0x10, 0x2, 0x26, + 0xb6, 0x5c, 0x55, 0x10, 0xb, 0x24, 0x0, 0x92, + 0xb, 0x0, 0x10, 0x5, 0x65, 0x65, 0xa8, 0x5a, + 0x55, 0x81, 0x0, 0x5, 0x0, 0xb0, 0x3, 0x40, + 0x0, 0x0, 0x42, 0x7, 0xb5, 0x58, 0xb7, 0x0, + 0x0, 0x90, 0x55, 0xb0, 0x7, 0x36, 0xd2, 0x19, + 0xa4, 0x30, 0xc5, 0x59, 0x30, 0x0, 0x4, 0x80, + 0x0, 0xb0, 0x3, 0x13, 0x0, 0x6, 0x80, 0x0, + 0xb0, 0x0, 0x4, 0x30, 0x3, 0x50, 0x0, 0xba, + 0xaa, 0xac, 0x60, + + /* U+6E56 "湖" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x60, 0x3, 0x90, 0x2, 0x0, 0x30, 0x0, 0x94, + 0x13, 0x70, 0xd, 0x55, 0xb0, 0x0, 0x1, 0x45, + 0x85, 0x1b, 0x1, 0x90, 0x44, 0x4, 0x26, 0x82, + 0x1c, 0x55, 0x90, 0xc, 0x25, 0x3, 0x70, 0xa, + 0x1, 0x90, 0x2, 0x6, 0x46, 0x86, 0xa, 0x1, + 0x90, 0x0, 0x43, 0xb2, 0x2a, 0xc, 0x55, 0x90, + 0x0, 0x90, 0xa0, 0xa, 0x19, 0x1, 0x90, 0x29, + 0xb0, 0xa0, 0xa, 0x46, 0x1, 0x90, 0x3, 0x90, + 0xb5, 0x59, 0x90, 0x1, 0x90, 0x5, 0x90, 0x80, + 0x5, 0x40, 0x22, 0x90, 0x2, 0x60, 0x0, 0x44, + 0x0, 0x4e, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E90 "源" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x91, 0x8, 0x55, 0x55, 0x57, 0xb0, 0x0, 0x68, + 0xc, 0x0, 0xc, 0x10, 0x0, 0x0, 0x1, 0x4c, + 0x2, 0x34, 0x4, 0x0, 0x35, 0x1, 0x3c, 0xc, + 0x55, 0x5c, 0x20, 0xb, 0x65, 0xc, 0xb, 0x0, + 0xb, 0x0, 0x2, 0x26, 0xc, 0xc, 0x55, 0x5c, + 0x0, 0x0, 0x16, 0xb, 0xb, 0x0, 0xb, 0x0, + 0x0, 0x71, 0x29, 0xa, 0x5d, 0x59, 0x0, 0x18, + 0xd0, 0x64, 0x6, 0xc, 0x22, 0x0, 0x2, 0xb0, + 0x90, 0x4a, 0xc, 0xa, 0x50, 0x4, 0xa3, 0x41, + 0x80, 0xc, 0x1, 0xe0, 0x2, 0x85, 0x4, 0x2, + 0x9d, 0x0, 0x30, 0x0, 0x10, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+6E96 "準" */ + 0x0, 0x10, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, + 0x94, 0x0, 0x95, 0x2a, 0x0, 0x0, 0x0, 0x5, + 0x31, 0xc5, 0x58, 0x59, 0x70, 0x8, 0x30, 0x48, + 0xb0, 0x1a, 0x2, 0x0, 0x1, 0x65, 0x62, 0xc5, + 0x6c, 0x57, 0x20, 0x0, 0x7, 0x10, 0xb0, 0x1a, + 0x15, 0x10, 0x3, 0xb3, 0x0, 0xc5, 0x6b, 0x44, + 0x20, 0x0, 0x91, 0x0, 0xd5, 0x6b, 0x57, 0x90, + 0x0, 0x82, 0x0, 0x46, 0x0, 0x0, 0x0, 0x5, + 0x55, 0x55, 0x7b, 0x55, 0x55, 0xa2, 0x1, 0x0, + 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+6E9D "溝" */ + 0x0, 0x0, 0x0, 0x21, 0x2, 0x10, 0x0, 0x0, + 0x70, 0x0, 0x67, 0x6, 0x70, 0x0, 0x0, 0x69, + 0x36, 0x98, 0x59, 0x87, 0x70, 0x0, 0x4, 0x20, + 0x65, 0x5, 0x54, 0x0, 0x31, 0x0, 0x46, 0x98, + 0x59, 0x85, 0x30, 0xc, 0x25, 0x36, 0x76, 0x97, + 0x75, 0x90, 0x5, 0x36, 0x2, 0x0, 0xb0, 0x3, + 0x0, 0x0, 0x34, 0xb, 0x55, 0xc5, 0x5d, 0x0, + 0x0, 0x90, 0xb, 0x55, 0xc5, 0x5b, 0x0, 0x29, + 0xa0, 0xb, 0x0, 0xb0, 0xb, 0x20, 0x6, 0x70, + 0x6c, 0x55, 0x65, 0x5c, 0x61, 0x7, 0x70, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x5, 0x60, 0xb, 0x0, + 0x5, 0x9a, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, + 0x42, 0x0, + + /* U+6EFF "滿" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x30, 0x0, 0x0, + 0x72, 0x0, 0x47, 0x0, 0xc0, 0x0, 0x0, 0x1d, + 0x36, 0x79, 0x55, 0xd5, 0x92, 0x0, 0x3, 0x20, + 0x36, 0x0, 0xb0, 0x0, 0x6, 0x0, 0x40, 0x49, + 0xa5, 0xc0, 0x0, 0x4, 0xb0, 0x50, 0x10, 0xb0, + 0x0, 0x0, 0x0, 0x74, 0x2c, 0x55, 0xc5, 0x58, + 0x90, 0x0, 0x7, 0xb, 0x61, 0xb3, 0x54, 0x60, + 0x0, 0x27, 0xb, 0x3b, 0xb0, 0xd8, 0x60, 0x5, + 0xd3, 0xb, 0x79, 0xd5, 0x6e, 0x60, 0x0, 0xc0, + 0xc, 0x11, 0xb3, 0x6, 0x60, 0x0, 0xe0, 0xb, + 0x0, 0xb0, 0x4, 0x60, 0x0, 0x90, 0xb, 0x0, + 0xb0, 0x5b, 0x50, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x5, 0x0, + + /* U+6F22 "漢" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, + 0x81, 0x0, 0xb0, 0x1, 0xa0, 0x40, 0x0, 0x4a, + 0x36, 0xc5, 0x56, 0xb5, 0x50, 0x0, 0x3, 0x31, + 0xb5, 0x56, 0x90, 0x0, 0x14, 0x0, 0x50, 0x40, + 0xa0, 0x31, 0x0, 0x9, 0x61, 0x4c, 0x55, 0xc5, + 0x5c, 0x0, 0x1, 0x56, 0xb, 0x0, 0xa0, 0xa, + 0x0, 0x0, 0x7, 0xa, 0x55, 0xc5, 0x58, 0x0, + 0x0, 0x63, 0x6, 0x55, 0xc5, 0x68, 0x0, 0x17, + 0xd0, 0x0, 0x1, 0x90, 0x0, 0x40, 0x1, 0xb0, + 0x65, 0x5a, 0x89, 0x55, 0x51, 0x2, 0xb0, 0x0, + 0x39, 0x5, 0x70, 0x0, 0x1, 0x80, 0x6, 0x70, + 0x0, 0x4d, 0x92, 0x0, 0x0, 0x41, 0x0, 0x0, + 0x0, 0x10, + + /* U+6F38 "漸" */ + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0xc0, 0x0, 0x16, 0xc2, 0x0, 0x4a, + 0x65, 0xc5, 0x99, 0x51, 0x0, 0x0, 0x1, 0x10, + 0xb0, 0x28, 0x10, 0x0, 0x26, 0x4, 0xb5, 0xc5, + 0xd8, 0x10, 0x50, 0x8, 0x75, 0xb0, 0xb0, 0xb8, + 0x6c, 0x51, 0x1, 0x45, 0xb5, 0xc5, 0xb8, 0x1b, + 0x0, 0x0, 0x52, 0xb0, 0xb0, 0xb8, 0x1b, 0x0, + 0x0, 0xa0, 0x95, 0xc5, 0x69, 0xb, 0x0, 0x29, + 0xa3, 0x55, 0xc5, 0xa9, 0xb, 0x0, 0x4, 0x80, + 0x0, 0xb0, 0x9, 0xb, 0x0, 0x6, 0x80, 0x0, + 0xb0, 0x44, 0xb, 0x0, 0x4, 0x60, 0x0, 0xc1, + 0x60, 0xb, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, + 0x4, 0x0, + + /* U+6FC3 "濃" */ + 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x1, + 0x60, 0x2, 0xa, 0xa, 0x3, 0x0, 0x0, 0x78, + 0xb, 0x5c, 0x5c, 0x5c, 0x20, 0x0, 0x4, 0x4b, + 0x5c, 0x5c, 0x5c, 0x0, 0x7, 0x11, 0x4b, 0xa, + 0xa, 0xb, 0x0, 0x3, 0xc5, 0x18, 0x55, 0x55, + 0x58, 0x0, 0x0, 0x57, 0x1c, 0x55, 0x55, 0x56, + 0x30, 0x0, 0x26, 0xb, 0x45, 0x55, 0x57, 0x0, + 0x1, 0xa2, 0xc, 0x55, 0x55, 0x55, 0x90, 0x5, + 0xe0, 0x1a, 0x73, 0x60, 0x36, 0x0, 0x0, 0xc0, + 0x37, 0x73, 0x39, 0x71, 0x0, 0x1, 0xd0, 0x81, + 0x75, 0x55, 0xb4, 0x10, 0x0, 0x42, 0x40, 0x77, + 0x0, 0x2a, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6FDF "濟" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x2, + 0x60, 0x0, 0x1, 0xb0, 0x0, 0x10, 0x0, 0x95, + 0x46, 0x56, 0x66, 0x57, 0x80, 0x0, 0x12, 0x30, + 0xa, 0x2b, 0x15, 0x10, 0x27, 0x4, 0x3a, 0x98, + 0x93, 0x68, 0x10, 0x8, 0x76, 0xa, 0x64, 0xb4, + 0x68, 0x0, 0x0, 0x45, 0x36, 0x92, 0xa5, 0x97, + 0xa1, 0x0, 0x61, 0x65, 0x90, 0x62, 0x43, 0x61, + 0x0, 0xa0, 0xa, 0x75, 0x55, 0x5d, 0x0, 0x1a, + 0x90, 0xa, 0x10, 0x0, 0xc, 0x0, 0x5, 0x70, + 0xb, 0x55, 0x55, 0x5c, 0x0, 0x6, 0x70, 0x18, + 0x0, 0x0, 0xc, 0x0, 0x3, 0x41, 0x80, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x3, 0x0, + + /* U+7063 "灣" */ + 0x0, 0x0, 0x2, 0x1, 0x20, 0x2, 0x0, 0x2, + 0x50, 0x28, 0x10, 0x92, 0x9, 0x40, 0x0, 0xa4, + 0x97, 0x66, 0x57, 0x96, 0xa0, 0x0, 0x23, 0x34, + 0x26, 0x87, 0x17, 0x30, 0x16, 0x4, 0xa7, 0xa5, + 0x35, 0x89, 0x75, 0x7, 0x75, 0x33, 0x3a, 0x5b, + 0x23, 0x30, 0x1, 0x57, 0x99, 0x8a, 0x5b, 0x94, + 0x86, 0x0, 0x52, 0x16, 0x58, 0x57, 0x6a, 0x10, + 0x0, 0x90, 0x3, 0x22, 0x22, 0x2b, 0x0, 0x18, + 0xa0, 0xb, 0x33, 0x33, 0x37, 0x0, 0x4, 0x80, + 0x18, 0x55, 0x55, 0x5b, 0x50, 0x5, 0x70, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x4, 0x70, 0x0, 0x0, + 0x17, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+706B "火" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x10, 0x0, 0x0, 0x4, 0x0, 0xb3, + 0x0, 0xb6, 0x0, 0x0, 0x18, 0x0, 0xc3, 0x6, + 0x80, 0x0, 0x1, 0xc4, 0x0, 0xd4, 0x36, 0x0, + 0x0, 0x4, 0x70, 0x1, 0xc4, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x70, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x10, 0x47, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x9, 0x70, 0x0, 0x0, 0x8, 0x60, + 0x0, 0x0, 0xab, 0x40, 0x4, 0x72, 0x0, 0x0, + 0x0, 0x8, 0x80, 0x21, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+707D "災" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xb, 0x40, 0x59, 0x0, 0xa5, 0x0, 0x0, 0x45, + 0x0, 0x90, 0x3, 0x60, 0x0, 0x0, 0x70, 0x6, + 0x0, 0x7, 0x0, 0x0, 0x0, 0x67, 0x3, 0x90, + 0x6, 0x60, 0x0, 0x0, 0xb, 0x20, 0x58, 0x0, + 0x94, 0x0, 0x0, 0x1, 0x0, 0x32, 0x0, 0x11, + 0x0, 0x0, 0x2, 0x0, 0xa7, 0x0, 0x10, 0x0, + 0x0, 0x9, 0x0, 0xc6, 0x3, 0xb0, 0x0, 0x0, + 0x7a, 0x2, 0xb3, 0x76, 0x0, 0x0, 0x0, 0x10, + 0xb, 0x40, 0x82, 0x0, 0x0, 0x0, 0x0, 0x97, + 0x0, 0xc, 0x60, 0x0, 0x1, 0x69, 0x30, 0x0, + 0x0, 0x9e, 0x81, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+70B9 "点" */ + 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc5, 0x55, 0x6c, 0x10, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x59, 0x55, 0x5e, 0x10, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x8, + 0x0, 0x0, 0x30, 0x12, 0x2, 0x10, 0x14, 0x0, + 0x9, 0x0, 0xb1, 0xc, 0x0, 0x85, 0x9, 0x70, + 0x7, 0x10, 0x81, 0x2, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+70BA "為" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xa0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x61, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x75, 0x56, + 0xc5, 0x56, 0xb0, 0x0, 0x0, 0x0, 0x9, 0x30, + 0x6, 0x50, 0x0, 0x0, 0x0, 0x1c, 0x55, 0x59, + 0x6d, 0x10, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x47, + 0x0, 0x0, 0x6, 0x95, 0x55, 0x55, 0x96, 0xc1, + 0x0, 0x38, 0x0, 0x1, 0x3, 0x0, 0xb0, 0x2, + 0x72, 0x27, 0x6, 0x62, 0xa2, 0xa0, 0x13, 0xa, + 0x4, 0x90, 0xb0, 0x64, 0x80, 0x0, 0x6b, 0x0, + 0x50, 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x8e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, + + /* U+7121 "無" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x86, + 0x56, 0x56, 0xa2, 0x0, 0x6, 0xd0, 0xa0, 0xa0, + 0xb0, 0x0, 0x2, 0x3a, 0xa, 0xa, 0xb, 0x0, + 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0xb0, 0x70, 0x2, + 0x6c, 0x5c, 0x5c, 0x5c, 0x55, 0x10, 0x0, 0xa0, + 0xa0, 0xa0, 0xb0, 0x0, 0x0, 0xa, 0xa, 0xa, + 0xb, 0x3, 0x0, 0x65, 0x85, 0x85, 0x85, 0x85, + 0x93, 0x0, 0x40, 0x23, 0x1, 0x50, 0x16, 0x0, + 0x1a, 0x0, 0xb1, 0x9, 0x40, 0x86, 0xc, 0x50, + 0x8, 0x30, 0x35, 0x2, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7136 "然" */ + 0x0, 0x3, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0xb2, 0x50, 0x0, 0x0, 0x49, + 0x2, 0x20, 0xb1, 0x4b, 0x0, 0x0, 0xa6, 0x5a, + 0x80, 0xb0, 0x7, 0x0, 0x2, 0xa9, 0x2b, 0x56, + 0xd6, 0x5b, 0x40, 0x8, 0x73, 0x6b, 0x0, 0xc5, + 0x0, 0x0, 0x32, 0x67, 0x74, 0x1, 0xa5, 0x30, + 0x0, 0x0, 0x3, 0xa0, 0x8, 0x30, 0xb1, 0x0, + 0x0, 0x2a, 0x0, 0x57, 0x0, 0x4d, 0x40, 0x4, + 0x70, 0x5, 0x30, 0x0, 0x6, 0x50, 0x11, 0x40, + 0x31, 0x4, 0x10, 0x34, 0x0, 0x1, 0xa0, 0x1c, + 0x1, 0xc0, 0xb, 0x40, 0xb, 0x70, 0xc, 0x0, + 0xa0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7159 "煙" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x2, 0x65, 0x55, 0x55, 0xb3, 0x0, 0xc, + 0x0, 0x0, 0xb0, 0xb0, 0x0, 0x0, 0xc, 0x27, + 0x75, 0xc5, 0xd5, 0x90, 0x2, 0x1c, 0x92, 0xa0, + 0xb0, 0xb0, 0xb0, 0x8, 0x2d, 0x10, 0xa0, 0xb0, + 0xb0, 0xb0, 0x1d, 0xb, 0x0, 0xa0, 0xb0, 0xb0, + 0xb0, 0x0, 0xb, 0x0, 0xa5, 0x5a, 0x55, 0x60, + 0x0, 0x1b, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x39, 0xa2, 0x55, 0x5c, 0x59, 0x60, 0x0, 0x73, + 0x3b, 0x0, 0xb, 0x0, 0x0, 0x0, 0xa0, 0x2, + 0x0, 0xb, 0x0, 0x0, 0x7, 0x20, 0x5, 0x55, + 0x5c, 0x55, 0x97, 0x12, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+71B1 "熱" */ + 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x65, + 0xc6, 0x80, 0xb, 0x4, 0x0, 0x0, 0x0, 0xb0, + 0x24, 0x5c, 0x79, 0x0, 0x4, 0x77, 0x76, 0x72, + 0x19, 0x36, 0x0, 0x0, 0x96, 0x37, 0x92, 0x48, + 0x36, 0x0, 0x6, 0x20, 0xc0, 0x70, 0xb9, 0x38, + 0x0, 0x0, 0x65, 0xc7, 0x70, 0xb9, 0x6b, 0x2, + 0x0, 0x0, 0xb3, 0x46, 0x30, 0x18, 0xa2, 0x4, + 0xba, 0x62, 0x23, 0x0, 0x0, 0xb2, 0x1, 0x23, + 0x5, 0x1, 0x40, 0x24, 0x0, 0x0, 0x92, 0x7, + 0x50, 0xa3, 0xb, 0x40, 0x7, 0xa0, 0x2, 0x60, + 0x33, 0x4, 0x60, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+71DF "營" */ + 0x0, 0x0, 0x30, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x2b, 0x15, 0x2, 0xa1, 0x30, 0x0, 0x63, 0xc7, + 0x37, 0x4a, 0x84, 0x0, 0x6, 0x2c, 0x63, 0x86, + 0x94, 0x0, 0x0, 0x9, 0x12, 0x92, 0x90, 0x6b, + 0x0, 0x5, 0x22, 0x22, 0x62, 0x22, 0x64, 0x4, + 0x73, 0x43, 0x33, 0x36, 0x3a, 0x60, 0xa1, 0xc, + 0x55, 0x55, 0xd2, 0x30, 0x0, 0x0, 0xc5, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x32, + 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xd2, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, + 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x70, 0x0, + 0x0, 0x5, 0x0, + + /* U+722D "爭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x2, 0x35, 0x7a, 0xdc, 0x0, 0x1, 0x54, 0x47, + 0x21, 0x2, 0x50, 0x0, 0x8, 0x50, 0x3a, 0x0, + 0x94, 0x0, 0x0, 0x9, 0x0, 0x60, 0x53, 0x0, + 0x0, 0x5, 0x55, 0x57, 0x56, 0x5c, 0x0, 0x0, + 0x0, 0x1, 0x90, 0x1, 0xa0, 0x13, 0x65, 0x55, + 0x6b, 0x55, 0x5c, 0x86, 0x0, 0x0, 0x1, 0x90, + 0x1, 0xa0, 0x0, 0x6, 0x55, 0x6b, 0x55, 0x5a, + 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x8e, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, + 0x0, 0x0, 0x0, + + /* U+7236 "父" */ + 0x0, 0x0, 0x47, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x1, 0xd5, 0x0, 0x7, 0x60, 0x0, 0x0, 0xb, + 0x30, 0x0, 0x0, 0x7c, 0x0, 0x1, 0x81, 0x10, + 0x0, 0x5, 0x9, 0x50, 0x14, 0x0, 0x50, 0x0, + 0x1d, 0x10, 0x0, 0x0, 0x0, 0x52, 0x0, 0x85, + 0x0, 0x0, 0x0, 0x0, 0x9, 0x1, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x8a, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xab, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x76, 0xc3, 0x0, 0x0, 0x0, 0x2, + 0x94, 0x0, 0x3c, 0xc7, 0x30, 0x3, 0x75, 0x0, + 0x0, 0x0, 0x4a, 0x91, 0x12, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7238 "爸" */ + 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x1, 0xc4, 0x0, 0x6, 0x91, 0x0, 0x0, 0x29, + 0x41, 0x0, 0x77, 0x4d, 0x0, 0x3, 0x50, 0x7, + 0x39, 0x80, 0x2, 0x0, 0x0, 0x0, 0x4, 0xda, + 0x10, 0x0, 0x0, 0x0, 0x5, 0x96, 0x2, 0x8a, + 0x97, 0x63, 0x15, 0x68, 0x55, 0x55, 0x55, 0xb5, + 0x50, 0x0, 0xb, 0x0, 0xb0, 0x1, 0xa0, 0x0, + 0x0, 0xb, 0x0, 0xb0, 0x1, 0x90, 0x0, 0x0, + 0xb, 0x55, 0x85, 0x56, 0x90, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x5, 0x30, 0x0, 0x7, 0xba, 0xaa, + 0xaa, 0xad, 0x60, + + /* U+7247 "片" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x64, 0x0, 0xd, 0x0, 0x0, 0x0, 0x8, 0x40, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x83, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x8, 0x75, 0x55, 0xd5, 0x5b, + 0x70, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb6, + 0x55, 0x55, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x1b, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x1, 0xb0, + 0x0, 0x0, 0x83, 0x0, 0x0, 0x1b, 0x0, 0x0, + 0x28, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x6, 0x0, + 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, + + /* U+725B "牛" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x9, 0x50, 0xc, 0x0, + 0x17, 0x0, 0x0, 0xc5, 0x55, 0xd5, 0x55, 0x51, + 0x0, 0x73, 0x0, 0xc, 0x0, 0x0, 0x0, 0x15, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x4, 0x55, 0x55, + 0x5d, 0x55, 0x59, 0xc1, 0x10, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7260 "牠" */ + 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0xd, 0x0, 0x0, 0x5, 0x5b, + 0x0, 0x40, 0xb, 0x0, 0x0, 0x9, 0x4b, 0x0, + 0xb2, 0xb, 0x3, 0x0, 0xb, 0x5c, 0x93, 0xb0, + 0xc, 0x5c, 0x20, 0x8, 0xb, 0x5, 0xc5, 0x4b, + 0xa, 0x0, 0x51, 0xb, 0x1, 0xb0, 0xb, 0xb, + 0x0, 0x20, 0xb, 0x22, 0xb0, 0xb, 0xb, 0x0, + 0x0, 0x3d, 0x40, 0xb0, 0xb, 0x5c, 0x0, 0x2b, + 0x6b, 0x0, 0xb0, 0xb, 0x56, 0x0, 0x2, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0x40, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0x2, 0x70, 0x0, 0xb, 0x0, 0x5b, + 0x99, 0x9b, 0x90, 0x0, 0x7, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7269 "物" */ + 0x0, 0x2, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0xd, 0x30, 0x0, 0x0, 0x6, 0x7b, + 0x0, 0x2b, 0x0, 0x0, 0x0, 0x9, 0x2b, 0x11, + 0x88, 0x95, 0x95, 0xd1, 0xb, 0x5c, 0x66, 0x90, + 0xc0, 0xd0, 0xc0, 0x24, 0xb, 0x6, 0x15, 0x61, + 0xb0, 0xc0, 0x30, 0xb, 0x2, 0xa, 0x6, 0x70, + 0xc0, 0x0, 0xc, 0x62, 0x64, 0xb, 0x11, 0xb0, + 0x18, 0x9d, 0x2, 0x60, 0x3a, 0x2, 0xa0, 0x15, + 0xb, 0x4, 0x0, 0xb1, 0x4, 0x80, 0x0, 0xb, + 0x0, 0x8, 0x30, 0x6, 0x70, 0x0, 0xb, 0x0, + 0x63, 0x14, 0x2c, 0x30, 0x0, 0xb, 0x4, 0x0, + 0x3, 0xf8, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7279 "特" */ + 0x0, 0x4, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, + 0xc, 0x10, 0x0, 0xc0, 0x0, 0x0, 0x7, 0x3c, + 0x0, 0x55, 0xd5, 0x6b, 0x0, 0xb, 0x1c, 0x0, + 0x10, 0xc0, 0x0, 0x0, 0xc, 0x5d, 0x6a, 0x0, + 0xc0, 0x0, 0x20, 0x26, 0xc, 0x5, 0x55, 0x95, + 0x56, 0xa1, 0x40, 0xc, 0x2, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xc, 0x75, 0x55, 0x55, 0xd5, 0xc2, + 0x18, 0xbd, 0x0, 0x30, 0x0, 0xc0, 0x0, 0x7, + 0xc, 0x0, 0x66, 0x0, 0xc0, 0x0, 0x0, 0xc, + 0x0, 0x1c, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, + 0x2, 0x11, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x5e, 0x70, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+72AC "犬" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x4a, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x30, 0x30, 0x6, 0x55, 0x56, 0xd7, 0x55, + 0x57, 0x91, 0x0, 0x0, 0x4, 0x95, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x65, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x11, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x74, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0xc, 0x30, 0x0, 0x0, 0xa, 0x40, + 0x0, 0x1, 0xe8, 0x10, 0x3, 0x81, 0x0, 0x0, + 0x0, 0x1c, 0xb1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+72AF "犯" */ + 0x1, 0x10, 0xb, 0x21, 0x0, 0x3, 0x0, 0x0, + 0x54, 0x88, 0xd, 0x55, 0x5d, 0x20, 0x0, 0xa, + 0x80, 0xc, 0x0, 0xc, 0x0, 0x0, 0x47, 0x80, + 0xc, 0x0, 0xc, 0x0, 0x5, 0x40, 0xb0, 0xc, + 0x0, 0xc, 0x0, 0x0, 0x3, 0xf0, 0xc, 0x0, + 0xc, 0x0, 0x0, 0xa, 0xa2, 0xc, 0x5, 0x4d, + 0x0, 0x0, 0x82, 0x93, 0xc, 0x1, 0xb7, 0x0, + 0x6, 0x20, 0xa2, 0xc, 0x0, 0x0, 0x10, 0x0, + 0x0, 0xb1, 0xc, 0x0, 0x0, 0x60, 0x0, 0x0, + 0xd0, 0xc, 0x0, 0x0, 0xb1, 0x1, 0x8d, 0x50, + 0x8, 0xcb, 0xbb, 0xd2, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+72B6 "状" */ + 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0xc2, 0x40, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc0, 0x4d, 0x0, 0x6, 0x20, 0xc0, + 0x0, 0xc0, 0x8, 0x0, 0x1, 0xe0, 0xc0, 0x0, + 0xc0, 0x0, 0x70, 0x0, 0x91, 0xc5, 0x65, 0xd8, + 0x55, 0x61, 0x0, 0x0, 0xc0, 0x0, 0xc6, 0x0, + 0x0, 0x0, 0x6, 0xc0, 0x1, 0xa5, 0x10, 0x0, + 0x2, 0xa1, 0xc0, 0x5, 0x71, 0x70, 0x0, 0xd, + 0x20, 0xc0, 0xa, 0x10, 0xb0, 0x0, 0x0, 0x0, + 0xc0, 0x1a, 0x0, 0x6a, 0x0, 0x0, 0x0, 0xc0, + 0x91, 0x0, 0xd, 0x90, 0x0, 0x0, 0xd5, 0x30, + 0x0, 0x2, 0xc4, 0x0, 0x0, 0x21, 0x0, 0x0, + 0x0, 0x0, + + /* U+72C0 "狀" */ + 0x0, 0x0, 0x10, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x40, 0xb2, 0x0, 0xb3, 0x30, 0x0, 0x0, 0xc0, + 0xb0, 0x0, 0xb1, 0x3a, 0x0, 0x0, 0xb0, 0xb0, + 0x0, 0xb1, 0x8, 0x0, 0x0, 0xb0, 0xb1, 0x22, + 0xb3, 0x23, 0x90, 0x2, 0x95, 0xc1, 0x32, 0xc7, + 0x22, 0x20, 0x0, 0x0, 0xb0, 0x0, 0xb7, 0x0, + 0x0, 0x3, 0x55, 0xc0, 0x0, 0xb6, 0x20, 0x0, + 0x0, 0x82, 0xb0, 0x4, 0x72, 0x80, 0x0, 0x0, + 0xa0, 0xb0, 0x9, 0x20, 0xb1, 0x0, 0x0, 0x90, + 0xb0, 0x1a, 0x0, 0x5b, 0x0, 0x5, 0x30, 0xb0, + 0x91, 0x0, 0xb, 0xa0, 0x5, 0x0, 0xb5, 0x30, + 0x0, 0x1, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+72EC "独" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, + 0x20, 0x79, 0x0, 0xd, 0x0, 0x0, 0x0, 0x76, + 0xb0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1e, 0x30, + 0x85, 0x5d, 0x59, 0x20, 0x1, 0x85, 0x60, 0xc0, + 0xc, 0xc, 0x0, 0x15, 0x3, 0xb0, 0xc0, 0xc, + 0xc, 0x0, 0x0, 0xb, 0xc0, 0xc0, 0xc, 0xc, + 0x0, 0x0, 0x57, 0xb0, 0xc0, 0xc, 0xc, 0x0, + 0x1, 0xa0, 0xc0, 0xd5, 0x5d, 0x5c, 0x0, 0x7, + 0x0, 0xc0, 0x10, 0xc, 0x2, 0x0, 0x10, 0x0, + 0xd0, 0x0, 0xc, 0x8, 0x20, 0x0, 0x2, 0xb1, + 0x24, 0x5d, 0x65, 0xd0, 0x0, 0x8e, 0x35, 0xc7, + 0x30, 0x0, 0x90, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+72ED "狭" */ + 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x3, + 0x0, 0xb1, 0x4, 0xa0, 0x0, 0x0, 0x1, 0x87, + 0x50, 0x3, 0x80, 0x2, 0x0, 0x0, 0x7a, 0x6, + 0x57, 0xa5, 0x5a, 0x20, 0x4, 0x5a, 0x2, 0x3, + 0x80, 0x62, 0x0, 0x22, 0xa, 0x31, 0xb4, 0x70, + 0xb1, 0x0, 0x0, 0x2e, 0x50, 0xc5, 0x75, 0x20, + 0x0, 0x0, 0x95, 0x85, 0x68, 0x96, 0x59, 0x90, + 0x6, 0x33, 0x81, 0x8, 0x44, 0x0, 0x0, 0x32, + 0x4, 0x80, 0xc, 0x7, 0x0, 0x0, 0x0, 0x6, + 0x70, 0x56, 0x4, 0x70, 0x0, 0x3, 0x4c, 0x22, + 0xa0, 0x0, 0x98, 0x0, 0x0, 0xa5, 0x56, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+732B "猫" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x4, + 0x0, 0x67, 0xc, 0x20, 0xe1, 0x0, 0x0, 0x75, + 0xb0, 0xc, 0x0, 0xc0, 0x10, 0x0, 0x1e, 0x26, + 0x5d, 0x55, 0xd5, 0xb1, 0x1, 0x84, 0x60, 0xc, + 0x0, 0xc0, 0x0, 0x4, 0x3, 0xb0, 0x7, 0x0, + 0x61, 0x0, 0x0, 0xa, 0xb1, 0xb5, 0x77, 0x5a, + 0x60, 0x0, 0x46, 0xb1, 0x90, 0x56, 0x7, 0x40, + 0x1, 0x80, 0xb1, 0x90, 0x56, 0x7, 0x40, 0x15, + 0x0, 0xb1, 0xb5, 0x99, 0x5a, 0x40, 0x10, 0x0, + 0xc1, 0x90, 0x56, 0x7, 0x40, 0x1, 0x37, 0x81, + 0xb5, 0x99, 0x5a, 0x40, 0x0, 0x4c, 0x1, 0x80, + 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+733F "猿" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, + 0x0, 0x83, 0x0, 0xc2, 0x1, 0x0, 0x1, 0x74, + 0xb1, 0x65, 0xd5, 0x69, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0xc0, 0x0, 0x50, 0x1, 0x8a, 0x26, 0x55, + 0x65, 0x55, 0x60, 0x15, 0x7, 0x50, 0xb5, 0x55, + 0x5c, 0x0, 0x0, 0xd, 0x80, 0xb0, 0x0, 0xb, + 0x0, 0x0, 0x66, 0xa0, 0xd5, 0x76, 0x5b, 0x0, + 0x1, 0x81, 0xb0, 0x29, 0x46, 0x4, 0xb0, 0x7, + 0x2, 0xb0, 0x68, 0x8, 0x67, 0x0, 0x10, 0x4, + 0xa5, 0x97, 0x1, 0xc0, 0x0, 0x0, 0x8, 0x80, + 0x46, 0x42, 0x5c, 0x30, 0x1, 0x9e, 0x0, 0x5c, + 0x20, 0x4, 0xb2, 0x0, 0x1, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+7372 "獲" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x2, + 0x0, 0x63, 0x9, 0x20, 0xa3, 0x40, 0x2, 0x82, + 0xb4, 0x6b, 0x65, 0xb6, 0x61, 0x0, 0x2e, 0x10, + 0x55, 0x37, 0x30, 0x0, 0x0, 0x9a, 0x10, 0xd6, + 0x5a, 0x58, 0x50, 0x6, 0x16, 0x56, 0xc3, 0x3c, + 0x38, 0x0, 0x0, 0xb, 0x93, 0xb2, 0x2b, 0x27, + 0x0, 0x0, 0x48, 0xa0, 0xc5, 0x5c, 0x55, 0x40, + 0x0, 0x90, 0xb0, 0xc5, 0x56, 0x55, 0x60, 0x7, + 0x10, 0xb0, 0x66, 0x55, 0x7b, 0x0, 0x11, 0x1, + 0xa0, 0x5, 0x31, 0xb2, 0x0, 0x0, 0x4, 0x80, + 0x0, 0x9d, 0x20, 0x0, 0x1, 0x8d, 0x30, 0x17, + 0x86, 0xb7, 0x52, 0x0, 0x25, 0x14, 0x40, 0x0, + 0x4, 0x50, + + /* U+73A9 "玩" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x55, 0x6a, 0x15, 0x55, 0x59, 0x50, 0x1, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x31, 0x5, 0x5e, 0x95, 0x68, 0x75, + 0xa5, 0x85, 0x0, 0xd, 0x0, 0x8, 0x40, 0xc0, + 0x0, 0x0, 0xd, 0x0, 0xa, 0x20, 0xc0, 0x0, + 0x0, 0xd, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, + 0xd, 0x34, 0x1b, 0x0, 0xc0, 0x0, 0x16, 0x99, + 0x20, 0x75, 0x0, 0xc0, 0x22, 0x9, 0x10, 0x3, + 0xa0, 0x0, 0xc0, 0x44, 0x0, 0x0, 0x57, 0x0, + 0x0, 0xba, 0xd8, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+73FE "現" */ + 0x4, 0x55, 0x68, 0x85, 0x55, 0x58, 0x30, 0x1, + 0xb, 0x0, 0xb0, 0x0, 0x8, 0x20, 0x0, 0xb, + 0x0, 0xb5, 0x55, 0x5a, 0x20, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0x8, 0x20, 0x0, 0xb, 0x23, 0xb4, + 0x44, 0x4a, 0x20, 0x4, 0x6c, 0x53, 0xb0, 0x0, + 0x8, 0x20, 0x0, 0xb, 0x0, 0xb5, 0x55, 0x5a, + 0x20, 0x0, 0xb, 0x0, 0x82, 0xb0, 0xa4, 0x10, + 0x0, 0xb, 0x1, 0x6, 0x60, 0xa0, 0x0, 0x1, + 0x4d, 0x53, 0xc, 0x10, 0xa0, 0x40, 0x1c, 0x60, + 0x0, 0x76, 0x0, 0xa0, 0x70, 0x0, 0x0, 0x7, + 0x50, 0x0, 0xca, 0xd4, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, 0x0, + + /* U+7403 "球" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0x18, 0x10, 0x6, 0x57, + 0x77, 0x0, 0x1b, 0x6, 0x60, 0x0, 0x1a, 0x2, + 0x55, 0x6c, 0x55, 0xc4, 0x0, 0x1a, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x0, 0x1a, 0x13, 0x70, 0x1e, + 0x11, 0xb0, 0x5, 0x6c, 0x64, 0x96, 0x1b, 0x69, + 0x30, 0x0, 0x1a, 0x0, 0x12, 0x1b, 0x91, 0x0, + 0x0, 0x1a, 0x0, 0x2, 0x7b, 0x38, 0x0, 0x0, + 0x1c, 0x65, 0x87, 0x1b, 0xb, 0x60, 0xa, 0xb4, + 0x8, 0x50, 0x1b, 0x1, 0xe7, 0x4, 0x0, 0x0, + 0x1, 0x2a, 0x0, 0x10, 0x0, 0x0, 0x0, 0x5, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+7406 "理" */ + 0x0, 0x0, 0x0, 0x53, 0x33, 0x37, 0x10, 0x6, + 0x58, 0x85, 0xb1, 0x1b, 0x1b, 0x0, 0x0, 0xb, + 0x0, 0xa0, 0xa, 0xa, 0x0, 0x0, 0xb, 0x0, + 0xb5, 0x5c, 0x5c, 0x0, 0x0, 0xb, 0x21, 0xa0, + 0xa, 0xa, 0x0, 0x6, 0x6d, 0x74, 0xb0, 0xa, + 0xa, 0x0, 0x0, 0xb, 0x0, 0xb5, 0x5c, 0x5a, + 0x0, 0x0, 0xb, 0x0, 0x0, 0xa, 0x0, 0x0, + 0x0, 0xc, 0x54, 0x55, 0x5c, 0x5a, 0x20, 0x7, + 0xb8, 0x10, 0x0, 0xa, 0x0, 0x0, 0x6, 0x0, + 0x0, 0x0, 0xa, 0x0, 0x40, 0x0, 0x0, 0x36, + 0x55, 0x56, 0x55, 0x71, + + /* U+74B0 "環" */ + 0x0, 0x0, 0x40, 0x75, 0x55, 0x57, 0x40, 0x6, + 0x6b, 0x52, 0xa0, 0x90, 0x95, 0x30, 0x0, 0x19, + 0x0, 0xc5, 0xa5, 0xa8, 0x30, 0x0, 0x19, 0x0, + 0x20, 0x0, 0x0, 0x40, 0x4, 0x6b, 0xa6, 0x55, + 0x55, 0x55, 0x50, 0x1, 0x29, 0x0, 0x85, 0x55, + 0x5b, 0x0, 0x0, 0x19, 0x0, 0xa1, 0x0, 0x9, + 0x0, 0x0, 0x19, 0x0, 0xa6, 0xb7, 0x58, 0x20, + 0x0, 0x1a, 0x52, 0xa, 0x37, 0x16, 0x90, 0x9, + 0xb6, 0x0, 0x8d, 0x1, 0xc2, 0x0, 0x3, 0x0, + 0x26, 0x1b, 0x14, 0x2c, 0x60, 0x0, 0x0, 0x0, + 0xc, 0x80, 0x1, 0x70, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+7518 "甘" */ + 0x0, 0x0, 0x40, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x2, 0x80, 0x6, 0x55, 0xd5, 0x55, + 0x5d, 0x55, 0x51, 0x0, 0x0, 0xc0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5d, 0x0, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xe5, + 0x55, 0x5d, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0xb, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+751A "甚" */ + 0x0, 0x0, 0x40, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0xc, 0x10, 0x0, 0x2, 0x65, + 0xd5, 0x55, 0x5d, 0x5a, 0x50, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x5d, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, 0x5d, 0x0, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x20, + 0x17, 0x5a, 0x85, 0x55, 0x58, 0x55, 0x91, 0x0, + 0xc, 0x1, 0xc0, 0x35, 0x0, 0x0, 0x0, 0xc, + 0x9, 0x40, 0x7, 0xb0, 0x0, 0x0, 0xc, 0x64, + 0x0, 0x0, 0x90, 0x0, 0x0, 0xe, 0x75, 0x55, + 0x55, 0x5d, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+751F "生" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x10, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x80, 0x2a, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x2a, 0x0, 0x5, 0x0, 0x0, 0x49, 0x55, 0x6c, + 0x55, 0x58, 0x30, 0x0, 0x90, 0x0, 0x2a, 0x0, + 0x0, 0x0, 0x2, 0x50, 0x0, 0x2a, 0x0, 0x0, + 0x0, 0x5, 0x0, 0x0, 0x2a, 0x0, 0x54, 0x0, + 0x0, 0x5, 0x55, 0x6c, 0x55, 0x54, 0x0, 0x0, + 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x60, 0x6, 0x55, 0x55, 0x56, + 0x55, 0x56, 0x72, + + /* U+7522 "產" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x40, 0x0, 0x40, 0x0, 0x55, 0x67, + 0x55, 0x6d, 0x65, 0x0, 0x0, 0x0, 0x27, 0x89, + 0x30, 0x0, 0x0, 0x0, 0x25, 0x65, 0xb4, 0x0, + 0x0, 0x7, 0x67, 0x55, 0x56, 0xb5, 0xc2, 0x0, + 0xc0, 0x23, 0x7, 0x10, 0x0, 0x0, 0xb, 0x8, + 0x60, 0xb0, 0x1, 0x0, 0x0, 0xb0, 0xc5, 0x5c, + 0x55, 0x84, 0x0, 0xa, 0x62, 0x0, 0xb0, 0x1, + 0x0, 0x2, 0x72, 0x46, 0x5c, 0x55, 0x80, 0x0, + 0x61, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x6, 0x15, + 0x55, 0x5c, 0x55, 0x5a, 0x71, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+7523 "産" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x50, 0x0, 0x60, 0x0, 0x55, 0x75, + 0x55, 0x76, 0x56, 0x10, 0x0, 0x2, 0x90, 0x8, + 0x60, 0x0, 0x0, 0x20, 0x8, 0x0, 0x70, 0x4, + 0x0, 0xc, 0x55, 0x55, 0x85, 0x55, 0x62, 0x0, + 0xb0, 0x57, 0xb, 0x10, 0x0, 0x0, 0xb, 0xa, + 0x30, 0xb0, 0x2, 0x50, 0x0, 0xb1, 0xa5, 0x5c, + 0x55, 0x54, 0x0, 0x19, 0x60, 0x0, 0xb0, 0x5, + 0x0, 0x4, 0x60, 0x36, 0x5c, 0x55, 0x51, 0x0, + 0x70, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x6, 0x15, + 0x55, 0x5c, 0x55, 0x5b, 0x51, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+7528 "用" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x65, 0x55, 0x75, 0x55, 0xd1, 0x0, 0x83, 0x0, + 0xa, 0x0, 0xc, 0x0, 0x8, 0x30, 0x0, 0xa0, + 0x0, 0xc0, 0x0, 0x87, 0x55, 0x5c, 0x55, 0x5c, + 0x0, 0x8, 0x30, 0x0, 0xa0, 0x0, 0xc0, 0x0, + 0x93, 0x0, 0xa, 0x0, 0xc, 0x0, 0x9, 0x20, + 0x0, 0xa0, 0x0, 0xc0, 0x0, 0xb5, 0x55, 0x5c, + 0x55, 0x5c, 0x0, 0xc, 0x0, 0x0, 0xa0, 0x0, + 0xc0, 0x2, 0x80, 0x0, 0x1a, 0x0, 0xc, 0x0, + 0x71, 0x0, 0x1, 0xa0, 0x22, 0xd0, 0x6, 0x0, + 0x0, 0x17, 0x3, 0xc9, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+7530 "田" */ + 0x10, 0x0, 0x0, 0x0, 0x10, 0xc5, 0x55, 0xa6, + 0x55, 0xa6, 0xc0, 0x0, 0xa1, 0x0, 0x84, 0xc0, + 0x0, 0xa1, 0x0, 0x84, 0xc0, 0x0, 0xa1, 0x0, + 0x84, 0xc5, 0x55, 0xc6, 0x55, 0xa4, 0xc0, 0x0, + 0xa1, 0x0, 0x84, 0xc0, 0x0, 0xa1, 0x0, 0x84, + 0xc0, 0x0, 0xa1, 0x0, 0x84, 0xc0, 0x0, 0xa1, + 0x0, 0x84, 0xc5, 0x55, 0x55, 0x55, 0xa4, 0x40, + 0x0, 0x0, 0x0, 0x20, + + /* U+7531 "由" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x30, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, + 0x2, 0x0, 0xa, 0x10, 0x0, 0x40, 0xc5, 0x55, + 0xc6, 0x55, 0x5e, 0x1c, 0x0, 0xa, 0x10, 0x0, + 0xc0, 0xc0, 0x0, 0xa1, 0x0, 0xc, 0xc, 0x0, + 0xa, 0x10, 0x0, 0xc0, 0xc5, 0x55, 0xc6, 0x55, + 0x5c, 0xc, 0x0, 0xa, 0x10, 0x0, 0xc0, 0xc0, + 0x0, 0xa1, 0x0, 0xc, 0xc, 0x0, 0xa, 0x10, + 0x0, 0xc0, 0xc5, 0x55, 0x55, 0x55, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7533 "申" */ + 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0x0, 0x0, 0x20, 0x0, 0xb0, 0x0, 0x30, 0xc5, + 0x55, 0xc5, 0x55, 0xd3, 0xc0, 0x0, 0xb0, 0x0, + 0xb0, 0xc5, 0x55, 0xc5, 0x55, 0xc0, 0xc0, 0x0, + 0xb0, 0x0, 0xb0, 0xc0, 0x0, 0xb0, 0x0, 0xb0, + 0xc5, 0x55, 0xc5, 0x55, 0xc1, 0xb0, 0x0, 0xb0, + 0x0, 0x70, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + + /* U+7535 "电" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0xa5, 0x55, 0xd5, 0x55, 0xb4, 0x0, + 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0xc0, 0x0, 0xc0, 0x0, 0xc5, 0x55, 0xd5, 0x55, + 0xd0, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xd5, 0x55, + 0xd5, 0x55, 0xa0, 0x10, 0x30, 0x0, 0xc0, 0x0, + 0x0, 0x50, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xa0, + 0x0, 0x0, 0x8b, 0xaa, 0xab, 0xd0, + + /* U+7537 "男" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xc5, + 0x55, 0xa5, 0x5c, 0x20, 0x0, 0xb0, 0x1, 0xa0, + 0xb, 0x0, 0x0, 0xc5, 0x55, 0xc5, 0x5c, 0x0, + 0x0, 0xb0, 0x1, 0xa0, 0xb, 0x0, 0x0, 0xd5, + 0x55, 0xc5, 0x5c, 0x10, 0x0, 0x80, 0x1, 0x80, + 0x5, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x30, + 0x6, 0x55, 0x59, 0x95, 0x55, 0xe1, 0x0, 0x0, + 0xa, 0x20, 0x1, 0xb0, 0x0, 0x0, 0x3a, 0x0, + 0x4, 0x80, 0x0, 0x4, 0xa0, 0x4, 0x8, 0x40, + 0x4, 0x86, 0x0, 0x1, 0xdc, 0x0, 0x31, 0x0, + 0x0, 0x0, 0x10, 0x0, + + /* U+753A "町" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x24, 0xb, 0x5a, + 0x5c, 0x56, 0x5b, 0x65, 0x50, 0xb0, 0xb0, 0xa0, + 0x0, 0xa2, 0x0, 0xb, 0xb, 0xa, 0x0, 0xa, + 0x20, 0x0, 0xb0, 0xb0, 0xa0, 0x0, 0xa2, 0x0, + 0xb, 0x5c, 0x5c, 0x0, 0xa, 0x20, 0x0, 0xb0, + 0xb0, 0xa0, 0x0, 0xa2, 0x0, 0xb, 0xb, 0xa, + 0x0, 0xa, 0x20, 0x0, 0xb0, 0xb0, 0xa0, 0x0, + 0xa2, 0x0, 0xc, 0x55, 0x5c, 0x10, 0xa, 0x20, + 0x0, 0x60, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xae, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x20, 0x0, 0x0, + + /* U+753B "画" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x65, + 0x55, 0x55, 0x55, 0x59, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0x56, 0x59, + 0x40, 0x0, 0x1, 0xc, 0x0, 0xa0, 0xb0, 0x8, + 0x1, 0xb0, 0xb0, 0xa, 0xb, 0x0, 0xb0, 0x1a, + 0xc, 0x55, 0xc5, 0xc0, 0xb, 0x1, 0xa0, 0xb0, + 0xa, 0xb, 0x0, 0xb0, 0x1a, 0xb, 0x0, 0xa0, + 0xb0, 0xb, 0x1, 0xa0, 0xb0, 0xa, 0xb, 0x0, + 0xb0, 0x1a, 0xc, 0x55, 0x55, 0xa0, 0xb, 0x3, + 0xb5, 0x55, 0x55, 0x55, 0x55, 0xb0, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x0, + + /* U+754C "界" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x55, 0x57, 0x55, 0x97, 0x0, 0x0, 0xb, + 0x0, 0x19, 0x0, 0x74, 0x0, 0x0, 0xc, 0x55, + 0x6b, 0x55, 0x94, 0x0, 0x0, 0xb, 0x0, 0x19, + 0x0, 0x74, 0x0, 0x0, 0xc, 0x55, 0xb7, 0x75, + 0x94, 0x0, 0x0, 0x1, 0x7, 0x70, 0x34, 0x0, + 0x0, 0x0, 0x0, 0x7b, 0x0, 0x7, 0x93, 0x0, + 0x0, 0x29, 0x4a, 0x40, 0x2b, 0x2a, 0xe3, 0x4, + 0x30, 0xc, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x1, 0xa1, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7559 "留" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x22, + 0x69, 0x80, 0x0, 0x0, 0x40, 0xc, 0x20, 0x0, + 0x6a, 0x95, 0x6b, 0x0, 0xb0, 0x17, 0x10, 0x93, + 0x3, 0x80, 0xb, 0x1, 0x7d, 0x1b, 0x0, 0x56, + 0x1, 0xd9, 0x60, 0x49, 0x22, 0x6b, 0x30, 0x7, + 0x0, 0x16, 0x20, 0x3, 0x70, 0x0, 0x59, 0x55, + 0x59, 0x55, 0x6c, 0x0, 0x4, 0x80, 0x1, 0xb0, + 0x1, 0xa0, 0x0, 0x4a, 0x55, 0x6c, 0x55, 0x6a, + 0x0, 0x4, 0x80, 0x1, 0xb0, 0x1, 0xa0, 0x0, + 0x48, 0x0, 0x1b, 0x0, 0x1b, 0x0, 0x5, 0xa5, + 0x55, 0x65, 0x56, 0xb0, 0x0, 0x11, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+756A "番" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x24, 0x79, 0xbb, 0x10, 0x0, 0x36, 0x64, + 0xa2, 0x9, 0x10, 0x0, 0x0, 0xb, 0x9, 0x24, + 0x60, 0x0, 0x6, 0x55, 0x88, 0xc8, 0x75, 0x57, + 0x40, 0x0, 0x4, 0x99, 0x27, 0x0, 0x0, 0x0, + 0x6, 0x60, 0x92, 0x9, 0x71, 0x0, 0x26, 0x40, + 0x8, 0x10, 0x8, 0xd7, 0x11, 0xb, 0x55, 0x97, + 0x55, 0xd2, 0x0, 0x0, 0xb0, 0x7, 0x40, 0xb, + 0x0, 0x0, 0xb, 0x55, 0xa7, 0x55, 0xc0, 0x0, + 0x0, 0xb0, 0x7, 0x40, 0xb, 0x0, 0x0, 0xb, + 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+756B "畫" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0x0, 0x30, 0x0, 0x0, 0x6, + 0x55, 0x6b, 0x55, 0xd1, 0x20, 0x3, 0x65, 0x55, + 0x6b, 0x55, 0xc5, 0x70, 0x0, 0x7, 0x55, 0x6b, + 0x55, 0xc0, 0x0, 0x0, 0x5, 0x55, 0x6b, 0x55, + 0x76, 0x0, 0x0, 0x23, 0x22, 0x3a, 0x22, 0x25, + 0x20, 0x0, 0x45, 0x33, 0x33, 0x33, 0x53, 0x10, + 0x0, 0xd, 0x55, 0x6b, 0x55, 0xb4, 0x0, 0x0, + 0xc, 0x55, 0x6b, 0x55, 0xb1, 0x0, 0x0, 0xb, + 0x0, 0x29, 0x0, 0xa1, 0x0, 0x0, 0xc, 0x55, + 0x55, 0x55, 0x91, 0x10, 0x5, 0x55, 0x55, 0x55, + 0x55, 0x58, 0xe1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7570 "異" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x55, 0x57, 0x55, 0xa5, 0x0, 0x0, 0xb0, 0x0, + 0xb0, 0x9, 0x10, 0x0, 0xc, 0x55, 0x5c, 0x55, + 0xb1, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x9, 0x10, + 0x0, 0xd, 0x55, 0x58, 0x55, 0xb2, 0x0, 0x0, + 0x21, 0xb0, 0x8, 0x20, 0x0, 0x0, 0x65, 0x6c, + 0x55, 0xa6, 0x5a, 0x10, 0x0, 0x1, 0xa0, 0x8, + 0x10, 0x0, 0x3, 0x55, 0x6c, 0x55, 0xa6, 0x57, + 0x80, 0x10, 0x0, 0x91, 0x4, 0x30, 0x0, 0x0, + 0x4, 0xb7, 0x10, 0x4, 0xb5, 0x0, 0x37, 0x50, + 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, + + /* U+7576 "當" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x6, + 0x10, 0x1b, 0x3, 0x70, 0x0, 0x0, 0x39, 0x0, + 0xa0, 0x92, 0x0, 0x0, 0x75, 0x65, 0x5b, 0x67, + 0x55, 0xa0, 0x29, 0x0, 0x0, 0x0, 0x10, 0x74, + 0x6, 0x40, 0xb5, 0x55, 0x5c, 0x22, 0x0, 0x0, + 0xb, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xc5, + 0x55, 0x5c, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, + 0x2, 0x30, 0x0, 0x1c, 0x55, 0x5c, 0x55, 0xa7, + 0x0, 0x1, 0xc5, 0x55, 0xc5, 0x5a, 0x40, 0x0, + 0x1a, 0x0, 0xb, 0x0, 0x74, 0x0, 0x1, 0xc5, + 0x55, 0xc5, 0x5a, 0x40, 0x0, 0x15, 0x0, 0x0, + 0x0, 0x42, 0x0, + + /* U+75B2 "疲" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x9, + 0x55, 0x58, 0x85, 0x56, 0xc1, 0x2, 0xb, 0x0, + 0x0, 0x91, 0x0, 0x0, 0x8, 0x2b, 0x6, 0x55, + 0xd5, 0x58, 0x40, 0x5, 0x4b, 0xb, 0x0, 0xb0, + 0x9, 0x20, 0x0, 0xb, 0xb, 0x0, 0xb0, 0x1, + 0x0, 0x16, 0x7b, 0xb, 0x55, 0xb5, 0x79, 0x0, + 0x15, 0xa, 0xb, 0x5, 0x0, 0xa3, 0x0, 0x0, + 0x47, 0xb, 0x3, 0x44, 0x90, 0x0, 0x0, 0x92, + 0x55, 0x0, 0x9b, 0x0, 0x0, 0x1, 0x80, 0x90, + 0x4, 0x99, 0x83, 0x0, 0x6, 0x6, 0x13, 0x63, + 0x0, 0x3a, 0xc1, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+75C5 "病" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0xc, 0x55, + 0x56, 0x65, 0x58, 0x60, 0x60, 0xc0, 0x0, 0x0, + 0x0, 0x20, 0x8, 0x3c, 0x26, 0x55, 0xb5, 0x58, + 0x20, 0x10, 0xb0, 0x0, 0xd, 0x0, 0x0, 0x1, + 0x6b, 0x9, 0x55, 0xd5, 0x5b, 0x22, 0xb1, 0xa0, + 0xb0, 0x2a, 0x0, 0xc0, 0x0, 0x28, 0xb, 0x6, + 0x86, 0xc, 0x0, 0x6, 0x40, 0xb0, 0xa0, 0x76, + 0xc0, 0x0, 0x90, 0xb, 0x61, 0x1, 0x6c, 0x0, + 0x26, 0x0, 0xb0, 0x0, 0x10, 0xc0, 0x6, 0x0, + 0xb, 0x0, 0x3, 0xcc, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, + + /* U+75DB "痛" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0x90, 0x0, 0x10, 0x0, 0x9, + 0x55, 0x55, 0x85, 0x58, 0x90, 0x7, 0xa, 0x15, + 0x55, 0x55, 0x57, 0x0, 0x7, 0x6a, 0x10, 0x3, + 0x23, 0x85, 0x0, 0x3, 0x3a, 0x13, 0x0, 0xc3, + 0x3, 0x0, 0x0, 0xb, 0x1c, 0x55, 0xc5, 0x5b, + 0x30, 0x3, 0x8c, 0xb, 0x0, 0xb0, 0xa, 0x10, + 0x3a, 0xb, 0xb, 0x55, 0xc5, 0x5b, 0x10, 0x0, + 0x19, 0xb, 0x55, 0xc5, 0x5b, 0x10, 0x0, 0x73, + 0xb, 0x0, 0xb0, 0xa, 0x10, 0x1, 0x80, 0xb, + 0x0, 0xb0, 0x1a, 0x10, 0x6, 0x0, 0xb, 0x0, + 0x90, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+767A "発" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x65, 0x55, 0xd5, 0x12, 0xc1, 0x0, 0x0, 0x15, + 0x7, 0x70, 0x76, 0x4, 0x10, 0x0, 0xa, 0x3a, + 0x0, 0x54, 0x48, 0x20, 0x0, 0x3, 0xa0, 0x0, + 0x8, 0xa1, 0x0, 0x0, 0x58, 0x55, 0x55, 0x58, + 0xad, 0xb1, 0x4, 0x10, 0x1b, 0x0, 0xb0, 0x0, + 0x10, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, 0x0, + 0x2, 0x55, 0x5c, 0x55, 0xc5, 0x58, 0x70, 0x0, + 0x10, 0xb, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x65, 0x0, 0xb0, 0x0, 0x30, 0x0, 0x3, 0x80, + 0x0, 0xb0, 0x0, 0x70, 0x2, 0x64, 0x0, 0x0, + 0x9a, 0x9b, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+767C "發" */ + 0x0, 0x0, 0x4, 0x10, 0x21, 0x0, 0x0, 0x46, + 0x59, 0xb2, 0x38, 0x11, 0x0, 0x3, 0x73, 0xa0, + 0x5, 0x25, 0x70, 0x0, 0x7, 0x80, 0x0, 0x4, + 0x91, 0x0, 0x36, 0x86, 0xa0, 0x18, 0x5a, 0x8a, + 0x21, 0x0, 0xb, 0x2, 0x80, 0xb0, 0x0, 0x4, + 0x22, 0xb0, 0x55, 0xc, 0x1, 0x0, 0xc2, 0x25, + 0x8, 0x0, 0x69, 0x91, 0xd, 0x55, 0x93, 0x26, + 0x46, 0xb0, 0x0, 0x30, 0xc, 0x1, 0x10, 0xa3, + 0x0, 0x0, 0x2, 0xa0, 0x3, 0x98, 0x0, 0x0, + 0x0, 0x57, 0x0, 0x57, 0x97, 0x0, 0x2, 0x9d, + 0x22, 0x53, 0x0, 0xa4, 0x0, 0x1, 0x10, 0x10, + 0x0, 0x0, 0x0, + + /* U+767D "白" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x3e, + 0x10, 0x0, 0x0, 0x0, 0x9, 0x20, 0x0, 0x0, + 0x7, 0x56, 0x85, 0x55, 0x56, 0xc0, 0xa2, 0x0, + 0x0, 0x0, 0x1a, 0x9, 0x20, 0x0, 0x0, 0x1, + 0xa0, 0x92, 0x0, 0x0, 0x0, 0x1a, 0x9, 0x75, + 0x55, 0x55, 0x56, 0xa0, 0x92, 0x0, 0x0, 0x0, + 0x1a, 0x9, 0x20, 0x0, 0x0, 0x1, 0xa0, 0x92, + 0x0, 0x0, 0x0, 0x1a, 0xa, 0x75, 0x55, 0x55, + 0x56, 0xa0, 0xa2, 0x0, 0x0, 0x0, 0x19, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+767E "百" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x55, + 0x55, 0x55, 0x55, 0x59, 0x90, 0x10, 0x0, 0xb, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x85, 0x77, 0x55, 0x5b, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd5, 0x55, 0x55, + 0x5d, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xd, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7684 "的" */ + 0x0, 0x11, 0x0, 0x1, 0x10, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x70, 0x0, + 0xb, 0x30, 0x0, 0x1, 0xa7, 0x5b, 0x42, 0xd5, + 0x56, 0xb0, 0x1b, 0x0, 0xb0, 0x92, 0x0, 0x3a, + 0x0, 0xb0, 0xb, 0x35, 0x0, 0x3, 0x90, 0xb, + 0x0, 0xb2, 0x25, 0x0, 0x39, 0x0, 0xc5, 0x5c, + 0x0, 0xa3, 0x4, 0x90, 0xb, 0x0, 0xb0, 0x5, + 0x40, 0x48, 0x0, 0xb0, 0xb, 0x0, 0x0, 0x5, + 0x70, 0xb, 0x0, 0xb0, 0x0, 0x0, 0x66, 0x1, + 0xc5, 0x5c, 0x0, 0x14, 0x2b, 0x40, 0x19, 0x0, + 0x70, 0x0, 0x2d, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7686 "皆" */ + 0x20, 0x0, 0x4, 0x0, 0x0, 0x0, 0xb1, 0x0, + 0xb, 0x20, 0x57, 0x0, 0xb5, 0x5b, 0x2b, 0x8, + 0x82, 0x0, 0xb0, 0x0, 0xb, 0x40, 0x0, 0x30, + 0xb0, 0x35, 0x1b, 0x0, 0x0, 0x80, 0xdb, 0x41, + 0x39, 0xa9, 0x99, 0xe1, 0x10, 0x4, 0x70, 0x11, + 0x11, 0x0, 0x8, 0x59, 0x55, 0x55, 0xa0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xd, 0x55, + 0x55, 0x55, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0xd, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+76BF "皿" */ + 0x0, 0x75, 0x56, 0x55, 0x55, 0xa2, 0x0, 0x0, + 0xc0, 0xb, 0x2, 0x90, 0xc0, 0x0, 0x0, 0xc0, + 0xb, 0x2, 0x90, 0xc0, 0x0, 0x0, 0xc0, 0xb, + 0x2, 0x90, 0xc0, 0x0, 0x0, 0xc0, 0xb, 0x2, + 0x90, 0xc0, 0x0, 0x0, 0xc0, 0xb, 0x2, 0x90, + 0xc0, 0x0, 0x0, 0xc0, 0xb, 0x2, 0x90, 0xc0, + 0x0, 0x0, 0xc0, 0xb, 0x2, 0x90, 0xc0, 0x0, + 0x0, 0xc0, 0xb, 0x2, 0x90, 0xc1, 0x40, 0x26, + 0x65, 0x56, 0x55, 0x65, 0x66, 0x60, + + /* U+76D7 "盗" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x63, + 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0xd0, 0x44, + 0xc5, 0x55, 0x84, 0x0, 0x1, 0x62, 0xa0, 0x62, + 0x9, 0x20, 0x0, 0x38, 0x61, 0xd, 0x41, 0x0, + 0x0, 0x6e, 0x10, 0x5, 0x87, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0xc1, 0x2a, 0x0, 0x0, 0x3b, 0x2, + 0x92, 0x0, 0x6e, 0x40, 0x0, 0x31, 0x30, 0x0, + 0x3, 0x30, 0x0, 0xc, 0x5c, 0x65, 0xc5, 0xb4, + 0x0, 0x0, 0xb0, 0xa1, 0xb, 0x9, 0x10, 0x0, + 0xb, 0xa, 0x10, 0xb0, 0x91, 0x0, 0x35, 0xc5, + 0xc6, 0x5c, 0x5b, 0x8b, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+76EE "目" */ + 0x85, 0x55, 0x55, 0x5a, 0x1d, 0x0, 0x0, 0x0, + 0xd0, 0xd0, 0x0, 0x0, 0xd, 0xd, 0x0, 0x0, + 0x0, 0xd0, 0xd5, 0x55, 0x55, 0x5d, 0xd, 0x0, + 0x0, 0x0, 0xd0, 0xd0, 0x0, 0x0, 0xd, 0xd, + 0x55, 0x55, 0x55, 0xd0, 0xd0, 0x0, 0x0, 0xd, + 0xd, 0x0, 0x0, 0x0, 0xd0, 0xd5, 0x55, 0x55, + 0x5d, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+76F4 "直" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x0, 0x2, 0x0, 0x4, 0x65, + 0x55, 0xa8, 0x55, 0x5a, 0x40, 0x0, 0x1, 0x0, + 0xa1, 0x0, 0x20, 0x0, 0x0, 0xc, 0x55, 0x75, + 0x56, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, + 0xa0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x56, 0xa0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, 0xa0, 0x0, + 0x0, 0xc, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x1, 0xa1, 0x60, 0x16, 0x56, 0x55, 0x55, + 0x55, 0x65, 0x61, + + /* U+76F8 "相" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa4, 0x0, 0x10, 0x0, 0x30, 0x0, 0x9, 0x10, + 0xd, 0x55, 0x5d, 0x30, 0x0, 0x91, 0x20, 0xc0, + 0x0, 0xc0, 0x6, 0x5d, 0x67, 0x4c, 0x0, 0xc, + 0x0, 0x0, 0xf2, 0x0, 0xc5, 0x55, 0xd0, 0x0, + 0x5f, 0x97, 0xc, 0x0, 0xc, 0x0, 0xa, 0xa1, + 0xb0, 0xc0, 0x0, 0xc0, 0x3, 0x79, 0x10, 0xc, + 0x55, 0x5d, 0x0, 0x80, 0x91, 0x0, 0xc0, 0x0, + 0xc0, 0x31, 0xa, 0x10, 0xc, 0x0, 0xc, 0x0, + 0x0, 0xa2, 0x0, 0xd5, 0x55, 0xd0, 0x0, 0xa, + 0x20, 0xc, 0x0, 0xa, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+770B "看" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x13, 0x57, 0x9b, 0xb5, 0x0, 0x1, 0x44, + 0x43, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x65, 0x58, + 0xb5, 0x55, 0xa4, 0x0, 0x0, 0x0, 0xb, 0x20, + 0x0, 0x0, 0x40, 0x17, 0x55, 0x7b, 0x55, 0x55, + 0x56, 0x92, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x30, + 0x0, 0x0, 0x7, 0xe5, 0x55, 0x55, 0xd0, 0x0, + 0x0, 0x45, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x4, + 0x40, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x11, 0x0, + 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, + 0x60, 0x0, + + /* U+771F "真" */ + 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x1, 0x30, 0x0, 0x65, + 0x55, 0x8a, 0x55, 0x56, 0x70, 0x0, 0x0, 0x0, + 0x56, 0x0, 0x30, 0x0, 0x0, 0x1, 0xc5, 0x65, + 0x56, 0xc0, 0x0, 0x0, 0x1, 0xc5, 0x55, 0x56, + 0x90, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x2, 0x90, + 0x0, 0x0, 0x1, 0xc5, 0x55, 0x56, 0x90, 0x0, + 0x0, 0x1, 0xc5, 0x55, 0x56, 0x90, 0x0, 0x0, + 0x1, 0xb0, 0x0, 0x2, 0x90, 0x52, 0x6, 0x55, + 0x6a, 0x55, 0x86, 0x65, 0x64, 0x0, 0x0, 0x89, + 0x10, 0x8, 0x91, 0x0, 0x0, 0x28, 0x30, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+7720 "眠" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x30, 0xa5, 0x55, 0x5c, 0x20, 0xc5, 0x5c, 0xb, + 0x0, 0x0, 0xc0, 0xb, 0x1, 0xa0, 0xb0, 0x0, + 0xc, 0x0, 0xb0, 0x1a, 0xc, 0x59, 0x55, 0xd0, + 0xc, 0x55, 0xa0, 0xb0, 0x91, 0x0, 0x0, 0xb0, + 0x1a, 0xb, 0x8, 0x30, 0x37, 0xc, 0x55, 0xa0, + 0xc4, 0x88, 0x44, 0x41, 0xb0, 0x1a, 0xb, 0x3, + 0x90, 0x0, 0xb, 0x1, 0xa0, 0xb0, 0xc, 0x0, + 0x3, 0xc5, 0x5b, 0xb, 0x23, 0x5a, 0x1, 0x5b, + 0x0, 0x70, 0xe7, 0x0, 0x8b, 0x84, 0x0, 0x0, + 0x8, 0x0, 0x0, 0x5e, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+773E "眾" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xb, 0x55, + 0xa5, 0x5b, 0x55, 0xd2, 0xb, 0x0, 0xa0, 0xe, + 0x0, 0xb0, 0xb, 0x0, 0xa0, 0xe, 0x0, 0xb0, + 0xb, 0x55, 0x55, 0x55, 0x55, 0x90, 0x0, 0x0, + 0x0, 0x14, 0x7b, 0xb0, 0x4, 0x55, 0x6a, 0x94, + 0x32, 0x10, 0x0, 0x46, 0x5, 0x50, 0x9, 0x0, + 0x0, 0x93, 0x5, 0x50, 0x3a, 0x0, 0x0, 0xc7, + 0x5, 0x50, 0x9a, 0x0, 0x8, 0x23, 0xc5, 0x52, + 0x91, 0x80, 0x43, 0x0, 0x65, 0x77, 0x0, 0x78, + 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, + + /* U+7740 "着" */ + 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x67, 0x0, 0x0, 0x3, 0x55, + 0x5c, 0x55, 0x95, 0x5c, 0x30, 0x1, 0x0, 0x0, + 0xc0, 0x0, 0x20, 0x0, 0x0, 0x36, 0x58, 0xa5, + 0x57, 0x90, 0x0, 0x0, 0x0, 0xb, 0x10, 0x0, + 0x4, 0x40, 0x16, 0x55, 0xa8, 0x55, 0x55, 0x55, + 0x40, 0x0, 0x3, 0xe5, 0x55, 0x55, 0xb0, 0x0, + 0x0, 0x39, 0x92, 0x0, 0x0, 0xb0, 0x0, 0x4, + 0x60, 0x96, 0x55, 0x55, 0xb0, 0x0, 0x21, 0x0, + 0x96, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x0, 0x92, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x96, 0x55, + 0x55, 0xb0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x20, 0x0, + + /* U+77E5 "知" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, 0x66, + 0xb0, 0x95, 0x55, 0xc0, 0x0, 0x80, 0xc0, 0x0, + 0xb0, 0x0, 0xb0, 0x5, 0x10, 0xc0, 0x0, 0xb0, + 0x0, 0xb0, 0x1, 0x0, 0xc0, 0x62, 0xb0, 0x0, + 0xb0, 0x6, 0x55, 0xd5, 0x53, 0xb0, 0x0, 0xb0, + 0x0, 0x2, 0xc0, 0x0, 0xb0, 0x0, 0xb0, 0x0, + 0x7, 0x59, 0x30, 0xb0, 0x0, 0xb0, 0x0, 0xb, + 0x1, 0xd2, 0xc5, 0x55, 0xb0, 0x0, 0x82, 0x0, + 0x64, 0xb0, 0x0, 0xb0, 0x6, 0x30, 0x0, 0x0, + 0x50, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+77ED "短" */ + 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x97, 0x0, 0x55, 0x55, 0x58, 0x60, 0x0, 0xc0, + 0x1, 0x10, 0x0, 0x0, 0x0, 0x3, 0xba, 0x69, + 0x0, 0x0, 0x1, 0x0, 0x8, 0x1c, 0x0, 0xc, + 0x55, 0x5d, 0x0, 0x3, 0xc, 0x0, 0xb, 0x0, + 0xb, 0x0, 0x3, 0x3d, 0x39, 0x2b, 0x0, 0xb, + 0x0, 0x3, 0x2c, 0x22, 0x1c, 0x55, 0x5b, 0x0, + 0x0, 0xd, 0x10, 0x6, 0x0, 0x34, 0x0, 0x0, + 0x29, 0x83, 0x8, 0x0, 0xa5, 0x0, 0x0, 0x73, + 0x1b, 0x7, 0x50, 0xa0, 0x0, 0x0, 0x90, 0x2, + 0x3, 0x21, 0x50, 0x30, 0x6, 0x10, 0x5, 0x55, + 0x56, 0x55, 0x91, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+77F3 "石" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x30, 0x6, + 0x55, 0x59, 0xa5, 0x55, 0x55, 0x50, 0x0, 0x0, + 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xd5, 0x55, 0x55, + 0xc3, 0x0, 0x0, 0x48, 0xc0, 0x0, 0x0, 0xc0, + 0x0, 0x2, 0x70, 0xc0, 0x0, 0x0, 0xc0, 0x0, + 0x24, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xc5, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7802 "砂" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x0, 0xd, 0x0, 0x0, 0x7, 0x79, + 0x67, 0x0, 0xb, 0x0, 0x0, 0x0, 0x74, 0x0, + 0x27, 0xb, 0x22, 0x0, 0x0, 0xa0, 0x0, 0x68, + 0xb, 0x9, 0x60, 0x0, 0xb0, 0x40, 0xa1, 0xc, + 0x1, 0xe0, 0x5, 0xe5, 0xc3, 0x80, 0xc, 0x0, + 0x20, 0x7, 0xb0, 0xa6, 0x10, 0xc, 0xa, 0x20, + 0x21, 0xb0, 0xa2, 0x0, 0x8, 0x6c, 0x10, 0x0, + 0xb0, 0xa0, 0x0, 0x4, 0xb0, 0x0, 0x0, 0xc5, + 0xc1, 0x0, 0x5a, 0x0, 0x0, 0x0, 0xb0, 0x60, + 0x18, 0x60, 0x0, 0x0, 0x0, 0x30, 0x25, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+7814 "研" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0x56, 0x55, 0x58, 0x70, 0x6, 0x78, + 0x65, 0x9, 0x20, 0xb0, 0x0, 0x0, 0x73, 0x0, + 0x9, 0x20, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x9, + 0x20, 0xb0, 0x0, 0x0, 0xe5, 0xa3, 0x9, 0x20, + 0xb0, 0x20, 0x6, 0xe0, 0x94, 0x6b, 0x65, 0xc6, + 0x90, 0x7, 0xb0, 0x92, 0xa, 0x10, 0xb0, 0x0, + 0x20, 0xb0, 0x92, 0xb, 0x0, 0xb0, 0x0, 0x0, + 0xb0, 0x92, 0x1b, 0x0, 0xb0, 0x0, 0x0, 0xc5, + 0xb2, 0x74, 0x0, 0xb0, 0x0, 0x0, 0x70, 0x12, + 0x70, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x26, 0x0, + 0x0, 0xb1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+7834 "破" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x6, 0x58, + 0x86, 0x30, 0xb, 0x0, 0x40, 0x0, 0x38, 0x0, + 0xa5, 0x5c, 0x58, 0xa0, 0x0, 0x74, 0x0, 0xa0, + 0xb, 0x3, 0x0, 0x0, 0xb1, 0x50, 0xa0, 0xb, + 0x0, 0x0, 0x3, 0xd3, 0xc1, 0xa5, 0x6a, 0x5c, + 0x10, 0x8, 0xb0, 0xb0, 0xb0, 0x50, 0x1a, 0x0, + 0x22, 0xb0, 0xb0, 0xb0, 0x60, 0x74, 0x0, 0x0, + 0xb0, 0xb0, 0xa0, 0x17, 0xb0, 0x0, 0x0, 0xc5, + 0xc5, 0x40, 0xb, 0x80, 0x0, 0x0, 0xb0, 0x68, + 0x0, 0x85, 0x89, 0x30, 0x0, 0x50, 0x52, 0x56, + 0x10, 0x5, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+78BA "確" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, + 0x33, 0x74, 0x0, 0xd, 0x30, 0x0, 0x3, 0x75, + 0x11, 0x46, 0x6c, 0x55, 0xa5, 0x0, 0x91, 0x0, + 0xc0, 0x95, 0x10, 0x50, 0x0, 0xb0, 0x10, 0x2, + 0xa0, 0xb0, 0x0, 0x0, 0xd5, 0xc3, 0xb, 0x65, + 0xa5, 0xa2, 0x5, 0xc0, 0xa0, 0x8c, 0x1, 0x90, + 0x0, 0x7, 0xa0, 0xa5, 0x2c, 0x56, 0xb5, 0x80, + 0x22, 0xa0, 0xa0, 0xb, 0x1, 0x90, 0x0, 0x0, + 0xa0, 0xa0, 0xb, 0x23, 0xa4, 0x60, 0x0, 0xb5, + 0xb0, 0xc, 0x34, 0xa2, 0x20, 0x0, 0x90, 0x0, + 0xb, 0x1, 0x90, 0x40, 0x0, 0x0, 0x0, 0xc, + 0x55, 0x55, 0x52, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+793A "示" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x15, 0x55, 0x55, 0x55, 0x9b, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x40, 0x6, 0x55, 0x55, 0x68, 0x55, + 0x55, 0xa3, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe2, 0x2a, 0x6, 0x0, 0x0, + 0x0, 0x8, 0x70, 0x2a, 0x0, 0xa2, 0x0, 0x0, + 0x3a, 0x0, 0x2a, 0x0, 0x2d, 0x20, 0x1, 0x90, + 0x0, 0x2a, 0x0, 0x6, 0xb0, 0x6, 0x0, 0x23, + 0x6a, 0x0, 0x0, 0x60, 0x0, 0x0, 0x6, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+793C "礼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x30, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2, + 0xb0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0x20, 0xc0, 0x0, 0x0, 0x2, 0x65, 0x5e, 0x60, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x2, 0xd0, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x19, 0xd9, 0x40, 0xc0, 0x0, 0x0, + 0x1, 0x70, 0xc1, 0xc0, 0xc0, 0x0, 0x0, 0x3, + 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x10, 0x0, 0x0, + 0xc0, 0x0, 0xc0, 0x0, 0x50, 0x0, 0x0, 0xc0, + 0x0, 0xc0, 0x0, 0xa0, 0x0, 0x0, 0xd0, 0x0, + 0x8b, 0xbb, 0xd2, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+793E "社" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x7, + 0x30, 0x0, 0x2a, 0x0, 0x0, 0x5, 0x55, 0x78, + 0x0, 0x2a, 0x0, 0x0, 0x1, 0x0, 0xb4, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0x4, 0x90, 0x55, 0x6b, + 0x58, 0x90, 0x0, 0xe, 0x70, 0x10, 0x2a, 0x0, + 0x0, 0x0, 0x9d, 0x3c, 0x0, 0x2a, 0x0, 0x0, + 0x6, 0x2c, 0x4, 0x0, 0x2a, 0x0, 0x0, 0x11, + 0xc, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xc, 0x4, + 0x55, 0x6b, 0x55, 0xc3, 0x0, 0xc, 0x1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7956 "祖" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x65, 0x55, 0x5a, 0x0, 0x0, 0xc, + 0x0, 0xa2, 0x0, 0xc, 0x0, 0x5, 0x55, 0xa1, + 0xa2, 0x0, 0xc, 0x0, 0x0, 0x2, 0xa0, 0x92, + 0x0, 0xc, 0x0, 0x0, 0xa, 0x20, 0x96, 0x55, + 0x5c, 0x0, 0x0, 0x4d, 0x60, 0x92, 0x0, 0xc, + 0x0, 0x0, 0x9b, 0x78, 0x92, 0x0, 0xc, 0x0, + 0x6, 0xb, 0x4, 0x96, 0x55, 0x5c, 0x0, 0x0, + 0xb, 0x0, 0x92, 0x0, 0xc, 0x0, 0x0, 0xb, + 0x0, 0x92, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, + 0x92, 0x0, 0xc, 0x52, 0x0, 0xc, 0x26, 0x55, + 0x55, 0x55, 0x54, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+795D "祝" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x20, 0x0, 0x4, 0x0, 0x0, 0xa, + 0x10, 0xb5, 0x55, 0x5d, 0x0, 0x5, 0x55, 0x93, + 0xb0, 0x0, 0xb, 0x0, 0x1, 0x0, 0xc0, 0xb0, + 0x0, 0xb, 0x0, 0x0, 0x7, 0x40, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0x2e, 0x30, 0xb6, 0x89, 0x5c, + 0x0, 0x0, 0x9b, 0x95, 0x14, 0x6b, 0x1, 0x0, + 0x6, 0x1b, 0x15, 0x5, 0x4b, 0x0, 0x0, 0x21, + 0xb, 0x0, 0x8, 0x1b, 0x0, 0x0, 0x0, 0xb, + 0x0, 0xa, 0xb, 0x0, 0x50, 0x0, 0xc, 0x0, + 0x82, 0xb, 0x0, 0x80, 0x0, 0xc, 0x6, 0x20, + 0x7, 0xa9, 0xd2, 0x0, 0x4, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+795E "神" */ + 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xb, 0x0, 0x10, 0x5, 0x55, 0x92, + 0xb5, 0x5c, 0x55, 0xd0, 0x1, 0x0, 0xb0, 0xb0, + 0xb, 0x0, 0xb0, 0x0, 0x7, 0x40, 0xb5, 0x5c, + 0x55, 0xb0, 0x0, 0x2d, 0x60, 0xb0, 0xb, 0x0, + 0xb0, 0x0, 0x9b, 0x69, 0xb0, 0xb, 0x0, 0xb0, + 0x6, 0xb, 0x3, 0xb5, 0x5c, 0x55, 0xb0, 0x10, + 0xb, 0x0, 0x50, 0xb, 0x0, 0x20, 0x0, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+796D "祭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x90, 0x11, 0x30, 0x3, 0x0, 0x0, 0xb, + 0x55, 0xc5, 0x95, 0x5d, 0x30, 0x0, 0x57, 0x92, + 0xc0, 0x71, 0x71, 0x0, 0x1, 0x93, 0x4a, 0x40, + 0x1b, 0x20, 0x0, 0x5, 0xb, 0x49, 0x0, 0x7, + 0x70, 0x0, 0x0, 0x2, 0x96, 0x55, 0x68, 0x8b, + 0x30, 0x0, 0x37, 0x0, 0x0, 0x0, 0x5, 0xa2, + 0x15, 0x56, 0x55, 0x56, 0x55, 0x87, 0x0, 0x0, + 0x0, 0x55, 0xb, 0x13, 0x0, 0x0, 0x0, 0x3, + 0xc3, 0xb, 0x3, 0xa4, 0x0, 0x0, 0x49, 0x0, + 0xb, 0x0, 0x1d, 0x30, 0x2, 0x30, 0x5, 0xb9, + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x31, 0x0, + 0x0, 0x0, + + /* U+7981 "禁" */ + 0x0, 0x0, 0x40, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0xb, 0x10, 0x0, 0x4, 0x55, + 0xc5, 0xa2, 0x5d, 0x56, 0xa0, 0x0, 0xb, 0xc2, + 0x0, 0x5f, 0x50, 0x0, 0x0, 0x56, 0xb9, 0x50, + 0x9b, 0x46, 0x0, 0x2, 0x80, 0xb1, 0x27, 0x1b, + 0x8, 0xb1, 0x4, 0x0, 0x80, 0x21, 0x7, 0x20, + 0x20, 0x0, 0x6, 0x55, 0x55, 0x55, 0x92, 0x0, + 0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0xb1, 0x1, + 0x0, 0x42, 0xc, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xd4, 0xc, 0x7, 0x60, 0x0, 0x0, 0x48, 0x10, + 0xc, 0x0, 0x8a, 0x0, 0x2, 0x30, 0x6, 0xd9, + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+79C0 "秀" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x0, + 0x4, 0x56, 0x7a, 0x89, 0x72, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x10, 0x4, 0x65, 0x55, + 0x8c, 0x65, 0x56, 0xb1, 0x0, 0x0, 0xb, 0x5a, + 0x42, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x1a, 0x8, + 0x60, 0x0, 0x0, 0x29, 0x20, 0x15, 0x2, 0x6d, + 0x72, 0x4, 0x42, 0x6b, 0x65, 0x8a, 0x1, 0x60, + 0x0, 0x0, 0xc, 0x0, 0xa2, 0x4, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0x85, 0x6c, 0x0, 0x0, 0x0, + 0x93, 0x0, 0x0, 0x47, 0x0, 0x0, 0x6, 0x60, + 0x0, 0x10, 0x93, 0x0, 0x0, 0x64, 0x0, 0x0, + 0x4d, 0xb0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+79C1 "私" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0xd1, 0x5, 0x10, 0x0, 0x2, 0x46, + 0xd1, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x52, + 0x2a, 0x0, 0x0, 0x6, 0x55, 0xe5, 0x53, 0x65, + 0x0, 0x0, 0x0, 0x5, 0xf4, 0x0, 0x90, 0x0, + 0x0, 0x0, 0xb, 0xd6, 0xb0, 0x90, 0x10, 0x0, + 0x0, 0x83, 0xc0, 0x93, 0x50, 0x35, 0x0, 0x5, + 0x40, 0xc0, 0x7, 0x0, 0xb, 0x10, 0x13, 0x0, + 0xc0, 0x18, 0x0, 0x7, 0xb0, 0x0, 0x0, 0xd0, + 0x8e, 0xa8, 0x64, 0xf0, 0x0, 0x0, 0xe0, 0x12, + 0x0, 0x0, 0x50, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+79CB "秋" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x3, 0xaa, 0x0, 0xb4, 0x0, 0x0, 0x3, 0x5b, + 0x30, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x9, 0x20, + 0x1, 0xb1, 0x9, 0x10, 0x15, 0x5b, 0x7b, 0x35, + 0xc2, 0x6a, 0x10, 0x1, 0xe, 0x20, 0x84, 0xd6, + 0x70, 0x0, 0x0, 0x4f, 0x50, 0xa0, 0xc7, 0x0, + 0x0, 0x0, 0x9b, 0x7a, 0x0, 0xc7, 0x0, 0x0, + 0x3, 0x69, 0x29, 0x3, 0x97, 0x10, 0x0, 0x6, + 0x9, 0x20, 0x9, 0x42, 0x90, 0x0, 0x20, 0x9, + 0x20, 0x1b, 0x0, 0xb3, 0x0, 0x0, 0xa, 0x20, + 0x91, 0x0, 0x2e, 0x40, 0x0, 0xa, 0x46, 0x0, + 0x0, 0x6, 0x70, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+79CD "种" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x4, 0xb8, 0x0, 0xd, 0x0, 0x0, 0x4, 0x5c, + 0x10, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x10, 0xb, 0x0, 0x40, 0x16, 0x5c, 0x69, 0xa5, + 0x5c, 0x56, 0xb0, 0x0, 0xe, 0x0, 0xa1, 0xb, + 0x2, 0x90, 0x0, 0x3f, 0x61, 0xa1, 0xb, 0x2, + 0x90, 0x0, 0xad, 0x3c, 0xa1, 0xb, 0x2, 0x90, + 0x3, 0x7b, 0x2, 0xa5, 0x5c, 0x56, 0x90, 0x8, + 0xb, 0x0, 0x20, 0xb, 0x0, 0x0, 0x30, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+79D1 "科" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x2, 0x8d, 0x0, 0x0, 0xc2, 0x0, 0x4, 0x5b, + 0x40, 0x3, 0x10, 0xb0, 0x0, 0x0, 0x8, 0x20, + 0x1, 0xd0, 0xb0, 0x0, 0x0, 0x8, 0x25, 0x10, + 0x40, 0xb0, 0x0, 0x26, 0x5d, 0x65, 0x31, 0x0, + 0xb0, 0x0, 0x0, 0x1f, 0x60, 0x5, 0x70, 0xb0, + 0x0, 0x0, 0x8c, 0x6b, 0x0, 0x90, 0xb0, 0x30, + 0x2, 0x88, 0x26, 0x0, 0x3, 0xd6, 0x70, 0x7, + 0x8, 0x23, 0x65, 0x41, 0xb0, 0x0, 0x30, 0x9, + 0x20, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x9, 0x20, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x9, 0x30, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x40, 0x0, + + /* U+79D8 "秘" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x38, 0xb7, 0x0, 0x70, 0x6, 0x0, 0x4, 0x2b, + 0x0, 0x0, 0x4b, 0x1e, 0x10, 0x0, 0xb, 0x0, + 0x6, 0x44, 0x49, 0x0, 0x14, 0x4c, 0x4a, 0x9, + 0x20, 0x95, 0x0, 0x2, 0x1f, 0x0, 0x9, 0x20, + 0xd1, 0x0, 0x0, 0x5f, 0x82, 0x49, 0x23, 0xb5, + 0x20, 0x0, 0xac, 0x29, 0x99, 0x2a, 0x50, 0xd0, + 0x4, 0x5b, 0x6, 0x99, 0x5c, 0x0, 0xb2, 0x7, + 0xb, 0x2, 0x19, 0xe2, 0x1, 0x10, 0x20, 0xb, + 0x0, 0xb, 0x60, 0x5, 0x0, 0x0, 0xb, 0x0, + 0x8c, 0x20, 0x9, 0x10, 0x0, 0xb, 0x26, 0x15, + 0xca, 0xad, 0x30, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+79FB "移" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x3, 0xa8, 0x0, 0xb4, 0x0, 0x0, 0x4, 0x6d, + 0x20, 0x4, 0xb5, 0x59, 0x30, 0x0, 0xb, 0x0, + 0x19, 0x50, 0x2b, 0x0, 0x0, 0xb, 0x5, 0x30, + 0xa2, 0xb1, 0x0, 0x26, 0x5f, 0x55, 0x10, 0x2a, + 0x10, 0x0, 0x0, 0x3f, 0x20, 0x4, 0x78, 0x50, + 0x0, 0x0, 0x9e, 0x77, 0x42, 0x4b, 0x10, 0x30, + 0x1, 0x8c, 0x7, 0x3, 0xa5, 0x59, 0xb0, 0x7, + 0xc, 0x0, 0x48, 0x70, 0x1c, 0x10, 0x22, 0xc, + 0x1, 0x20, 0x92, 0xb2, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x4a, 0x20, 0x0, 0x0, 0xc, 0x0, 0x57, + 0x50, 0x0, 0x0, 0x0, 0x3, 0x13, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A0B "程" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x37, 0xb9, 0x18, 0x55, 0x59, 0x30, 0x4, 0x3b, + 0x0, 0x1a, 0x0, 0xa, 0x0, 0x0, 0xb, 0x0, + 0xa, 0x0, 0xa, 0x0, 0x15, 0x5c, 0x5a, 0x2c, + 0x55, 0x5c, 0x0, 0x1, 0x1e, 0x0, 0x17, 0x0, + 0x5, 0x0, 0x0, 0x5f, 0x71, 0x35, 0x55, 0x57, + 0x70, 0x0, 0x9c, 0x2b, 0x10, 0xb, 0x0, 0x0, + 0x1, 0x7b, 0x1, 0x0, 0xb, 0x0, 0x0, 0x7, + 0xb, 0x0, 0x16, 0x5c, 0x59, 0x30, 0x23, 0xb, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xb, 0x0, 0x30, 0x0, 0xc, 0x3, 0x65, + 0x57, 0x55, 0x80, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A2E "種" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x2, 0x95, 0x14, 0x6a, 0xa8, 0x0, 0x3, 0x5c, + 0x20, 0x0, 0xb, 0x0, 0x10, 0x0, 0xb, 0x1, + 0x65, 0x5c, 0x56, 0x70, 0x4, 0x4c, 0x67, 0x20, + 0xb, 0x2, 0x0, 0x2, 0x4d, 0x0, 0xa5, 0x5c, + 0x5c, 0x10, 0x0, 0x7c, 0x80, 0xa5, 0x5c, 0x5c, + 0x0, 0x0, 0xab, 0x65, 0xa0, 0xb, 0xb, 0x0, + 0x5, 0x3b, 0x1, 0xa5, 0x5c, 0x5c, 0x0, 0x5, + 0xb, 0x0, 0x40, 0xb, 0x4, 0x0, 0x10, 0xb, + 0x0, 0x65, 0x5c, 0x59, 0x40, 0x0, 0xc, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x3, 0x55, + 0x5c, 0x57, 0xd0, 0x0, 0x3, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A4D "積" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x27, 0xd3, 0x0, 0xc, 0x0, 0x40, 0x3, 0x3b, + 0x0, 0x65, 0x5c, 0x55, 0x61, 0x0, 0xb, 0x0, + 0x27, 0x5c, 0x57, 0x50, 0x6, 0x6d, 0x85, 0x11, + 0x1b, 0x11, 0x62, 0x0, 0x5d, 0x31, 0x63, 0x33, + 0x33, 0x52, 0x0, 0xab, 0x83, 0x96, 0x55, 0x56, + 0xb0, 0x1, 0x8b, 0x23, 0x86, 0x55, 0x56, 0x90, + 0x7, 0x1b, 0x0, 0x81, 0x0, 0x2, 0x90, 0x14, + 0xb, 0x0, 0x86, 0x55, 0x56, 0x90, 0x0, 0xb, + 0x0, 0x96, 0x55, 0x56, 0x90, 0x0, 0xc, 0x0, + 0x2a, 0x60, 0x37, 0x10, 0x0, 0xb, 0x3, 0x73, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x20, + + /* U+7A76 "究" */ + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x75, + 0x55, 0x87, 0x55, 0x5c, 0x10, 0x3, 0x90, 0x94, + 0x1, 0x50, 0x36, 0x0, 0x3, 0x29, 0x75, 0x10, + 0x2b, 0xa0, 0x0, 0x2, 0x61, 0xb, 0x10, 0x0, + 0x91, 0x0, 0x0, 0x46, 0x6d, 0x66, 0x94, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x0, 0x92, 0x0, 0x0, + 0x0, 0x0, 0x38, 0x0, 0x92, 0x0, 0x0, 0x0, + 0x0, 0x93, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x2, + 0xb0, 0x0, 0xa1, 0x0, 0x50, 0x0, 0xb, 0x20, + 0x0, 0xa1, 0x1, 0x90, 0x1, 0x82, 0x0, 0x0, + 0x5b, 0xac, 0x90, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A7A "空" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x16, 0x0, 0x2, 0x0, 0x4, 0x95, 0x56, + 0x55, 0x55, 0x5c, 0x80, 0xd, 0x30, 0xa9, 0x0, + 0x57, 0x25, 0x0, 0x0, 0x9, 0x70, 0x0, 0x2, + 0xc8, 0x0, 0x2, 0x72, 0x0, 0x0, 0x0, 0x1b, + 0x10, 0x3, 0x17, 0x55, 0x85, 0x57, 0x80, 0x0, + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, 0xc7, + 0x55, 0x5d, 0x60, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A93 "窓" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x75, + 0x55, 0x5c, 0x55, 0x56, 0xa0, 0x3, 0x90, 0x18, + 0x0, 0x54, 0x5, 0x50, 0x6, 0x25, 0xa4, 0x63, + 0x4, 0xd7, 0x0, 0x0, 0x52, 0x3, 0xc3, 0x10, + 0x4, 0x0, 0x0, 0x0, 0x58, 0x0, 0xa, 0x10, + 0x0, 0x0, 0x8, 0xda, 0x87, 0x68, 0xb0, 0x0, + 0x0, 0x2, 0x30, 0x50, 0x0, 0x80, 0x0, 0x0, + 0x10, 0xc1, 0x2c, 0x0, 0x5, 0x0, 0x0, 0x70, + 0xc0, 0x7, 0x0, 0x46, 0x70, 0x7, 0x90, 0xc0, + 0x0, 0x1, 0x70, 0xb0, 0x3, 0x0, 0xbb, 0xbb, + 0xbc, 0xb0, 0x0, + + /* U+7ACB "立" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x1, 0x0, 0x2, 0x65, 0x55, + 0x55, 0x55, 0x5c, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0xe, + 0x40, 0x0, 0x0, 0x0, 0x90, 0x0, 0x1c, 0x0, + 0x0, 0x0, 0x0, 0x67, 0x0, 0x47, 0x0, 0x0, + 0x0, 0x0, 0x3d, 0x0, 0x91, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x2, 0x40, 0x0, 0x0, 0x15, 0x55, 0x55, + 0x59, 0x55, 0x57, 0xd1, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7AD9 "站" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x43, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x7, 0x0, + 0x30, 0xb, 0x1, 0x40, 0x6, 0x55, 0x56, 0x70, + 0xc, 0x55, 0x50, 0x0, 0x10, 0x28, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x70, 0x57, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xb0, 0x72, 0xa, 0x5a, 0x5b, 0x30, + 0x0, 0x94, 0x80, 0xb, 0x0, 0xb, 0x0, 0x0, + 0x51, 0x60, 0xb, 0x0, 0xb, 0x0, 0x0, 0x36, + 0x95, 0x2b, 0x0, 0xb, 0x0, 0xc, 0x83, 0x0, + 0xc, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7AE5 "童" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x40, 0x14, 0x0, 0x0, 0x46, 0x97, + 0x55, 0xc6, 0x50, 0x0, 0x0, 0x1, 0xb0, 0x26, + 0x0, 0x0, 0x5, 0x65, 0x56, 0x57, 0x55, 0x87, + 0x0, 0x0, 0x75, 0x55, 0x55, 0x75, 0x0, 0x0, + 0xb, 0x0, 0x91, 0x5, 0x50, 0x0, 0x0, 0xb5, + 0x5b, 0x65, 0x95, 0x0, 0x0, 0xb, 0x55, 0xb6, + 0x59, 0x60, 0x0, 0x0, 0x60, 0x9, 0x10, 0x33, + 0x0, 0x0, 0x55, 0x55, 0xb6, 0x55, 0xb4, 0x0, + 0x0, 0x0, 0x9, 0x10, 0x0, 0x20, 0x6, 0x55, + 0x55, 0x75, 0x55, 0x58, 0x50, + + /* U+7AEF "端" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x71, 0x0, 0x50, 0x1c, 0x2, 0x10, 0x0, 0x48, + 0x0, 0xb0, 0xa, 0x4, 0x70, 0x0, 0x1, 0x50, + 0xa0, 0xa, 0x4, 0x60, 0x5, 0x44, 0x62, 0x85, + 0x55, 0x57, 0x40, 0x3, 0x10, 0xd3, 0x55, 0x55, + 0x55, 0x92, 0x1, 0x72, 0x80, 0x10, 0x92, 0x0, + 0x0, 0x0, 0xb5, 0x30, 0x85, 0xa5, 0x55, 0x90, + 0x0, 0x66, 0x0, 0xb0, 0xa0, 0xa0, 0xb0, 0x0, + 0x8, 0x53, 0xb0, 0xa0, 0xa0, 0xb0, 0xb, 0xa3, + 0x0, 0xb0, 0xa0, 0xa0, 0xb0, 0x1, 0x0, 0x0, + 0xb0, 0xa0, 0x90, 0xb0, 0x0, 0x0, 0x0, 0xb0, + 0x40, 0x29, 0xa0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x2, 0x10, + + /* U+7B11 "笑" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x4c, + 0x55, 0xb3, 0xc6, 0x57, 0xb0, 0x0, 0xa0, 0x82, + 0x5, 0x50, 0xa1, 0x0, 0x6, 0x20, 0x47, 0x15, + 0x0, 0x73, 0x0, 0x1, 0x0, 0x13, 0x67, 0xad, + 0xc0, 0x0, 0x0, 0x24, 0x43, 0xb3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x2, 0x10, + 0x6, 0x55, 0x55, 0xd7, 0x55, 0x58, 0x60, 0x0, + 0x0, 0x4, 0x83, 0x40, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x83, 0x0, 0x0, 0x0, 0x1, 0x92, + 0x0, 0xa, 0x92, 0x0, 0x2, 0x56, 0x0, 0x0, + 0x0, 0x6e, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7B26 "符" */ + 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x69, 0x0, 0x0, 0x0, 0x6a, + 0x65, 0x92, 0xb5, 0x75, 0x90, 0x1, 0x90, 0x1a, + 0x5, 0x30, 0x83, 0x0, 0x6, 0x0, 0x54, 0x25, + 0x0, 0x32, 0x0, 0x0, 0x2, 0xd1, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xb, 0x25, 0x55, 0x55, 0xc5, + 0xa2, 0x0, 0x7d, 0x10, 0x20, 0x0, 0xb0, 0x0, + 0x6, 0x3b, 0x0, 0x75, 0x0, 0xb0, 0x0, 0x11, + 0xb, 0x0, 0xd, 0x0, 0xb0, 0x0, 0x0, 0xb, + 0x0, 0x1, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x6c, 0x90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+7B2C "第" */ + 0x0, 0x2, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0xc, 0x50, 0x10, 0x8a, 0x0, 0x10, 0x0, 0x6a, + 0x85, 0x94, 0xc7, 0x65, 0x91, 0x3, 0x70, 0x66, + 0x8, 0x0, 0xb0, 0x0, 0x2, 0x25, 0x67, 0x65, + 0x55, 0x89, 0x0, 0x0, 0x1, 0x0, 0xb, 0x0, + 0xb, 0x0, 0x0, 0x9, 0x55, 0x5c, 0x55, 0x5b, + 0x0, 0x0, 0x1b, 0x0, 0xb, 0x0, 0x5, 0x0, + 0x0, 0x7a, 0x55, 0x5c, 0x55, 0x55, 0x90, 0x0, + 0x21, 0x5, 0x9b, 0x0, 0x1, 0xb0, 0x0, 0x0, + 0x59, 0xb, 0x0, 0x4, 0x80, 0x0, 0x18, 0x50, + 0xb, 0x2, 0x9e, 0x30, 0x15, 0x50, 0x0, 0xb, + 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+7B46 "筆" */ + 0x0, 0x4, 0x10, 0x0, 0x22, 0x0, 0x0, 0x0, + 0xd, 0x40, 0x0, 0x78, 0x0, 0x10, 0x0, 0x5b, + 0x65, 0x95, 0xc5, 0x76, 0xa0, 0x0, 0xa0, 0x2b, + 0x6, 0x30, 0x69, 0x0, 0x7, 0x10, 0x8, 0x39, + 0x0, 0x1a, 0x0, 0x1, 0x4, 0x65, 0x6b, 0x55, + 0xd2, 0x0, 0x1, 0x55, 0x55, 0x6b, 0x55, 0xd9, + 0x80, 0x0, 0x10, 0x0, 0x29, 0x0, 0xc0, 0x0, + 0x0, 0x4, 0x65, 0x6b, 0x55, 0xa0, 0x0, 0x0, + 0x2, 0x22, 0x4a, 0x23, 0x80, 0x0, 0x0, 0x3, + 0x33, 0x5a, 0x33, 0x35, 0x10, 0x3, 0x65, 0x55, + 0x6b, 0x55, 0x57, 0x40, 0x0, 0x0, 0x0, 0x2a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, + 0x0, 0x0, + + /* U+7B49 "等" */ + 0x0, 0x3, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, + 0xe, 0x50, 0x10, 0x88, 0x0, 0x10, 0x0, 0x5b, + 0x75, 0x85, 0xb7, 0x55, 0x80, 0x1, 0xa0, 0x84, + 0x5, 0x10, 0xb0, 0x0, 0x6, 0x0, 0x35, 0xc, + 0x0, 0x70, 0x0, 0x0, 0x6, 0x55, 0x5d, 0x55, + 0x78, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x30, 0x6, 0x55, 0x55, 0x57, 0x56, 0x55, 0x70, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x21, 0x30, 0x1, + 0x75, 0x75, 0x55, 0x5c, 0x55, 0x60, 0x0, 0x0, + 0x39, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0xb, + 0x10, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0x0, 0x0, + + /* U+7B54 "答" */ + 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xf, 0x20, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x7b, + 0x55, 0xa7, 0x86, 0x59, 0x30, 0x1, 0xa0, 0xa0, + 0x16, 0x6, 0x60, 0x0, 0x7, 0x10, 0x85, 0xe1, + 0x0, 0xa0, 0x0, 0x0, 0x0, 0x4b, 0x17, 0x20, + 0x0, 0x0, 0x0, 0x6, 0x90, 0x0, 0x79, 0x30, + 0x0, 0x1, 0x85, 0x65, 0x55, 0xa4, 0xae, 0x80, + 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x5d, 0x30, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, + 0x5d, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+7B56 "策" */ + 0x0, 0x1, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x9, 0x70, 0x0, 0x93, 0x0, 0x0, 0x0, 0x3c, + 0x75, 0x86, 0xa7, 0x58, 0x70, 0x0, 0x90, 0x47, + 0x5, 0x8, 0x40, 0x0, 0x4, 0x0, 0x4, 0xa, + 0x2, 0x22, 0x30, 0x4, 0x55, 0x55, 0x5c, 0x55, + 0x58, 0x80, 0x0, 0x7, 0x55, 0x5c, 0x55, 0x83, + 0x0, 0x0, 0xb, 0x0, 0xb, 0x0, 0xa1, 0x0, + 0x0, 0xb, 0x0, 0x7d, 0x11, 0xb0, 0x0, 0x0, + 0xb, 0x6, 0x8b, 0x87, 0xc0, 0x0, 0x0, 0x0, + 0x86, 0xb, 0x1a, 0x30, 0x0, 0x0, 0x38, 0x20, + 0xb, 0x0, 0xac, 0x83, 0x15, 0x30, 0x0, 0xb, + 0x0, 0x3, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7B97 "算" */ + 0x0, 0x4, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x30, 0xb2, 0x0, 0x10, 0x0, 0x77, + 0x96, 0x75, 0x85, 0x96, 0x60, 0x2, 0x71, 0x37, + 0x5, 0x0, 0x85, 0x0, 0x5, 0xb, 0x55, 0x55, + 0x57, 0xb0, 0x0, 0x0, 0xb, 0x55, 0x55, 0x57, + 0x90, 0x0, 0x0, 0xb, 0x0, 0x0, 0x3, 0x90, + 0x0, 0x0, 0xc, 0x55, 0x55, 0x57, 0x90, 0x0, + 0x0, 0xc, 0x59, 0x55, 0x97, 0x90, 0x0, 0x0, + 0x2, 0x2b, 0x0, 0xc0, 0x0, 0x20, 0x16, 0x55, + 0x8b, 0x55, 0xd5, 0x57, 0x80, 0x0, 0x0, 0xb2, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x38, 0x20, 0x0, + 0xc0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+7BA1 "管" */ + 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x79, 0x0, 0x11, 0xc1, 0x1, 0x0, 0x0, 0xb7, + 0x66, 0x58, 0x68, 0x57, 0x40, 0x7, 0x10, 0xa0, + 0x61, 0x6, 0x60, 0x0, 0x3, 0x0, 0x20, 0x92, + 0x0, 0x12, 0x30, 0x9, 0x55, 0x55, 0x55, 0x55, + 0x5b, 0x80, 0x29, 0x8, 0x55, 0x55, 0x5c, 0x4, + 0x0, 0x0, 0xa, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0xa, 0x55, 0x55, 0x5b, 0x0, 0x0, 0x0, + 0xa, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0xa, + 0x55, 0x55, 0x5a, 0x60, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x7, 0x30, 0x0, 0x0, 0xb, 0x55, 0x55, + 0x5a, 0x40, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7BC0 "節" */ + 0x0, 0x4, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x60, 0xb3, 0x3, 0x40, 0x0, 0xa5, + 0xa8, 0x54, 0xa6, 0xa5, 0x40, 0x4, 0x30, 0xc, + 0x7, 0x0, 0x5a, 0x0, 0x13, 0x20, 0x0, 0x41, + 0x20, 0x7, 0x0, 0x0, 0xb5, 0x55, 0xd1, 0xc5, + 0x5d, 0x0, 0x0, 0xb5, 0x55, 0xb0, 0xb0, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0xb0, 0xb0, 0xb, 0x0, + 0x0, 0xb5, 0x55, 0xb0, 0xb0, 0xb, 0x0, 0x0, + 0xb0, 0x3, 0x10, 0xb0, 0xb, 0x0, 0x0, 0xb0, + 0x8, 0x50, 0xb2, 0x9a, 0x0, 0x0, 0xc7, 0x74, + 0xe0, 0xb0, 0x20, 0x0, 0x0, 0x74, 0x0, 0x41, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+7BC4 "範" */ + 0x0, 0x3, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, + 0x4d, 0x10, 0x60, 0xa5, 0x3, 0x40, 0x0, 0xb6, + 0xa6, 0x55, 0xa6, 0xb6, 0x40, 0x5, 0x40, 0x3d, + 0x8, 0x0, 0x3d, 0x10, 0x4, 0x11, 0xc4, 0x61, + 0x20, 0x8, 0x0, 0x2, 0x64, 0xb4, 0x51, 0xc5, + 0x5c, 0x0, 0x0, 0xb5, 0xc5, 0xc0, 0xa0, 0xa, + 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa, 0x0, + 0x0, 0xc5, 0xc5, 0xa0, 0xa0, 0xa, 0x0, 0x0, + 0xc5, 0xc5, 0xb0, 0xa4, 0x7a, 0x0, 0x0, 0x20, + 0xa0, 0x70, 0xa0, 0x41, 0x20, 0x5, 0x55, 0xc5, + 0x52, 0xa0, 0x0, 0x50, 0x0, 0x0, 0xb0, 0x0, + 0xb9, 0x9a, 0xc0, 0x0, 0x0, 0x40, 0x0, 0x0, + 0x0, 0x0, + + /* U+7C21 "簡" */ + 0x0, 0x3, 0x0, 0x0, 0x40, 0x0, 0x0, 0x3, + 0xc0, 0x6, 0x3d, 0x10, 0x43, 0x0, 0xa6, 0xb5, + 0x5a, 0x6b, 0x75, 0x40, 0x51, 0x6, 0x52, 0x20, + 0x1c, 0x0, 0x0, 0xb4, 0x4b, 0x27, 0x54, 0x5c, + 0x10, 0xc, 0x55, 0xc0, 0x86, 0x55, 0xc0, 0x0, + 0xb0, 0xa, 0x8, 0x20, 0xb, 0x0, 0xc, 0x55, + 0x90, 0x75, 0x55, 0xc0, 0x0, 0xb0, 0x85, 0x55, + 0x88, 0xb, 0x0, 0xb, 0x9, 0x55, 0x58, 0x70, + 0xb0, 0x0, 0xb0, 0x91, 0x0, 0x47, 0xb, 0x0, + 0xb, 0x9, 0x55, 0x57, 0x50, 0xb0, 0x0, 0xc0, + 0x0, 0x0, 0x4, 0x8d, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x1, 0x20, + + /* U+7C73 "米" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0xb5, 0x0, 0x60, 0x0, 0x0, 0x1a, + 0x10, 0xb1, 0x6, 0xc1, 0x0, 0x0, 0x7, 0xa0, + 0xb1, 0xb, 0x10, 0x0, 0x0, 0x1, 0x90, 0xb1, + 0x72, 0x0, 0x0, 0x16, 0x55, 0x56, 0xd8, 0x85, + 0x5b, 0x70, 0x0, 0x0, 0xb, 0xf7, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x4a, 0xb2, 0x80, 0x0, 0x0, + 0x0, 0x1, 0xc1, 0xb1, 0x67, 0x0, 0x0, 0x0, + 0xb, 0x20, 0xb1, 0xa, 0x80, 0x0, 0x0, 0x91, + 0x0, 0xb1, 0x0, 0xbd, 0x60, 0x26, 0x0, 0x0, + 0xb1, 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+7CBE "精" */ + 0x0, 0x2, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x0, 0xc, 0x0, 0x0, 0x6, 0xb, + 0xb, 0x36, 0x5c, 0x57, 0x60, 0x6, 0x6b, 0x63, + 0x0, 0xb, 0x3, 0x0, 0x1, 0x3b, 0x31, 0x6, + 0x5c, 0x56, 0x10, 0x6, 0x5d, 0x57, 0x45, 0x5c, + 0x55, 0x90, 0x0, 0x5e, 0x10, 0x12, 0x0, 0x2, + 0x0, 0x0, 0xac, 0xa4, 0xc, 0x55, 0x5d, 0x10, + 0x1, 0x9b, 0x27, 0xc, 0x55, 0x5c, 0x0, 0x7, + 0x2b, 0x0, 0xb, 0x0, 0xb, 0x0, 0x14, 0xb, + 0x0, 0xc, 0x55, 0x5c, 0x0, 0x10, 0xb, 0x0, + 0xb, 0x0, 0xb, 0x0, 0x0, 0xc, 0x0, 0xb, + 0x2, 0x8c, 0x0, 0x0, 0x2, 0x0, 0x3, 0x0, + 0x12, 0x0, + + /* U+7CD6 "糖" */ + 0x0, 0x20, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x0, 0xc, 0x0, 0x10, 0x15, 0x65, + 0x95, 0xb5, 0x59, 0x57, 0x70, 0xc, 0x66, 0x90, + 0xb0, 0xc, 0x1, 0x0, 0x5, 0x69, 0x0, 0xb4, + 0x6c, 0x5d, 0x0, 0x36, 0xa8, 0x95, 0xb1, 0x1b, + 0xb, 0x50, 0x0, 0xb5, 0x0, 0xa5, 0x4c, 0x5c, + 0x40, 0x0, 0xea, 0x71, 0xa3, 0x5c, 0x5c, 0x0, + 0x5, 0xa5, 0xa3, 0x81, 0xb, 0x4, 0x0, 0x7, + 0x65, 0x6, 0x58, 0x56, 0x5b, 0x10, 0x31, 0x65, + 0x9, 0xa, 0x0, 0xb, 0x0, 0x0, 0x75, 0x16, + 0xa, 0x0, 0xb, 0x0, 0x0, 0x75, 0x60, 0xb, + 0x55, 0x5c, 0x0, 0x0, 0x20, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+7CFB "系" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, + 0x2, 0x46, 0x79, 0xaa, 0x60, 0x0, 0x24, 0x32, + 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0x0, + 0x25, 0x0, 0x0, 0x4, 0x94, 0x23, 0x5c, 0x60, + 0x0, 0x0, 0x9a, 0x65, 0xa7, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x81, 0x3, 0x60, 0x0, 0x1, 0x8b, + 0x64, 0x55, 0x59, 0xe1, 0x0, 0x1a, 0x64, 0x2c, + 0x0, 0x9, 0x20, 0x0, 0x7, 0x70, 0xc1, 0x61, + 0x0, 0x0, 0x5, 0xb1, 0xc, 0x1, 0xb9, 0x0, + 0x7, 0x60, 0x21, 0xc0, 0x0, 0xc8, 0x5, 0x10, + 0x3, 0xca, 0x0, 0x1, 0x50, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+7D00 "紀" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x0, 0x0, 0x5, 0x10, 0x0, 0x38, + 0x0, 0x36, 0x55, 0x5d, 0x20, 0x0, 0x80, 0x34, + 0x0, 0x0, 0xc, 0x0, 0xb, 0x65, 0xb3, 0x0, + 0x0, 0xc, 0x0, 0x6, 0x38, 0x40, 0x7, 0x55, + 0x5d, 0x0, 0x0, 0x65, 0x26, 0xc, 0x0, 0x6, + 0x0, 0x8, 0x84, 0x6d, 0x2c, 0x0, 0x0, 0x0, + 0xb, 0x82, 0x6, 0x1c, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x16, 0xc, 0x0, 0x0, 0x20, 0x6, 0xb, + 0xb, 0x2c, 0x0, 0x0, 0x80, 0xb, 0xb, 0x36, + 0x3d, 0x0, 0x0, 0xc0, 0x36, 0x3, 0x0, 0x9, + 0xdb, 0xbd, 0xe1, + + /* U+7D04 "約" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0x6b, 0x0, 0x0, 0x0, 0xa, + 0x10, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x72, 0x9, + 0x1, 0xd5, 0x55, 0xb1, 0x7, 0xa6, 0x97, 0x6, + 0x20, 0x0, 0xc0, 0x4, 0x54, 0x80, 0x15, 0x0, + 0x0, 0xc0, 0x0, 0x38, 0x8, 0x12, 0x20, 0x0, + 0xc0, 0x5, 0xb4, 0x6a, 0x80, 0xb6, 0x0, 0xb0, + 0x5, 0x83, 0x2, 0x50, 0x1d, 0x1, 0xa0, 0x0, + 0x12, 0x5, 0x10, 0x1, 0x2, 0x90, 0x4, 0x36, + 0x51, 0xc0, 0x0, 0x4, 0x80, 0xb, 0x23, 0xa0, + 0xa0, 0x0, 0x6, 0x60, 0x9, 0x0, 0x20, 0x0, + 0x5, 0xce, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+7D19 "紙" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x0, 0x1, 0x7c, 0x10, 0x0, 0x74, + 0x0, 0x85, 0x6d, 0x40, 0x0, 0x3, 0x70, 0x63, + 0x91, 0xb, 0x0, 0x0, 0x2d, 0x76, 0xb1, 0x91, + 0xb, 0x0, 0x0, 0x6, 0x19, 0x10, 0x91, 0xa, + 0x3, 0x30, 0x0, 0x91, 0x62, 0x95, 0x5b, 0x55, + 0x40, 0x1c, 0x66, 0x8b, 0x91, 0x7, 0x20, 0x0, + 0x9, 0x40, 0x7, 0x91, 0x5, 0x60, 0x0, 0x1, + 0x20, 0x61, 0x91, 0x0, 0xa0, 0x10, 0x7, 0x47, + 0x2b, 0x91, 0x1, 0xa2, 0x60, 0x39, 0xb, 0x2, + 0xa7, 0x50, 0x2c, 0xa0, 0x64, 0x0, 0x0, 0xa4, + 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D20 "素" */ + 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0x0, 0x6, 0x0, 0x0, 0x56, + 0x55, 0x6b, 0x55, 0x55, 0x20, 0x0, 0x5, 0x55, + 0x6b, 0x55, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x29, + 0x0, 0x0, 0x60, 0x6, 0x55, 0x5b, 0xa5, 0x55, + 0x55, 0x62, 0x0, 0x2, 0x75, 0x12, 0xc6, 0x0, + 0x0, 0x0, 0x7, 0x96, 0x8a, 0x33, 0x0, 0x0, + 0x0, 0x0, 0x48, 0x40, 0x6, 0xa0, 0x0, 0x0, + 0xe, 0xd8, 0x8c, 0x53, 0x75, 0x0, 0x0, 0x2, + 0x92, 0x29, 0x25, 0x10, 0x0, 0x0, 0x9, 0x70, + 0x29, 0x2, 0xb8, 0x0, 0x2, 0x61, 0x16, 0xd8, + 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+7D30 "細" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x74, + 0x0, 0xb5, 0x5a, 0x57, 0xc0, 0x3, 0x60, 0x62, + 0xb0, 0xb, 0x2, 0x90, 0x3c, 0x66, 0xc1, 0xb0, + 0xb, 0x2, 0x90, 0x6, 0x2a, 0x10, 0xb0, 0xb, + 0x2, 0x90, 0x0, 0x91, 0x70, 0xb5, 0x5c, 0x56, + 0x90, 0x2c, 0x66, 0x98, 0xb0, 0xb, 0x2, 0x90, + 0x1a, 0x51, 0x16, 0xb0, 0xb, 0x2, 0x90, 0x1, + 0x10, 0x61, 0xb0, 0xb, 0x2, 0x90, 0x7, 0x28, + 0x3b, 0xb0, 0xb, 0x2, 0x90, 0x2a, 0xd, 0x5, + 0xb5, 0x5b, 0x56, 0x90, 0x44, 0x1, 0x0, 0xb0, + 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+7D39 "紹" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x50, 0x35, 0x55, 0x55, 0xa1, 0x0, 0x2a, + 0x0, 0x10, 0xa3, 0x0, 0xc0, 0x0, 0x90, 0x16, + 0x0, 0xc1, 0x1, 0xb0, 0xa, 0x75, 0xa5, 0x1, + 0xc0, 0x3, 0x90, 0x7, 0x57, 0x60, 0x7, 0x50, + 0x5, 0x70, 0x0, 0x47, 0x33, 0x27, 0x1, 0x8d, + 0x30, 0x6, 0x82, 0x5d, 0x43, 0x0, 0x3, 0x40, + 0xa, 0x94, 0x17, 0xc, 0x55, 0x55, 0xd0, 0x0, + 0x2, 0x18, 0xb, 0x0, 0x0, 0xb0, 0x4, 0x28, + 0x28, 0x6b, 0x0, 0x0, 0xb0, 0xb, 0x26, 0x61, + 0x3c, 0x55, 0x55, 0xb0, 0x8, 0x0, 0x0, 0xa, + 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D42 "終" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x2, 0xe1, 0x0, 0x0, 0x0, 0x39, + 0x0, 0x8, 0x85, 0x5a, 0x20, 0x0, 0x90, 0x35, + 0x2b, 0x10, 0x2b, 0x0, 0xb, 0x76, 0xb3, 0x60, + 0x70, 0xa2, 0x0, 0x5, 0x38, 0x40, 0x0, 0x5a, + 0x70, 0x0, 0x0, 0x64, 0x25, 0x0, 0x4e, 0x60, + 0x0, 0x9, 0x85, 0x5d, 0x15, 0x70, 0xab, 0x50, + 0x8, 0x62, 0x5, 0x62, 0x29, 0x25, 0x81, 0x1, + 0x2, 0x35, 0x0, 0x4, 0xa0, 0x0, 0x7, 0xa, + 0xc, 0x12, 0x62, 0x10, 0x0, 0xc, 0xb, 0x23, + 0x0, 0x1a, 0xb1, 0x0, 0x26, 0x0, 0x0, 0x0, + 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+7D44 "組" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x7, 0x55, 0x59, 0x0, 0x0, 0x47, + 0x0, 0xc, 0x0, 0xc, 0x0, 0x1, 0x80, 0x36, + 0xc, 0x0, 0xc, 0x0, 0xc, 0x76, 0xb3, 0xc, + 0x0, 0xc, 0x0, 0x6, 0x38, 0x30, 0xd, 0x55, + 0x5c, 0x0, 0x0, 0x74, 0x26, 0xc, 0x0, 0xc, + 0x0, 0xa, 0x85, 0x6d, 0x2c, 0x0, 0xc, 0x0, + 0x8, 0x61, 0x5, 0x1d, 0x55, 0x5c, 0x0, 0x1, + 0x3, 0x26, 0xc, 0x0, 0xc, 0x0, 0x7, 0xa, + 0xc, 0x1c, 0x0, 0xc, 0x0, 0xc, 0x9, 0x32, + 0xc, 0x0, 0xc, 0x0, 0x16, 0x0, 0x4, 0x5d, + 0x55, 0x5d, 0xd1, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D4C "経" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x66, 0x55, 0x59, 0x40, 0x0, 0x74, + 0x0, 0x7, 0x0, 0x1d, 0x20, 0x2, 0x70, 0x62, + 0x2, 0x70, 0xa4, 0x0, 0x1c, 0x55, 0xb0, 0x0, + 0x7b, 0x60, 0x0, 0x7, 0x3a, 0x10, 0x0, 0x9b, + 0xa2, 0x0, 0x0, 0x82, 0x61, 0x48, 0x14, 0x4d, + 0xc2, 0x9, 0x64, 0x7b, 0x10, 0xd, 0x0, 0x10, + 0xa, 0x62, 0x7, 0x25, 0x5d, 0x59, 0x50, 0x0, + 0x12, 0x52, 0x1, 0xc, 0x0, 0x0, 0x7, 0xb, + 0xd, 0x0, 0xc, 0x0, 0x0, 0x1c, 0xc, 0x5, + 0x0, 0xc, 0x0, 0x70, 0x25, 0x0, 0x3, 0x65, + 0x55, 0x55, 0x51, + + /* U+7D50 "結" */ + 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0xc, 0x10, 0x0, 0x0, 0x66, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x2, 0x80, 0x54, + 0x45, 0x5c, 0x55, 0xb1, 0x1c, 0x66, 0xc2, 0x10, + 0xb, 0x0, 0x0, 0x7, 0x39, 0x20, 0x0, 0xb, + 0x0, 0x0, 0x0, 0x83, 0x34, 0x16, 0x5a, 0x59, + 0x40, 0x1a, 0x64, 0x6e, 0x10, 0x0, 0x0, 0x0, + 0xb, 0x62, 0x7, 0xb, 0x55, 0x5c, 0x20, 0x1, + 0x3, 0x26, 0xb, 0x0, 0xb, 0x0, 0x6, 0xa, + 0xb, 0x2b, 0x0, 0xb, 0x0, 0xc, 0xa, 0x34, + 0x1c, 0x55, 0x5c, 0x0, 0x27, 0x1, 0x0, 0xb, + 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D61 "絡" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x73, + 0x0, 0xa, 0x75, 0x59, 0x10, 0x2, 0x70, 0x60, + 0x2b, 0x0, 0x3c, 0x10, 0x1b, 0x34, 0xc0, 0x72, + 0x50, 0xc1, 0x0, 0x9, 0x4b, 0x12, 0x0, 0x5b, + 0x30, 0x0, 0x0, 0x72, 0x60, 0x0, 0x99, 0x80, + 0x0, 0x8, 0x42, 0x87, 0x37, 0x10, 0x5d, 0x91, + 0x1e, 0x95, 0x29, 0x28, 0x55, 0x59, 0x20, 0x0, + 0x0, 0x20, 0xb, 0x0, 0xb, 0x0, 0x5, 0x6, + 0x56, 0xb, 0x0, 0xb, 0x0, 0xb, 0xd, 0x1b, + 0xb, 0x0, 0xb, 0x0, 0x48, 0x6, 0x0, 0xd, + 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x1, 0x0, + + /* U+7D66 "給" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x8, 0x50, 0x0, 0x2e, 0x10, 0x0, 0x0, 0x1a, + 0x0, 0x0, 0x87, 0x40, 0x0, 0x0, 0x81, 0x34, + 0x1, 0xb0, 0x70, 0x0, 0x7, 0x85, 0xa3, 0x9, + 0x20, 0x1b, 0x10, 0x4, 0x57, 0x50, 0x63, 0x0, + 0x16, 0xe4, 0x0, 0x36, 0x27, 0x16, 0x55, 0x64, + 0x30, 0x4, 0xa4, 0x6d, 0x11, 0x0, 0x3, 0x0, + 0x5, 0x83, 0x6, 0x1c, 0x55, 0x5d, 0x10, 0x1, + 0x14, 0x35, 0xa, 0x0, 0xb, 0x0, 0x6, 0x27, + 0x3d, 0x2a, 0x0, 0xb, 0x0, 0xd, 0x6, 0x54, + 0x1c, 0x55, 0x5c, 0x0, 0x3, 0x0, 0x0, 0x1a, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D71 "統" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0x97, 0x0, 0x0, 0x0, 0x38, + 0x0, 0x0, 0x17, 0x0, 0x60, 0x0, 0x90, 0x34, + 0x65, 0xa8, 0x55, 0x50, 0xb, 0x65, 0xb3, 0x3, + 0xa0, 0x31, 0x0, 0x7, 0x38, 0x30, 0x47, 0x0, + 0x1b, 0x20, 0x0, 0x64, 0x34, 0x99, 0x65, 0x36, + 0x80, 0x9, 0x74, 0x6e, 0x16, 0x50, 0xa0, 0x0, + 0xb, 0x83, 0x17, 0x7, 0x40, 0xb0, 0x0, 0x1, + 0x11, 0x55, 0x9, 0x20, 0xb0, 0x0, 0x7, 0xb, + 0xc, 0xb, 0x0, 0xb0, 0x30, 0x1c, 0xa, 0x1, + 0x57, 0x0, 0xb0, 0x60, 0x13, 0x0, 0x6, 0x60, + 0x0, 0xba, 0xd4, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D75 "絵" */ + 0x0, 0x1, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x93, + 0x0, 0x1, 0xc5, 0x20, 0x0, 0x4, 0x50, 0x82, + 0x9, 0x30, 0x91, 0x0, 0x2d, 0x77, 0xb0, 0x55, + 0x0, 0x1c, 0x40, 0x5, 0x1a, 0x14, 0x34, 0x55, + 0xb5, 0xb3, 0x0, 0x91, 0x62, 0x1, 0x0, 0x0, + 0x0, 0x1a, 0x44, 0x8b, 0x0, 0x0, 0x4, 0x30, + 0x1d, 0x73, 0x8, 0x55, 0xa7, 0x55, 0x40, 0x0, + 0x11, 0x51, 0x1, 0xd2, 0x0, 0x0, 0x6, 0xa, + 0x1c, 0x9, 0x20, 0x33, 0x0, 0xa, 0xb, 0x6, + 0x74, 0x12, 0x3c, 0x20, 0x24, 0x0, 0x0, 0xb9, + 0x64, 0x25, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D93 "經" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x1, 0x55, 0x55, 0x58, 0x90, 0x0, 0x82, + 0x0, 0x23, 0x5, 0x4, 0x0, 0x2, 0x60, 0x70, + 0x68, 0x3a, 0x1c, 0x10, 0x1b, 0x46, 0xa0, 0x90, + 0x80, 0x71, 0x0, 0x8, 0x3a, 0x1, 0x70, 0x80, + 0x83, 0x0, 0x0, 0x82, 0x50, 0x86, 0x4a, 0xd, + 0x10, 0x7, 0x51, 0x95, 0x26, 0x7, 0x4, 0x0, + 0xd, 0xa5, 0x47, 0x45, 0x55, 0x57, 0x70, 0x1, + 0x1, 0x41, 0x10, 0xb, 0x0, 0x0, 0x6, 0x9, + 0x1b, 0x0, 0xb, 0x0, 0x0, 0xc, 0xc, 0x6, + 0x0, 0xb, 0x0, 0x0, 0x18, 0x2, 0x2, 0x55, + 0x5c, 0x56, 0xd1, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+7D9A "続" */ + 0x0, 0x1, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x73, + 0x0, 0x55, 0x5c, 0x57, 0xa0, 0x1, 0x70, 0x60, + 0x10, 0xb, 0x0, 0x0, 0xb, 0x45, 0xa0, 0x6, + 0x5a, 0x5a, 0x10, 0x8, 0x4a, 0x0, 0x30, 0x0, + 0x0, 0x20, 0x0, 0x72, 0x50, 0xa5, 0x55, 0x55, + 0xe1, 0x6, 0x51, 0x96, 0x74, 0x51, 0x44, 0x20, + 0xd, 0xa6, 0x57, 0x5, 0x71, 0xa0, 0x0, 0x1, + 0x0, 0x30, 0x7, 0x41, 0x90, 0x0, 0x5, 0x17, + 0x2a, 0xa, 0x1, 0x90, 0x40, 0xb, 0xc, 0x7, + 0x47, 0x1, 0x90, 0x70, 0x17, 0x3, 0x6, 0x60, + 0x0, 0xca, 0xe2, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, + + /* U+7DAD "維" */ + 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x6, 0x6a, 0x30, 0x0, 0x0, 0x82, + 0x0, 0xb, 0x14, 0x80, 0x0, 0x2, 0x60, 0x70, + 0x1d, 0x57, 0x58, 0x80, 0x1b, 0x56, 0xa0, 0x7b, + 0xa, 0x10, 0x0, 0x6, 0x2a, 0x1, 0x6b, 0xa, + 0x11, 0x0, 0x0, 0x81, 0x74, 0xc, 0x5c, 0x57, + 0x40, 0x9, 0x54, 0xa7, 0xb, 0xa, 0x10, 0x0, + 0xc, 0x72, 0x16, 0xb, 0xa, 0x13, 0x10, 0x1, + 0x20, 0x51, 0xc, 0x5c, 0x55, 0x30, 0x6, 0x19, + 0x1d, 0xb, 0xa, 0x10, 0x0, 0x2a, 0xc, 0x5, + 0xb, 0xa, 0x12, 0x50, 0x33, 0x0, 0x0, 0xd, + 0x55, 0x55, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+7DB2 "網" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x85, 0x55, 0x55, 0xa1, 0x0, 0x72, + 0x0, 0xb2, 0x20, 0x82, 0xc0, 0x2, 0x60, 0x60, + 0xb0, 0xb2, 0x90, 0xc0, 0x1c, 0x67, 0x90, 0xb4, + 0x88, 0x86, 0xc0, 0x6, 0x2a, 0x0, 0xb1, 0x42, + 0x0, 0xc0, 0x0, 0x91, 0x60, 0xb0, 0xd, 0x0, + 0xc0, 0x9, 0x54, 0xa6, 0xb6, 0x86, 0x77, 0xc0, + 0xb, 0x72, 0x25, 0xb0, 0xb0, 0x0, 0xc0, 0x1, + 0x20, 0x70, 0xb0, 0xb0, 0x40, 0xc0, 0x7, 0x45, + 0x76, 0xb1, 0x75, 0x52, 0xc0, 0x3a, 0x29, 0x23, + 0xb0, 0x0, 0x0, 0xc0, 0x42, 0x0, 0x0, 0xb0, + 0x0, 0x5d, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+7DD1 "緑" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x65, 0x55, 0x5c, 0x0, 0x0, 0x82, + 0x0, 0x0, 0x0, 0xc, 0x0, 0x3, 0x50, 0x70, + 0x26, 0x55, 0x5c, 0x0, 0x1c, 0x67, 0x80, 0x0, + 0x0, 0xc, 0x20, 0x6, 0x29, 0x1, 0x75, 0x69, + 0x58, 0x81, 0x0, 0x90, 0x70, 0x20, 0x2d, 0x2, + 0x60, 0xb, 0x66, 0xa6, 0x86, 0x2c, 0x68, 0x20, + 0x9, 0x50, 0x24, 0x9, 0x3a, 0xa0, 0x0, 0x2, + 0x31, 0x91, 0x5, 0x7a, 0x64, 0x0, 0x8, 0x1a, + 0x57, 0x94, 0x2a, 0xb, 0x20, 0x4a, 0x8, 0x7, + 0x30, 0x29, 0x2, 0xc2, 0x21, 0x0, 0x0, 0x5, + 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+7DD2 "緒" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0x92, 0x1, 0x0, 0x0, 0x82, + 0x0, 0x0, 0x91, 0x2b, 0x20, 0x2, 0x60, 0x60, + 0x65, 0xb6, 0x98, 0x0, 0x1b, 0x46, 0xa0, 0x0, + 0x91, 0xa0, 0x10, 0x7, 0x3a, 0x5, 0x65, 0x9b, + 0x76, 0xa0, 0x0, 0x91, 0x60, 0x0, 0x75, 0x0, + 0x0, 0xa, 0x54, 0xa7, 0xa, 0xa5, 0x59, 0x0, + 0xb, 0x62, 0x26, 0x89, 0x0, 0xa, 0x0, 0x1, + 0x20, 0x64, 0x1b, 0x55, 0x5b, 0x0, 0x7, 0x36, + 0x84, 0x9, 0x0, 0xa, 0x0, 0x2a, 0x1b, 0x25, + 0x19, 0x0, 0xa, 0x0, 0x33, 0x1, 0x0, 0x1b, + 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+7DDA "線" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x92, + 0x0, 0x95, 0x85, 0x5c, 0x10, 0x3, 0x50, 0x50, + 0xb0, 0x0, 0xb, 0x0, 0x2a, 0x37, 0x80, 0xb5, + 0x55, 0x5c, 0x0, 0x18, 0x4a, 0x0, 0xb0, 0x0, + 0xb, 0x0, 0x0, 0x92, 0x40, 0xa5, 0x6b, 0x59, + 0x0, 0x9, 0x33, 0xd1, 0x1, 0x1d, 0x1, 0x50, + 0x1d, 0x73, 0x74, 0x6c, 0x8b, 0x59, 0x50, 0x2, + 0x30, 0x80, 0xb, 0x1a, 0x90, 0x0, 0x7, 0x65, + 0x93, 0x83, 0x1a, 0x57, 0x0, 0x86, 0x37, 0x15, + 0x50, 0x1a, 0xa, 0xa1, 0x30, 0x0, 0x42, 0x6, + 0xd8, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+7DE0 "締" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x82, + 0x2, 0x65, 0x59, 0x58, 0x70, 0x2, 0x60, 0x50, + 0x8, 0x0, 0xa2, 0x0, 0x1a, 0x35, 0xa0, 0x5, + 0x60, 0x80, 0x0, 0x8, 0x4a, 0x5, 0x75, 0x56, + 0x55, 0xd1, 0x0, 0x81, 0x5b, 0x10, 0x18, 0x2, + 0x30, 0x8, 0x42, 0xa3, 0x20, 0x19, 0x3, 0x0, + 0xe, 0x94, 0x55, 0xa5, 0x6b, 0x5c, 0x10, 0x0, + 0x10, 0x50, 0xa0, 0x19, 0xa, 0x0, 0x6, 0x63, + 0x85, 0xa0, 0x19, 0xa, 0x0, 0x29, 0x2a, 0x13, + 0x90, 0x19, 0x7b, 0x0, 0x53, 0x1, 0x0, 0x0, + 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+7DE9 "緩" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x1c, 0x0, 0x35, 0x67, 0x9b, 0x40, 0x0, 0x85, + 0x0, 0x30, 0x50, 0x1a, 0x0, 0x2, 0x70, 0x60, + 0x65, 0x46, 0x55, 0x0, 0x1b, 0x46, 0xa1, 0x77, + 0x65, 0x88, 0x60, 0x7, 0x3a, 0x0, 0x1, 0xa0, + 0x0, 0x0, 0x0, 0x81, 0x64, 0x67, 0xa5, 0x55, + 0xb1, 0x8, 0x54, 0xa6, 0x8, 0x40, 0x0, 0x0, + 0xb, 0x72, 0x25, 0xb, 0x85, 0x6d, 0x0, 0x2, + 0x30, 0x60, 0x47, 0x70, 0xa4, 0x0, 0x8, 0x38, + 0x85, 0x90, 0x1c, 0x70, 0x0, 0x59, 0x9, 0x19, + 0x10, 0x7a, 0xb2, 0x0, 0x10, 0x0, 0x21, 0x27, + 0x30, 0x3d, 0xb2, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x20, + + /* U+7DF4 "練" */ + 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, + 0x3, 0x65, 0x5c, 0x56, 0xb1, 0x2, 0x60, 0x70, + 0x0, 0xa, 0x0, 0x0, 0x1c, 0x56, 0x90, 0x95, + 0x5c, 0x5b, 0x20, 0x6, 0x29, 0x0, 0xa5, 0xa, + 0x7b, 0x0, 0x0, 0x81, 0x60, 0xa4, 0x6a, 0x7a, + 0x0, 0x8, 0x53, 0x97, 0xb5, 0x6d, 0x5c, 0x0, + 0xc, 0x73, 0x26, 0x61, 0xdb, 0x33, 0x0, 0x1, + 0x11, 0x61, 0x8, 0x5a, 0x80, 0x0, 0x6, 0xa, + 0x3a, 0x39, 0xa, 0x49, 0x0, 0x1b, 0xc, 0x5, + 0x80, 0xa, 0x9, 0xc3, 0x25, 0x0, 0x14, 0x0, + 0xa, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+7E3D "總" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x73, + 0x0, 0x94, 0x84, 0x48, 0x70, 0x1, 0x70, 0x60, + 0xa0, 0xa5, 0x27, 0x50, 0xb, 0x45, 0xa0, 0xa3, + 0x85, 0xc9, 0x50, 0x7, 0x39, 0x0, 0xa3, 0x39, + 0x76, 0x50, 0x0, 0x81, 0x60, 0xb1, 0x66, 0xc6, + 0x50, 0x9, 0x65, 0x97, 0xb8, 0x66, 0x7a, 0x50, + 0xa, 0x62, 0x15, 0x21, 0x44, 0x2, 0x0, 0x0, + 0x14, 0x30, 0x2c, 0xd, 0x14, 0x60, 0x5, 0x63, + 0xc6, 0x2a, 0x3, 0x3, 0xc2, 0x1a, 0x37, 0x1d, + 0xa, 0x0, 0x6, 0x10, 0x56, 0x0, 0x1, 0xd, + 0xaa, 0xbc, 0x0, + + /* U+7E3E "績" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x2a, 0x4, 0x0, 0x0, 0x73, + 0x3, 0x65, 0x6b, 0x56, 0x30, 0x1, 0x70, 0x60, + 0x46, 0x6b, 0x58, 0x0, 0xb, 0x45, 0x91, 0x11, + 0x39, 0x14, 0x70, 0x7, 0x39, 0x3, 0x63, 0x33, + 0x36, 0x30, 0x0, 0x72, 0x60, 0xc5, 0x55, 0x5d, + 0x20, 0x7, 0x52, 0xa5, 0xc5, 0x55, 0x5c, 0x0, + 0xc, 0x94, 0x36, 0xc4, 0x44, 0x4c, 0x0, 0x0, + 0x20, 0x50, 0xc1, 0x11, 0x1b, 0x0, 0x6, 0x37, + 0x57, 0xa6, 0x55, 0x5a, 0x0, 0x1b, 0xc, 0x3, + 0xb, 0x60, 0x67, 0x10, 0x24, 0x0, 0x1, 0x93, + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x30, + + /* U+7E54 "織" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, + 0x83, 0x0, 0x39, 0x0, 0xa0, 0x0, 0x0, 0x90, + 0x6, 0x58, 0x93, 0x97, 0x10, 0x6, 0x13, 0x15, + 0x20, 0xc0, 0x92, 0x90, 0x49, 0x4b, 0x21, 0x93, + 0x40, 0x90, 0x0, 0x35, 0x74, 0x26, 0x57, 0x55, + 0xb5, 0xb1, 0x1, 0x74, 0x22, 0x0, 0x30, 0x93, + 0x20, 0x19, 0x25, 0xb9, 0x65, 0xc0, 0x99, 0x40, + 0x4b, 0x51, 0x79, 0x10, 0xa0, 0x9b, 0x0, 0x0, + 0x24, 0x29, 0x65, 0xa0, 0xa5, 0x0, 0x7, 0x92, + 0xc9, 0x10, 0xa1, 0xc6, 0x22, 0x77, 0x75, 0x2a, + 0x65, 0x97, 0xb, 0xa0, 0x41, 0x0, 0x1, 0x1, + 0x50, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7E70 "繰" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x10, 0xb, 0x55, 0x5c, 0x0, 0x0, 0x45, + 0x0, 0xb, 0x0, 0xb, 0x0, 0x0, 0x80, 0x61, + 0xb, 0x55, 0x5a, 0x0, 0xb, 0x86, 0xb0, 0x75, + 0x70, 0x75, 0x70, 0x4, 0x19, 0x10, 0xa0, 0xa0, + 0xb0, 0x90, 0x0, 0x73, 0x61, 0xc5, 0xb0, 0xc5, + 0xa0, 0x6, 0x84, 0x8a, 0x40, 0x36, 0x50, 0x30, + 0x8, 0x83, 0x7, 0x65, 0x6e, 0x55, 0xb1, 0x0, + 0x10, 0x61, 0x0, 0xbc, 0x50, 0x0, 0x7, 0xa, + 0x2a, 0x9, 0x2c, 0x64, 0x0, 0x1b, 0xc, 0x3, + 0x82, 0xc, 0x9, 0x81, 0x14, 0x0, 0x15, 0x0, + 0xc, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+7E7C "繼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x56, 0x8, 0x16, 0x0, 0x33, 0x0, 0x0, 0xa0, + 0xa, 0x37, 0x40, 0x93, 0x20, 0x6, 0x31, 0x3a, + 0xb6, 0xa6, 0x8a, 0x20, 0x3a, 0x49, 0x4a, 0x18, + 0x30, 0x64, 0x10, 0x26, 0x57, 0xa, 0xa7, 0x96, + 0xa4, 0xa0, 0x1, 0x81, 0x4a, 0x10, 0x0, 0x13, + 0x50, 0x1a, 0x34, 0xda, 0x59, 0x55, 0x69, 0x30, + 0x2c, 0x51, 0x6a, 0x18, 0x30, 0x73, 0x20, 0x0, + 0x13, 0xa, 0x95, 0xa6, 0x89, 0x40, 0x6, 0x81, + 0xba, 0x18, 0x20, 0x64, 0x30, 0x56, 0x84, 0x7a, + 0x96, 0x95, 0xa4, 0x90, 0x61, 0x10, 0xc, 0x75, + 0x86, 0x67, 0xb0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, + + /* U+7E8C "續" */ + 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, + 0xb, 0x2, 0x55, 0x6c, 0x55, 0xb1, 0x0, 0x64, + 0x0, 0x21, 0x2a, 0x15, 0x20, 0x1, 0x80, 0x40, + 0x55, 0x44, 0x44, 0x40, 0x9, 0x23, 0xb0, 0xb5, + 0xa5, 0xa5, 0xc0, 0xa, 0x5b, 0x10, 0xa0, 0x90, + 0x90, 0xa0, 0x0, 0x63, 0x50, 0x95, 0x55, 0x56, + 0x50, 0x6, 0x52, 0x95, 0x87, 0x55, 0x5a, 0x50, + 0xd, 0x95, 0x37, 0x77, 0x55, 0x5a, 0x40, 0x0, + 0x10, 0x30, 0x87, 0x55, 0x5a, 0x40, 0x6, 0x64, + 0x93, 0x87, 0x55, 0x5a, 0x40, 0x29, 0x2a, 0x34, + 0x39, 0x60, 0x48, 0x10, 0x43, 0x1, 0x4, 0x84, + 0x0, 0x4, 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x20, + + /* U+7EDF "统" */ + 0x0, 0x22, 0x0, 0x4, 0x0, 0x0, 0x0, 0x9, + 0x70, 0x0, 0x2c, 0x0, 0x0, 0x1, 0xb0, 0x5, + 0x55, 0xa5, 0x6c, 0x10, 0x81, 0xa, 0x20, 0x77, + 0x0, 0x0, 0x57, 0x39, 0x70, 0x19, 0x2, 0x0, + 0x7, 0x65, 0x80, 0x8, 0x0, 0x3a, 0x20, 0x1, + 0x90, 0xb, 0xaa, 0x6a, 0x7c, 0x1, 0xa2, 0x34, + 0x34, 0xa0, 0xb0, 0x30, 0x6d, 0x72, 0x0, 0x39, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x5, 0x70, 0xb0, + 0x0, 0x14, 0x76, 0x40, 0x93, 0xb, 0x4, 0x8, + 0x81, 0x0, 0x3a, 0x0, 0xb0, 0x61, 0x0, 0x0, + 0x57, 0x0, 0xb, 0xbc, 0x40, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+7F3A "缺" */ + 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xb4, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0xb0, + 0x1, 0x0, 0xb0, 0x0, 0x0, 0x5, 0x89, 0x59, + 0x46, 0xc5, 0x6b, 0x0, 0x7, 0xa, 0x0, 0x0, + 0xb0, 0x19, 0x0, 0x11, 0xa, 0x1, 0x20, 0xb0, + 0x19, 0x0, 0x36, 0x5c, 0x57, 0x60, 0xb0, 0x19, + 0x30, 0x5, 0x1a, 0x5, 0x65, 0xc7, 0x57, 0x72, + 0xa, 0xa, 0xa, 0x2, 0x86, 0x0, 0x0, 0xa, + 0xa, 0xa, 0x7, 0x33, 0x60, 0x0, 0xa, 0x5c, + 0x5c, 0x9, 0x0, 0xa1, 0x0, 0x8, 0x60, 0x4, + 0x81, 0x0, 0x3d, 0x20, 0x0, 0x0, 0x16, 0x10, + 0x0, 0x5, 0xb1, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+7F6E "置" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xb6, 0x6b, 0x66, 0xa6, 0x6d, 0x0, 0x0, 0xc0, + 0xc, 0x0, 0xb0, 0xd, 0x0, 0x0, 0xc6, 0x6b, + 0x76, 0xa6, 0x6d, 0x0, 0x0, 0x20, 0x0, 0xa3, + 0x0, 0x7, 0x0, 0x2, 0x76, 0x66, 0xd6, 0x66, + 0x66, 0x10, 0x0, 0xa, 0x66, 0x96, 0x69, 0xa0, + 0x0, 0x0, 0xb, 0x10, 0x0, 0x4, 0x80, 0x0, + 0x0, 0xb, 0x66, 0x66, 0x68, 0x80, 0x0, 0x0, + 0xb, 0x76, 0x66, 0x69, 0x80, 0x0, 0x0, 0xb, + 0x10, 0x0, 0x4, 0x80, 0x0, 0x0, 0xb, 0x76, + 0x66, 0x69, 0x80, 0x0, 0x26, 0x6d, 0x76, 0x66, + 0x69, 0xb7, 0xd2, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7F8E "美" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xa3, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, + 0x57, 0x3, 0x40, 0x44, 0x0, 0x3, 0x65, 0x55, + 0xd5, 0x55, 0x54, 0x0, 0x0, 0x45, 0x55, 0xd5, + 0x56, 0xa1, 0x0, 0x0, 0x10, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x25, 0x55, 0x55, 0xd5, 0x55, 0x5b, + 0x70, 0x1, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x4, 0x55, 0x55, 0xe5, 0x55, 0x98, 0x0, 0x1, + 0x0, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x2, 0x80, 0x0, 0x0, 0x0, 0x1, 0xa3, + 0x0, 0x3c, 0x61, 0x0, 0x2, 0x67, 0x10, 0x0, + 0x1, 0x9f, 0x90, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7FA9 "義" */ + 0x0, 0x0, 0x40, 0x0, 0x32, 0x0, 0x0, 0x0, + 0x0, 0x58, 0x0, 0xa3, 0x12, 0x0, 0x2, 0x65, + 0x57, 0x95, 0x75, 0x88, 0x0, 0x0, 0x25, 0x55, + 0xc5, 0x55, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0, + 0x0, 0x5, 0x0, 0x5, 0x55, 0x55, 0x85, 0x55, + 0x59, 0x30, 0x0, 0x0, 0x38, 0xb5, 0x82, 0x81, + 0x0, 0x1, 0x45, 0xc3, 0x13, 0x90, 0x57, 0x0, + 0x16, 0x55, 0xc5, 0x55, 0xc5, 0x59, 0x80, 0x0, + 0x0, 0xa3, 0x30, 0xb0, 0x68, 0x0, 0xb, 0xa7, + 0xc0, 0x0, 0x6b, 0x90, 0x20, 0x0, 0x0, 0xa0, + 0x3, 0xac, 0x50, 0x60, 0x0, 0x29, 0xd2, 0x53, + 0x0, 0x7c, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7FD2 "習" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x20, 0x26, 0x55, + 0xd2, 0x55, 0x57, 0xc0, 0x6, 0x70, 0xc0, 0x39, + 0x12, 0x90, 0x0, 0xb0, 0xc0, 0x6, 0x32, 0x90, + 0x0, 0x46, 0xd0, 0x3, 0x77, 0x90, 0x5b, 0x40, + 0xc2, 0x99, 0x12, 0x70, 0x21, 0x0, 0xc, 0x30, + 0x0, 0x0, 0x0, 0x85, 0x78, 0x55, 0x5a, 0x20, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xd5, 0x55, 0x55, + 0x5d, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xd5, 0x55, 0x55, 0x5d, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x1, 0x0, + + /* U+8001 "老" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x14, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x5, 0x8c, 0x0, 0x0, 0x16, 0x55, + 0xc6, 0x58, 0xd1, 0x0, 0x0, 0x0, 0x0, 0xb2, + 0xc, 0x30, 0x0, 0x5, 0x55, 0x55, 0xb6, 0xaa, + 0x55, 0xc2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xb4, 0x1, 0x40, 0x0, + 0x0, 0x0, 0x7e, 0x10, 0x3d, 0x90, 0x0, 0x0, + 0x49, 0x5c, 0x28, 0x71, 0x1, 0x0, 0x5, 0x30, + 0x1d, 0x40, 0x0, 0x5, 0x0, 0x0, 0x0, 0x1c, + 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xc, 0xcb, + 0xbb, 0xbe, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8003 "考" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x71, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x55, 0xc1, 0x0, 0x0, 0x16, 0x55, + 0xd5, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0xb0, 0x0, 0x60, 0x16, 0x55, 0x55, 0x8c, 0x55, + 0x55, 0x51, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x15, + 0x0, 0x0, 0x0, 0x76, 0x99, 0x55, 0x56, 0x0, + 0x0, 0x48, 0x10, 0xa2, 0x0, 0x20, 0x0, 0x4, + 0x10, 0x0, 0x95, 0x55, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x16, + 0xab, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, + 0x0, 0x0, + + /* U+8005 "者" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x31, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x71, 0xd4, 0x0, 0x0, 0x36, 0x55, + 0xd5, 0x5d, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0xa5, 0x0, 0x50, 0x7, 0x55, 0x55, 0x7c, 0x75, + 0x56, 0x72, 0x0, 0x0, 0x1, 0xa3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbb, 0x65, 0x56, 0xd0, 0x0, + 0x0, 0x18, 0xe0, 0x0, 0x1, 0xa0, 0x0, 0x4, + 0x50, 0xc5, 0x55, 0x56, 0xa0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x56, 0xb0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x10, 0x0, + + /* U+800C "而" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, + 0x55, 0x55, 0x55, 0x55, 0x58, 0xb0, 0x1, 0x0, + 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x75, 0x57, 0x75, + 0x55, 0x5a, 0x10, 0x0, 0xc0, 0xb, 0x0, 0xb0, + 0xd, 0x0, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, + 0x0, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, + 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, + 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xc0, + 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xc0, 0xb, + 0x0, 0xb1, 0x1c, 0x0, 0x0, 0x90, 0x3, 0x0, + 0x24, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8033 "耳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x57, 0x55, 0x55, 0x57, 0x58, 0x80, 0x0, 0xa, + 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, 0x20, + 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, 0x65, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xa, 0x65, 0x55, 0x5c, 0x0, 0x0, + 0x0, 0xa, 0x20, 0x0, 0xc, 0x0, 0x20, 0x0, + 0xa, 0x32, 0x34, 0x5d, 0x56, 0x91, 0x26, 0x55, + 0x42, 0x10, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+805E "聞" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, 0x55, + 0xd0, 0x95, 0x55, 0xc3, 0xb0, 0x0, 0xb0, 0xa0, + 0x0, 0xa0, 0xb5, 0x55, 0xb0, 0xa5, 0x55, 0xc0, + 0xb5, 0x55, 0xa0, 0xa5, 0x55, 0xc0, 0xb0, 0x0, + 0x0, 0x0, 0x40, 0xa0, 0xb0, 0x6a, 0x65, 0x69, + 0x72, 0xa0, 0xb0, 0xa, 0x65, 0x78, 0x0, 0xa0, + 0xb0, 0xa, 0x10, 0x28, 0x0, 0xa0, 0xb0, 0xa, + 0x65, 0x78, 0x0, 0xa0, 0xb0, 0xa, 0x32, 0x5a, + 0x79, 0xa0, 0xb3, 0x54, 0x32, 0x38, 0x0, 0xb0, + 0xb0, 0x0, 0x0, 0x25, 0x3a, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+806F "聯" */ + 0x0, 0x0, 0x0, 0x2, 0x20, 0x3, 0x0, 0x5, + 0x55, 0x5c, 0x59, 0x30, 0x59, 0x0, 0x1, 0xb0, + 0x91, 0x54, 0x63, 0x80, 0x82, 0x0, 0xb0, 0x93, + 0xd7, 0x86, 0x87, 0x80, 0x0, 0xc5, 0xb1, 0x18, + 0x31, 0x36, 0x30, 0x0, 0xb0, 0x92, 0x93, 0x83, + 0x84, 0x94, 0x0, 0xb0, 0x93, 0xb5, 0x53, 0x83, + 0x23, 0x0, 0xc5, 0xb1, 0x1, 0x44, 0xa1, 0x10, + 0x0, 0xb0, 0x91, 0x1a, 0x44, 0xa0, 0xa0, 0x1, + 0xc6, 0xc5, 0x29, 0x64, 0xa0, 0xa0, 0xd, 0x71, + 0x91, 0x2a, 0x83, 0xa5, 0xb0, 0x0, 0x0, 0xa1, + 0x0, 0xa0, 0xa0, 0x0, 0x0, 0x0, 0xa2, 0x38, + 0x20, 0xb0, 0x0, 0x0, 0x0, 0x11, 0x10, 0x0, + 0x20, 0x0, + + /* U+8072 "聲" */ + 0x0, 0x0, 0x50, 0x0, 0x10, 0x10, 0x0, 0x4, + 0x55, 0xc5, 0xa2, 0xb5, 0xc1, 0x0, 0x1, 0x0, + 0xa0, 0x31, 0x80, 0xa4, 0x50, 0x2, 0x85, 0x55, + 0x57, 0x10, 0x28, 0x60, 0x0, 0xb5, 0xa6, 0xb2, + 0x95, 0xa8, 0x0, 0x1, 0xb5, 0xc6, 0x90, 0x1b, + 0x70, 0x0, 0x3, 0x60, 0x0, 0x2, 0x85, 0x98, + 0x50, 0x6, 0x35, 0x55, 0x68, 0x55, 0x89, 0x40, + 0x2, 0x1, 0xb1, 0x11, 0x17, 0x30, 0x0, 0x0, + 0x0, 0xb4, 0x44, 0x49, 0x30, 0x0, 0x0, 0x0, + 0xb5, 0x55, 0x5a, 0x30, 0x20, 0x2, 0x44, 0xc5, + 0x55, 0x5a, 0x76, 0x80, 0x1, 0x10, 0x0, 0x0, + 0x7, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+8077 "職" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x5, + 0x55, 0x5a, 0x3b, 0x10, 0xc0, 0x0, 0x0, 0xa0, + 0xa2, 0x68, 0x67, 0xb5, 0x30, 0x0, 0xa0, 0xa0, + 0x50, 0x55, 0xa0, 0xc0, 0x0, 0xc5, 0xc0, 0x73, + 0x70, 0xa0, 0x0, 0x0, 0xa0, 0xa4, 0x75, 0x85, + 0xc5, 0xb1, 0x0, 0xa0, 0xa0, 0x31, 0x40, 0xa1, + 0x90, 0x0, 0xc5, 0xc0, 0xb4, 0xa3, 0x94, 0x70, + 0x0, 0xa0, 0xa0, 0xa0, 0x81, 0x7b, 0x10, 0x0, + 0xb3, 0xc4, 0xb5, 0xb1, 0x4b, 0x0, 0xc, 0xa4, + 0xa0, 0xa0, 0x81, 0x8a, 0x3, 0x0, 0x0, 0xa0, + 0xa5, 0x84, 0x67, 0xa2, 0x0, 0x0, 0xb0, 0x0, + 0x26, 0x0, 0xc2, 0x0, 0x0, 0x10, 0x0, 0x10, + 0x0, 0x0, + + /* U+807D "聽" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x5, + 0x55, 0x57, 0x80, 0xa, 0x10, 0x30, 0x0, 0xa0, + 0xa, 0x46, 0x5a, 0x55, 0x71, 0x0, 0xc5, 0x5a, + 0x15, 0x36, 0x33, 0x60, 0x0, 0xc5, 0x5a, 0x1a, + 0x56, 0xb2, 0xb0, 0x0, 0xa0, 0xa, 0x1a, 0x44, + 0xa0, 0xa0, 0x6, 0x75, 0x5a, 0x1b, 0x77, 0xb4, + 0xa0, 0x5, 0x67, 0x5a, 0x15, 0x11, 0x11, 0x50, + 0x0, 0x83, 0xa, 0x36, 0x55, 0x55, 0x92, 0x5, + 0xa9, 0x3a, 0x1, 0x47, 0x11, 0x0, 0x0, 0x82, + 0xa, 0x34, 0xa2, 0x82, 0xa1, 0x6, 0xa6, 0x2a, + 0xd1, 0xa0, 0x4, 0x63, 0x4, 0x0, 0xb, 0x10, + 0xc9, 0x9c, 0x40, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, + + /* U+8089 "肉" */ + 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x60, 0x0, 0x0, 0x95, 0x55, 0xa8, 0x55, 0x5a, + 0x2d, 0x0, 0xc, 0x10, 0x0, 0xc1, 0xd0, 0x2, + 0xb8, 0x50, 0xc, 0x1d, 0x1, 0x92, 0x9, 0xc0, + 0xc1, 0xd2, 0x60, 0x97, 0x9, 0xc, 0x1d, 0x10, + 0xe, 0x20, 0x0, 0xc1, 0xd0, 0x7, 0x57, 0x81, + 0xc, 0x1d, 0x4, 0x60, 0x6, 0xd0, 0xc1, 0xd3, + 0x30, 0x0, 0x7, 0xc, 0x1d, 0x0, 0x0, 0x0, + 0x56, 0xe0, 0xc0, 0x0, 0x0, 0x0, 0xa9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+80A9 "肩" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x49, 0x55, + 0x57, 0x55, 0x5c, 0x30, 0x3, 0x90, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0x3b, 0x55, 0x55, 0x55, 0x5c, + 0x10, 0x3, 0x90, 0x10, 0x0, 0x0, 0x20, 0x0, + 0x48, 0xd, 0x55, 0x55, 0x6c, 0x0, 0x4, 0x70, + 0xc0, 0x0, 0x2, 0xa0, 0x0, 0x75, 0xd, 0x55, + 0x55, 0x6a, 0x0, 0xa, 0x10, 0xd5, 0x55, 0x56, + 0xa0, 0x0, 0x90, 0xc, 0x0, 0x0, 0x2a, 0x0, + 0x62, 0x0, 0xc0, 0x0, 0x2, 0x90, 0x23, 0x0, + 0xc, 0x0, 0x6, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+80AF "肯" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x70, 0xe, 0x0, 0x1, 0x0, 0x0, 0x6, + 0x70, 0xd, 0x55, 0x6a, 0x0, 0x0, 0x6, 0x70, + 0xd, 0x0, 0x0, 0x20, 0x17, 0x57, 0x75, 0x5a, + 0x55, 0x57, 0xa0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x40, 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xe1, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0xd, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, + 0xd, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xe, 0x0, 0x1, + 0x6d, 0xa0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+80B2 "育" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x10, 0x0, 0x20, 0x6, 0x55, 0x58, + 0x85, 0x55, 0x6a, 0x10, 0x0, 0x6, 0x92, 0x4, + 0x10, 0x0, 0x0, 0x39, 0x53, 0x33, 0x4c, 0xa0, + 0x0, 0x2, 0xa7, 0x53, 0x20, 0xa, 0x10, 0x0, + 0x9, 0x55, 0x55, 0x5b, 0x30, 0x0, 0x0, 0xa1, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0xa, 0x65, 0x55, + 0x5c, 0x20, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0xa, 0x65, 0x55, 0x5c, 0x20, 0x0, + 0x0, 0xa1, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xb, + 0x10, 0x3, 0x9e, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x10, 0x0, + + /* U+80CC "背" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd0, 0x2c, 0x0, 0x60, 0x6, 0x55, 0x6c, + 0x2, 0xb5, 0x98, 0x10, 0x0, 0x4, 0xc0, 0x2c, + 0x0, 0x4, 0x3b, 0x96, 0x4c, 0x1, 0xe6, 0x68, + 0xb0, 0x20, 0x2, 0x80, 0x4, 0x66, 0x52, 0x0, + 0xb, 0x55, 0x55, 0x55, 0xe1, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, 0x55, + 0x55, 0xc0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xc0, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, + 0x0, 0x1, 0x6c, 0xa0, 0x0, 0x0, 0x50, 0x0, + 0x0, 0x41, 0x0, + + /* U+80F8 "胸" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x65, + 0x5a, 0x14, 0x90, 0x0, 0x0, 0x9, 0x20, 0xb0, + 0x92, 0x0, 0x3, 0x10, 0x92, 0xb, 0xa, 0x57, + 0x65, 0xa3, 0x9, 0x65, 0xc4, 0x12, 0x79, 0x8, + 0x20, 0x92, 0xb, 0x2, 0x6a, 0x11, 0x82, 0x9, + 0x20, 0xb0, 0xb3, 0x90, 0xb8, 0x20, 0x96, 0x5c, + 0xa, 0x4b, 0xa, 0x81, 0xa, 0x10, 0xb0, 0xa7, + 0x82, 0xa9, 0x10, 0xb0, 0xb, 0xc, 0x23, 0x2a, + 0x91, 0xa, 0x0, 0xb0, 0xa5, 0x55, 0xaa, 0x1, + 0x62, 0x3c, 0x0, 0x0, 0x33, 0xc0, 0x40, 0x9, + 0x70, 0x0, 0x1, 0x89, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+80FD "能" */ + 0x0, 0x6, 0x0, 0x2, 0x0, 0x0, 0x0, 0x7, + 0x80, 0x0, 0xb2, 0x3, 0x0, 0x4, 0x60, 0x26, + 0xb, 0x7, 0xb1, 0x5, 0xa5, 0x55, 0xa5, 0xb6, + 0x20, 0x20, 0x35, 0x20, 0x2, 0x2b, 0x0, 0x6, + 0x0, 0xa5, 0x55, 0xb0, 0x8a, 0x99, 0xd1, 0xc, + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, + 0xa0, 0xb1, 0x5, 0x0, 0xc, 0x0, 0x1a, 0xb, + 0x7, 0xb2, 0x0, 0xd5, 0x55, 0xa0, 0xc8, 0x40, + 0x0, 0xc, 0x0, 0x1a, 0xb, 0x0, 0x4, 0x0, + 0xc0, 0x1, 0xa0, 0xb0, 0x0, 0x80, 0xc, 0x5, + 0xc8, 0xa, 0xba, 0xad, 0x30, 0x20, 0x3, 0x0, + 0x0, 0x0, 0x0, + + /* U+8131 "脱" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xa5, 0xa3, 0x8, 0x0, 0xe1, 0x0, 0x0, 0xb0, + 0x92, 0x9, 0x44, 0x70, 0x0, 0x0, 0xb0, 0x92, + 0x23, 0x17, 0x4, 0x0, 0x0, 0xc5, 0xb2, 0xb5, + 0x55, 0x5c, 0x0, 0x0, 0xb0, 0x92, 0xa0, 0x0, + 0x1b, 0x0, 0x0, 0xb0, 0x92, 0xa0, 0x0, 0x1b, + 0x0, 0x0, 0xc5, 0xb2, 0xb8, 0x9b, 0x6b, 0x0, + 0x0, 0xa0, 0x92, 0x24, 0x6a, 0x0, 0x0, 0x1, + 0x90, 0x92, 0x5, 0x5a, 0x0, 0x0, 0x4, 0x50, + 0x92, 0x8, 0x2a, 0x0, 0x40, 0x7, 0x11, 0xa1, + 0x1a, 0xa, 0x10, 0x70, 0x6, 0x5, 0xd2, 0x70, + 0x7, 0xb9, 0xc2, 0x10, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+814A "腊" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, + 0x95, 0xa3, 0x7, 0x80, 0xc1, 0x0, 0x0, 0xb0, + 0xa1, 0x7, 0x50, 0xb2, 0x30, 0x0, 0xb0, 0xa1, + 0x6a, 0x85, 0xc5, 0x40, 0x0, 0xc5, 0xc1, 0x7, + 0x50, 0xb0, 0x0, 0x0, 0xb0, 0xa3, 0x5a, 0x85, + 0xc5, 0xc2, 0x0, 0xb0, 0xa1, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0xc1, 0x65, 0x55, 0x59, 0x20, + 0x0, 0xb0, 0xa1, 0x92, 0x0, 0xa, 0x10, 0x1, + 0x90, 0xa1, 0x96, 0x55, 0x5c, 0x10, 0x3, 0x60, + 0xa1, 0x92, 0x0, 0xa, 0x10, 0x7, 0x11, 0xb0, + 0x96, 0x55, 0x5c, 0x10, 0x5, 0x6, 0xd0, 0x91, + 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8155 "腕" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, + 0x42, 0x61, 0x0, 0x38, 0x0, 0x0, 0x1, 0xb3, + 0xc0, 0x75, 0x5c, 0x55, 0x80, 0x1, 0xa0, 0xb2, + 0x95, 0x0, 0x3, 0x50, 0x1, 0xb5, 0xc2, 0x3a, + 0x0, 0x2, 0x0, 0x1, 0xa0, 0xb0, 0x68, 0x8b, + 0x5b, 0x20, 0x1, 0xa0, 0xb0, 0x90, 0xba, 0xa, + 0x0, 0x1, 0xb5, 0xc2, 0xa1, 0xaa, 0xa, 0x0, + 0x2, 0x90, 0xb4, 0x49, 0x6a, 0xa, 0x0, 0x3, + 0x70, 0xb0, 0xa, 0x1a, 0x3d, 0x0, 0x5, 0x40, + 0xb0, 0x18, 0xa, 0x3, 0x40, 0x8, 0x0, 0xb0, + 0x80, 0xa, 0x0, 0x70, 0x6, 0x18, 0xc5, 0x10, + 0x7, 0xa9, 0xc2, 0x10, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8166 "腦" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0xa3, 0x3d, 0xa, 0x50, 0xd1, 0x0, 0xb0, + 0xa1, 0x82, 0x19, 0x6, 0x60, 0x0, 0xb0, 0xa2, + 0x60, 0x70, 0x27, 0x0, 0x0, 0xc5, 0xc1, 0x91, + 0x47, 0x19, 0x30, 0x0, 0xb0, 0xa1, 0x3b, 0x48, + 0x61, 0xe0, 0x0, 0xb0, 0xa1, 0x4, 0xa1, 0x10, + 0x30, 0x0, 0xc5, 0xc1, 0xb5, 0x65, 0x55, 0xd0, + 0x0, 0xb0, 0xa1, 0xb2, 0x0, 0xd2, 0xb0, 0x0, + 0x90, 0xa1, 0xb0, 0x7b, 0x50, 0xb0, 0x3, 0x60, + 0xa1, 0xb0, 0x5b, 0x70, 0xb0, 0x6, 0x10, 0xa0, + 0xb3, 0x50, 0xb1, 0xb0, 0x6, 0x29, 0xd0, 0xb6, + 0x55, 0x55, 0xb0, 0x11, 0x0, 0x20, 0x50, 0x0, + 0x0, 0x50, + + /* U+8170 "腰" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x65, 0xc4, 0x55, 0x55, 0x58, 0x70, 0x9, 0x20, + 0xb1, 0xa, 0xa, 0x0, 0x0, 0x9, 0x20, 0xb5, + 0x6c, 0x5c, 0x5a, 0x10, 0x9, 0x65, 0xb7, 0x3a, + 0xa, 0xb, 0x0, 0x9, 0x20, 0xb7, 0x3a, 0xa, + 0xb, 0x0, 0x9, 0x20, 0xb7, 0x79, 0x57, 0x5c, + 0x0, 0x9, 0x65, 0xb1, 0x9, 0x50, 0x0, 0x0, + 0x9, 0x10, 0xb6, 0x5d, 0x55, 0x77, 0x90, 0xa, + 0x0, 0xb0, 0x64, 0x5, 0x60, 0x0, 0x9, 0x0, + 0xb0, 0xb4, 0x1b, 0x0, 0x0, 0x17, 0x11, 0xb0, + 0x2, 0xda, 0x61, 0x0, 0x50, 0x2c, 0x71, 0x58, + 0x20, 0x5d, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, + 0x1, 0x0, + + /* U+819D "膝" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x4, + 0x37, 0x30, 0x0, 0xb1, 0x4, 0x0, 0xa, 0x2a, + 0x25, 0x59, 0xf5, 0x57, 0x20, 0xa, 0xa, 0x10, + 0x2a, 0xb6, 0x82, 0x0, 0xa, 0x5c, 0x12, 0x80, + 0x70, 0x2e, 0x20, 0xa, 0xa, 0x33, 0x6, 0xc2, + 0x3, 0x10, 0xa, 0xa, 0x10, 0x3a, 0x6, 0x60, + 0x0, 0xa, 0x5c, 0x14, 0x70, 0xb1, 0x6d, 0x80, + 0xa, 0xa, 0x33, 0x55, 0xb2, 0xb2, 0x20, 0xa, + 0xa, 0x10, 0x8, 0xd4, 0x0, 0x0, 0x9, 0xa, + 0x10, 0x66, 0xb5, 0x93, 0x0, 0x25, 0x1b, 0x1c, + 0x50, 0xb0, 0x1d, 0x20, 0x50, 0x5b, 0x0, 0x18, + 0xe0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+81C9 "臉" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x1, + 0x85, 0xa1, 0x0, 0x8a, 0x0, 0x0, 0x1, 0x90, + 0xa0, 0x2, 0x91, 0x50, 0x0, 0x1, 0x90, 0xa0, + 0x9, 0x0, 0x57, 0x0, 0x1, 0xb5, 0xb0, 0x65, + 0x55, 0x96, 0xc3, 0x1, 0x90, 0xa2, 0x20, 0x21, + 0x10, 0x40, 0x1, 0x90, 0xa0, 0xb5, 0xb3, 0xa5, + 0xb0, 0x1, 0xb5, 0xb0, 0x90, 0x92, 0x70, 0x90, + 0x1, 0x80, 0xa0, 0xb5, 0xa3, 0x95, 0x90, 0x3, + 0x60, 0xa0, 0x1b, 0x0, 0x38, 0x0, 0x5, 0x30, + 0xa0, 0x49, 0x0, 0x74, 0x0, 0x7, 0x12, 0xa0, + 0x82, 0xb0, 0x96, 0x80, 0x4, 0x9, 0x63, 0x30, + 0x36, 0x10, 0x74, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+81EA "自" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x10, 0x44, 0x0, 0x3, 0xd, 0x56, 0x55, + 0x55, 0xd4, 0xd0, 0x0, 0x0, 0xc, 0xd, 0x0, + 0x0, 0x0, 0xc0, 0xd5, 0x55, 0x55, 0x5d, 0xd, + 0x0, 0x0, 0x0, 0xc0, 0xd0, 0x0, 0x0, 0xc, + 0xd, 0x55, 0x55, 0x55, 0xd0, 0xd0, 0x0, 0x0, + 0xc, 0xd, 0x0, 0x0, 0x0, 0xc0, 0xe5, 0x55, + 0x55, 0x5d, 0x14, 0x0, 0x0, 0x0, 0x40, + + /* U+81F3 "至" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x55, 0x55, 0x55, 0x55, 0x6d, 0x20, 0x1, 0x0, + 0xa, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, + 0x1, 0x50, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, + 0x2c, 0x50, 0x0, 0x0, 0x89, 0x45, 0x66, 0x67, + 0xe5, 0x0, 0x0, 0x98, 0x53, 0xb2, 0x0, 0x34, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x55, 0x55, 0xc7, 0x55, 0xd5, 0x0, 0x0, + 0x10, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x7, 0x50, 0x26, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x40, + + /* U+81FA "臺" */ + 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x10, 0x6, + 0x55, 0x55, 0x6c, 0x55, 0x58, 0xa0, 0x0, 0x24, + 0x44, 0x6b, 0x44, 0x94, 0x0, 0x0, 0x8, 0x55, + 0x55, 0x55, 0xa1, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x1, 0xb, 0x55, 0x55, 0x55, + 0x90, 0x0, 0x8, 0x55, 0x55, 0x55, 0x55, 0x56, + 0xd1, 0x4b, 0x35, 0x55, 0x65, 0x56, 0xb5, 0x20, + 0x0, 0x0, 0x48, 0x30, 0x6, 0x30, 0x0, 0x0, + 0x1d, 0xc8, 0x88, 0x55, 0xc5, 0x0, 0x0, 0x3, + 0x0, 0x38, 0x0, 0x82, 0x0, 0x0, 0x36, 0x55, + 0x7b, 0x55, 0x52, 0x0, 0x4, 0x55, 0x55, 0x7b, + 0x55, 0x5c, 0x70, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8207 "與" */ + 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x24, 0xa7, 0x70, 0x1, 0x16, 0x0, 0x0, 0xd2, + 0x6, 0x85, 0xa6, 0x4d, 0x20, 0x0, 0xc0, 0x26, + 0x50, 0x0, 0xc, 0x0, 0x0, 0xc5, 0x59, 0x85, + 0xb3, 0x6c, 0x0, 0x0, 0xb0, 0x3, 0x0, 0xb0, + 0xb, 0x0, 0x0, 0xc5, 0x99, 0x40, 0xb2, 0x5c, + 0x0, 0x0, 0xc0, 0x9, 0x20, 0xb0, 0x1b, 0x0, + 0x0, 0xc0, 0x9, 0x20, 0xb0, 0xb, 0x50, 0x8, + 0x65, 0x66, 0x55, 0x65, 0x56, 0x61, 0x0, 0x1, + 0xd5, 0x0, 0x17, 0x50, 0x0, 0x0, 0x1b, 0x40, + 0x0, 0x0, 0x5d, 0x40, 0x4, 0x81, 0x0, 0x0, + 0x0, 0x4, 0xb0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8208 "興" */ + 0x0, 0x38, 0x68, 0x55, 0x85, 0x15, 0x0, 0x0, + 0xc1, 0x19, 0x2, 0x65, 0x5c, 0x10, 0x0, 0xb2, + 0x1a, 0x66, 0x84, 0xb, 0x0, 0x0, 0xb5, 0x39, + 0x67, 0x75, 0x5c, 0x0, 0x0, 0xa0, 0x19, 0x89, + 0x64, 0xb, 0x0, 0x0, 0xb8, 0x49, 0x89, 0x65, + 0x4b, 0x0, 0x0, 0xb1, 0x19, 0x89, 0x64, 0x2b, + 0x0, 0x0, 0xb0, 0x19, 0x0, 0x64, 0x1b, 0x50, + 0x6, 0x65, 0x57, 0x55, 0x65, 0x56, 0x61, 0x0, + 0x0, 0x9a, 0x0, 0x18, 0x60, 0x0, 0x0, 0x9, + 0x70, 0x0, 0x0, 0x7e, 0x50, 0x3, 0x71, 0x0, + 0x0, 0x0, 0x5, 0x90, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8209 "舉" */ + 0x0, 0x0, 0x31, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xa7, 0x85, 0xd5, 0x95, 0x6c, 0x20, 0x0, 0xb0, + 0x31, 0xa0, 0x0, 0xb, 0x0, 0x0, 0xb5, 0x65, + 0xb5, 0xa5, 0x6b, 0x0, 0x0, 0xa0, 0x61, 0x50, + 0xc0, 0xa, 0x0, 0x0, 0xa6, 0x53, 0xb0, 0xc4, + 0x6b, 0x0, 0x5, 0xb6, 0x56, 0xb5, 0xd5, 0x5d, + 0xb1, 0x1, 0x0, 0xc4, 0x25, 0x5, 0x0, 0x0, + 0x0, 0xa, 0x50, 0x37, 0x24, 0x80, 0x0, 0x1, + 0x93, 0x46, 0x79, 0x54, 0x2b, 0x50, 0x15, 0x25, + 0x55, 0x79, 0x55, 0xb6, 0x70, 0x0, 0x1, 0x0, + 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+822A "航" */ + 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x0, 0x45, 0x0, 0x0, 0x0, 0x99, + 0x5a, 0x0, 0xb, 0x1, 0x0, 0x0, 0xb0, 0xb, + 0x45, 0x55, 0x59, 0x50, 0x0, 0xb6, 0x2b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb2, 0x6b, 0x9, 0x55, + 0xb2, 0x0, 0x15, 0xc5, 0x5c, 0xa, 0x10, 0xb0, + 0x0, 0x1, 0xa1, 0xb, 0xa, 0x10, 0xb0, 0x0, + 0x0, 0xa6, 0x4b, 0xa, 0x0, 0xb0, 0x0, 0x1, + 0x81, 0x7b, 0xa, 0x0, 0xb0, 0x0, 0x4, 0x40, + 0xb, 0x9, 0x0, 0xb0, 0x40, 0x7, 0x1, 0xb, + 0x43, 0x0, 0xb0, 0x80, 0x14, 0x2, 0xc9, 0x60, + 0x0, 0x8b, 0xe2, 0x10, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+822C "般" */ + 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x7, 0x55, 0x82, 0x0, 0x0, 0xa7, + 0x5b, 0x2a, 0x10, 0xb0, 0x0, 0x0, 0xb3, 0xb, + 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb4, 0x7b, 0xa, + 0x0, 0x8b, 0xc2, 0x0, 0xb0, 0x3b, 0x35, 0x0, + 0x0, 0x0, 0x5, 0xc5, 0x5c, 0x37, 0x55, 0x7c, + 0x0, 0x0, 0xb2, 0xb, 0x4, 0x10, 0x75, 0x0, + 0x0, 0xb6, 0x4b, 0x0, 0x60, 0xc0, 0x0, 0x1, + 0x91, 0x7b, 0x0, 0x79, 0x60, 0x0, 0x4, 0x50, + 0xb, 0x0, 0x4f, 0x30, 0x0, 0x8, 0x2, 0x3c, + 0x4, 0x91, 0xc8, 0x10, 0x24, 0x0, 0x78, 0x64, + 0x0, 0x9, 0xc1, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+8239 "船" */ + 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x40, 0x0, 0xa5, 0x5b, 0x0, 0x0, 0x98, + 0x5b, 0x20, 0xa0, 0xb, 0x0, 0x0, 0xb1, 0xb, + 0x0, 0xa0, 0xb, 0x0, 0x0, 0xb5, 0x5b, 0x2, + 0x80, 0xb, 0x0, 0x0, 0xb0, 0x4b, 0x7, 0x20, + 0xb, 0xb6, 0x16, 0xc5, 0x5c, 0x34, 0x0, 0x0, + 0x0, 0x0, 0xa1, 0xb, 0x11, 0x75, 0x56, 0x60, + 0x0, 0x96, 0x4b, 0x2, 0x90, 0x5, 0x60, 0x2, + 0x70, 0x6b, 0x1, 0x90, 0x5, 0x50, 0x5, 0x30, + 0xb, 0x1, 0x90, 0x5, 0x50, 0x8, 0x1, 0x4b, + 0x2, 0xb5, 0x59, 0x60, 0x13, 0x0, 0x67, 0x2, + 0x80, 0x4, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+826F "良" */ + 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x20, 0x0, 0x0, 0x8, 0x55, 0xb6, 0x59, 0x30, + 0x0, 0xc0, 0x0, 0x0, 0xa2, 0x0, 0xc, 0x0, + 0x0, 0xa, 0x20, 0x0, 0xd5, 0x55, 0x55, 0xc2, + 0x0, 0xc, 0x0, 0x0, 0xa, 0x20, 0x0, 0xd5, + 0x65, 0x55, 0xb2, 0x0, 0xc, 0x2, 0x30, 0x5, + 0xd1, 0x0, 0xc0, 0x8, 0x37, 0x50, 0x0, 0xc, + 0x0, 0x3b, 0x10, 0x0, 0x0, 0xc5, 0x71, 0x2b, + 0x94, 0x10, 0xd, 0x50, 0x0, 0x5, 0xce, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8272 "色" */ + 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd5, 0x0, 0x50, 0x0, 0x0, 0x0, 0x7, + 0x95, 0x58, 0xe3, 0x0, 0x0, 0x0, 0x2a, 0x0, + 0x9, 0x10, 0x0, 0x0, 0x1, 0xd6, 0x55, 0x86, + 0x55, 0xa1, 0x0, 0x16, 0x82, 0x0, 0xb0, 0x0, + 0xb0, 0x0, 0x0, 0x82, 0x0, 0xb0, 0x0, 0xb0, + 0x0, 0x0, 0x87, 0x55, 0xc5, 0x55, 0xc0, 0x0, + 0x0, 0x82, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, + 0x82, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x83, 0x0, + 0x0, 0x0, 0x1, 0xa0, 0x0, 0x5d, 0xaa, 0xaa, + 0xaa, 0xac, 0xa0, + + /* U+8282 "节" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc, 0x1, 0xa0, 0x6, 0x55, 0x5d, + 0x55, 0x5d, 0x55, 0x52, 0x0, 0x0, 0xb, 0x0, + 0xa, 0x0, 0x0, 0x0, 0x45, 0x55, 0x55, 0x55, + 0x5a, 0x0, 0x0, 0x10, 0x0, 0xb0, 0x0, 0x2b, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x2b, 0x0, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x2b, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x58, 0xe8, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+82B1 "花" */ + 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x84, 0x1, 0xc0, 0x0, 0x0, 0x25, 0x55, + 0xa7, 0x56, 0xd5, 0x5c, 0x80, 0x1, 0x0, 0x73, + 0x1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, + 0x50, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x7, 0x20, + 0x2, 0x0, 0x0, 0xb, 0x20, 0xb, 0x10, 0x8c, + 0x0, 0x0, 0x5f, 0x10, 0xb, 0x2a, 0x80, 0x0, + 0x1, 0x9c, 0x0, 0xb, 0xb3, 0x0, 0x0, 0x27, + 0xc, 0x2, 0x7d, 0x10, 0x0, 0x0, 0x10, 0xc, + 0x12, 0xa, 0x10, 0x0, 0x50, 0x0, 0xc, 0x0, + 0xa, 0x10, 0x0, 0x80, 0x0, 0xc, 0x0, 0x7, + 0xca, 0xab, 0xc0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+82E5 "若" */ + 0x0, 0x0, 0x21, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0xc2, 0x0, 0x0, 0x5, 0x55, + 0x99, 0x55, 0xd5, 0x5c, 0x30, 0x0, 0x0, 0x56, + 0x10, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x33, 0xd0, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, + 0x3, 0x40, 0x6, 0x55, 0x5d, 0x55, 0x55, 0x56, + 0x50, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe5, 0x55, 0x57, 0x90, 0x0, 0x0, + 0x4a, 0xc0, 0x0, 0x4, 0x80, 0x0, 0x5, 0x50, + 0xc0, 0x0, 0x4, 0x80, 0x0, 0x10, 0x0, 0xc5, + 0x55, 0x58, 0x80, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x4, 0x70, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+82E6 "苦" */ + 0x0, 0x0, 0x20, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0xd, 0x0, 0x10, 0x6, 0x55, + 0xa8, 0x55, 0x5c, 0x56, 0xc2, 0x0, 0x0, 0x74, + 0x10, 0xb, 0x0, 0x0, 0x0, 0x0, 0x31, 0xa4, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, + 0x1, 0x80, 0x6, 0x55, 0x55, 0xc5, 0x55, 0x55, + 0x51, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x55, 0x85, 0x55, 0xb3, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x0, 0xa1, 0x0, 0x0, 0xd, 0x55, 0x55, + 0x55, 0xc1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+82F1 "英" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x67, 0x0, 0x1c, 0x0, 0x30, 0x6, 0x55, + 0x88, 0x55, 0x5c, 0x56, 0xb2, 0x0, 0x0, 0x55, + 0x42, 0xa, 0x0, 0x0, 0x0, 0x0, 0x11, 0x84, + 0x1, 0x0, 0x0, 0x0, 0xa, 0x55, 0xb7, 0x55, + 0xc3, 0x0, 0x0, 0xb, 0x0, 0x92, 0x0, 0xa0, + 0x0, 0x0, 0xb, 0x0, 0xa1, 0x0, 0xa0, 0x0, + 0x5, 0x5c, 0x55, 0xd5, 0x55, 0xc6, 0xd2, 0x1, + 0x0, 0x2, 0xb3, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x74, 0x0, 0x0, 0x0, 0x1, 0xa5, + 0x0, 0x8, 0xa3, 0x0, 0x0, 0x57, 0x10, 0x0, + 0x0, 0x3c, 0xd2, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+8336 "茶" */ + 0x0, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0xc1, 0x3, 0x0, 0x6, 0x55, + 0xc6, 0x55, 0xd5, 0x59, 0x60, 0x0, 0x0, 0xb2, + 0xc1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x29, 0x65, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x86, 0x1, 0x81, + 0x0, 0x0, 0x0, 0x18, 0x40, 0x82, 0x9, 0xa4, + 0x10, 0x4, 0x50, 0x0, 0xc0, 0x2, 0x8b, 0x60, + 0x0, 0x55, 0x55, 0xd5, 0x57, 0x70, 0x0, 0x0, + 0x1, 0xa0, 0xc0, 0x33, 0x0, 0x0, 0x0, 0xa, + 0x40, 0xc0, 0x5, 0xa1, 0x0, 0x0, 0x82, 0x10, + 0xc0, 0x0, 0x6c, 0x0, 0x4, 0x0, 0x2b, 0xd0, + 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8377 "荷" */ + 0x0, 0x0, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x49, 0x0, 0x10, 0x5, 0x55, + 0x5d, 0x55, 0x79, 0x56, 0xc2, 0x0, 0x0, 0xc, + 0x0, 0x36, 0x0, 0x0, 0x0, 0x3, 0xa3, 0x0, + 0x11, 0x0, 0x30, 0x0, 0xa, 0x46, 0x55, 0x55, + 0x59, 0xa3, 0x0, 0x4b, 0x0, 0x0, 0x10, 0x1a, + 0x0, 0x1, 0xad, 0x8, 0x65, 0xe1, 0x1a, 0x0, + 0x7, 0x1b, 0x8, 0x30, 0xb0, 0x1a, 0x0, 0x0, + 0xb, 0x8, 0x30, 0xb0, 0x1a, 0x0, 0x0, 0xb, + 0x8, 0x75, 0xb0, 0x1a, 0x0, 0x0, 0xb, 0x6, + 0x10, 0x0, 0x1a, 0x0, 0x0, 0x1c, 0x0, 0x0, + 0x5, 0xc8, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x20, 0x0, + + /* U+83D3 "菓" */ + 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x48, 0x0, 0x20, 0x6, 0x55, + 0x8a, 0x55, 0x89, 0x57, 0xb2, 0x0, 0x0, 0x47, + 0x0, 0x46, 0x0, 0x0, 0x0, 0xb, 0x55, 0x58, + 0x55, 0xd4, 0x0, 0x0, 0xb, 0x0, 0x1a, 0x0, + 0xc0, 0x0, 0x0, 0xc, 0x55, 0x6c, 0x55, 0xd0, + 0x0, 0x0, 0xc, 0x55, 0x6c, 0x55, 0xd0, 0x0, + 0x0, 0x4, 0x0, 0x1a, 0x0, 0x38, 0x0, 0x2, + 0x65, 0x57, 0xdc, 0x85, 0x56, 0x40, 0x0, 0x0, + 0x2c, 0x4a, 0x36, 0x0, 0x0, 0x0, 0x5, 0x91, + 0x1a, 0x4, 0xb4, 0x0, 0x4, 0x63, 0x0, 0x2a, + 0x0, 0x2b, 0xd2, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+83DC "菜" */ + 0x0, 0x0, 0x4, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0xc1, 0x1, 0x40, 0x6, 0x55, + 0x5d, 0x55, 0xd5, 0x57, 0x90, 0x0, 0x0, 0xa, + 0x0, 0x73, 0x81, 0x0, 0x0, 0x34, 0x56, 0x78, + 0x97, 0x62, 0x0, 0x0, 0x11, 0x0, 0x54, 0x0, + 0xb1, 0x0, 0x0, 0xb, 0x30, 0xb, 0x4, 0x70, + 0x0, 0x0, 0x3, 0x30, 0x38, 0x7, 0x0, 0x20, + 0x17, 0x55, 0x55, 0xab, 0x65, 0x58, 0xb1, 0x0, + 0x0, 0xa, 0x88, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x95, 0x38, 0x19, 0x10, 0x0, 0x0, 0x29, 0x20, + 0x38, 0x2, 0xc8, 0x30, 0x5, 0x50, 0x0, 0x38, + 0x0, 0x7, 0x91, 0x0, 0x0, 0x0, 0x11, 0x0, + 0x0, 0x0, + + /* U+843D "落" */ + 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x0, 0xc0, 0x3, 0x20, 0x6, 0x55, + 0xc5, 0x55, 0xc5, 0x58, 0x70, 0x1, 0x40, 0x60, + 0x36, 0x50, 0x0, 0x0, 0x0, 0x86, 0x10, 0xa7, + 0x55, 0x80, 0x0, 0x0, 0x2, 0x42, 0x84, 0x8, + 0x40, 0x0, 0xa, 0x23, 0x27, 0x5, 0x77, 0x0, + 0x0, 0x3, 0x47, 0x21, 0x6, 0xc6, 0x0, 0x0, + 0x0, 0x17, 0x0, 0x76, 0x5, 0xc7, 0x30, 0x3, + 0xb3, 0x37, 0xa5, 0x55, 0xb7, 0x70, 0x2, 0xd0, + 0x2, 0x90, 0x0, 0xb0, 0x0, 0x0, 0xd0, 0x2, + 0x90, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x2, 0xb5, + 0x55, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+8449 "葉" */ + 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x91, 0x0, 0xb1, 0x6, 0x60, 0x16, 0x55, + 0xb5, 0x55, 0xc5, 0x55, 0x50, 0x0, 0x6, 0x35, + 0x10, 0x50, 0x0, 0x0, 0x0, 0xa, 0x1b, 0x10, + 0xa3, 0x16, 0x0, 0x4, 0x5c, 0x5c, 0x55, 0xb6, + 0x55, 0x10, 0x0, 0xa, 0xb, 0x55, 0xb1, 0x0, + 0x0, 0x0, 0xc, 0x57, 0x55, 0x75, 0xb1, 0x0, + 0x0, 0x2, 0x0, 0xc0, 0x0, 0x4, 0x0, 0x5, + 0x55, 0x5a, 0xe7, 0x55, 0x6a, 0x40, 0x0, 0x0, + 0x79, 0xc1, 0x60, 0x0, 0x0, 0x0, 0x19, 0x50, + 0xc0, 0x1a, 0x71, 0x0, 0x14, 0x50, 0x0, 0xd0, + 0x0, 0x6e, 0x90, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, + + /* U+8457 "著" */ + 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x6, 0x70, 0xc, 0x10, 0x60, 0x5, 0x55, 0x98, + 0x55, 0xc5, 0x57, 0x30, 0x0, 0x5, 0x38, 0x27, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x61, 0xb2, + 0x0, 0x0, 0x65, 0x5c, 0x56, 0xd6, 0x0, 0x4, + 0x55, 0x55, 0xc5, 0xd8, 0x5b, 0x70, 0x10, 0x0, + 0x4, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x6a, 0xb5, + 0x55, 0xa0, 0x0, 0x1, 0x7e, 0x10, 0x0, 0xb, + 0x0, 0x15, 0x50, 0xb5, 0x55, 0x55, 0xb0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0xb5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x2, 0x0, + + /* U+8535 "蔵" */ + 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0xa3, 0x2, 0x40, 0x6, 0x55, + 0x6b, 0x55, 0xb6, 0x57, 0x80, 0x0, 0x0, 0x5, + 0x0, 0x74, 0x80, 0x0, 0x0, 0x41, 0x11, 0x11, + 0x97, 0x76, 0x50, 0x0, 0xb4, 0x44, 0x46, 0x88, + 0x44, 0x30, 0x0, 0xb1, 0xb6, 0x87, 0x56, 0x6, + 0x20, 0x0, 0xb1, 0x93, 0x54, 0x38, 0xc, 0x30, + 0x0, 0xb1, 0xb5, 0x5c, 0x1b, 0x39, 0x0, 0x0, + 0xb1, 0xb5, 0x6b, 0xb, 0xb1, 0x0, 0x0, 0x91, + 0x93, 0x52, 0x9, 0xa0, 0x40, 0x5, 0x22, 0xa5, + 0x68, 0x75, 0xa5, 0x70, 0x5, 0x0, 0x0, 0x16, + 0x20, 0xa, 0xc0, 0x10, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x20, + + /* U+8584 "薄" */ + 0x0, 0x0, 0x3, 0x0, 0x21, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x58, 0x1, 0x50, 0x3, 0x65, + 0x5c, 0x55, 0x8a, 0x85, 0x60, 0x1, 0x81, 0x4, + 0x0, 0xa1, 0x83, 0x20, 0x0, 0x46, 0x26, 0x55, + 0xd5, 0x56, 0x70, 0x4, 0x0, 0x47, 0x55, 0xc5, + 0x5c, 0x0, 0x5, 0x84, 0x9, 0x54, 0xc4, 0x4b, + 0x0, 0x0, 0x26, 0x9, 0x31, 0xb1, 0x1b, 0x0, + 0x0, 0x44, 0x9, 0x65, 0xc5, 0x6a, 0x0, 0x5, + 0xe0, 0x56, 0x55, 0x65, 0xd5, 0xb1, 0x0, 0xc0, + 0x11, 0x70, 0x0, 0xb0, 0x0, 0x0, 0xe0, 0x0, + 0x54, 0x0, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x0, + 0x5d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+85AC "薬" */ + 0x0, 0x0, 0x2, 0x0, 0x11, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x3a, 0x0, 0x81, 0x6, 0x55, + 0x5c, 0x55, 0x7a, 0x55, 0x52, 0x0, 0x0, 0x2, + 0x2a, 0x11, 0x0, 0x0, 0x1, 0x72, 0x17, 0x95, + 0x59, 0x2, 0x60, 0x0, 0x2a, 0x19, 0x0, 0xa, + 0x58, 0x30, 0x0, 0x0, 0x4b, 0x55, 0x5a, 0x40, + 0x0, 0x4, 0x96, 0x29, 0x0, 0xa, 0x1a, 0x80, + 0x3, 0x10, 0x19, 0x57, 0x57, 0x0, 0x60, 0x3, + 0x55, 0x55, 0x5e, 0x55, 0x57, 0xd1, 0x1, 0x0, + 0x9, 0x9b, 0x51, 0x0, 0x0, 0x0, 0x2, 0xa5, + 0xb, 0x7, 0x82, 0x0, 0x3, 0x55, 0x0, 0xb, + 0x0, 0x3c, 0xd3, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+85DD "藝" */ + 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x1b, 0x0, 0x80, 0x5, 0x55, + 0x5c, 0x55, 0x6a, 0x55, 0x52, 0x0, 0x0, 0xa0, + 0x10, 0x7, 0x0, 0x0, 0x0, 0x65, 0xb5, 0x73, + 0x5c, 0x58, 0x0, 0x3, 0x75, 0x96, 0x93, 0xa, + 0x18, 0x0, 0x1, 0x92, 0xb6, 0x90, 0x5b, 0x19, + 0x0, 0x3, 0x26, 0xb5, 0x30, 0x95, 0x7b, 0x40, + 0x0, 0x78, 0xa5, 0x35, 0x21, 0x16, 0xc0, 0x0, + 0x33, 0x65, 0x55, 0x57, 0x72, 0x20, 0x1, 0x65, + 0x55, 0x95, 0x55, 0x5a, 0x30, 0x0, 0x0, 0x18, + 0x71, 0x27, 0x30, 0x0, 0x0, 0x8, 0xea, 0x87, + 0x54, 0xb4, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8607 "蘇" */ + 0x0, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0xa2, 0x2, 0x50, 0x6, 0x55, + 0x5b, 0x55, 0xc5, 0x55, 0x50, 0x0, 0x8, 0x24, + 0x0, 0x40, 0x15, 0x0, 0x0, 0x3c, 0x5a, 0x13, + 0x5b, 0x86, 0x10, 0x0, 0xa0, 0x44, 0x0, 0xa, + 0x0, 0x0, 0x6, 0xb5, 0xa5, 0xa5, 0x6d, 0x59, + 0x50, 0x0, 0x90, 0x91, 0x80, 0x9d, 0x50, 0x0, + 0x0, 0xb5, 0xb5, 0x80, 0x9a, 0x70, 0x0, 0x0, + 0x90, 0x91, 0x93, 0x5a, 0x29, 0x0, 0x0, 0x85, + 0x55, 0x45, 0xb, 0x9, 0xa1, 0x0, 0x43, 0x65, + 0x60, 0xb, 0x0, 0x20, 0xa, 0x2a, 0x44, 0x70, + 0xb, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+8655 "處" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xd5, 0x55, 0x61, 0x0, 0x0, 0xb5, 0x55, + 0xa5, 0x55, 0x59, 0x90, 0x0, 0xb0, 0x0, 0xd1, + 0x3, 0x16, 0x0, 0x0, 0xb2, 0x34, 0xc4, 0x55, + 0x32, 0x0, 0x0, 0xb0, 0x20, 0xb9, 0x88, 0x9a, + 0x0, 0x0, 0xb0, 0xa4, 0x1, 0x20, 0x20, 0x0, + 0x0, 0xa0, 0xc5, 0x8b, 0x87, 0xc2, 0x0, 0x0, + 0x95, 0x80, 0x93, 0x91, 0xa0, 0x20, 0x3, 0x57, + 0x36, 0xa0, 0x90, 0xa0, 0x70, 0x6, 0x10, 0x2c, + 0x97, 0x10, 0x38, 0x70, 0x13, 0x5, 0x60, 0x17, + 0xac, 0xdd, 0xb1, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+884C "行" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x80, 0x0, 0x0, 0x6, 0x0, 0x0, 0x3a, + 0x0, 0x55, 0x55, 0x56, 0x10, 0x1, 0x80, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x1, 0xd1, 0x0, + 0x0, 0x0, 0x20, 0x0, 0xb, 0x34, 0x65, 0x59, + 0x57, 0x90, 0x0, 0x7e, 0x10, 0x0, 0xc, 0x0, + 0x0, 0x4, 0x6c, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x13, 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, + 0x12, 0x2c, 0x0, 0x0, 0x0, 0xc, 0x0, 0x6, + 0xe8, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+8853 "術" */ + 0x0, 0x21, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0xd2, 0x2, 0x55, 0x90, 0x1, 0x90, + 0x0, 0xb5, 0x60, 0x10, 0x0, 0x7, 0x9, 0x0, + 0xb0, 0x60, 0x0, 0x0, 0x20, 0x5a, 0x33, 0xc6, + 0x50, 0x0, 0x50, 0x0, 0xd1, 0x2a, 0xc1, 0x15, + 0x6c, 0x51, 0x7, 0xd2, 0xb, 0xc4, 0x0, 0xb, + 0x0, 0x32, 0xb0, 0x19, 0xb6, 0x90, 0xb, 0x0, + 0x0, 0xb0, 0x63, 0xb0, 0x70, 0xb, 0x0, 0x0, + 0xb0, 0x70, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb4, + 0x10, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb1, 0x0, + 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb0, 0x0, 0xb0, + 0x6, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+8868 "表" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc1, 0x0, 0x1, 0x0, 0x1, 0x65, + 0x55, 0xd5, 0x55, 0x6c, 0x10, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x20, 0x0, 0x0, 0x26, 0x55, 0xd5, + 0x55, 0x92, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x2, 0x30, 0x6, 0x55, 0x57, 0xe5, 0x55, 0x57, + 0x70, 0x0, 0x0, 0xc, 0x45, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0xc4, 0x8, 0x28, 0x20, 0x0, 0x0, + 0x3a, 0xe0, 0x1, 0xb0, 0x0, 0x0, 0x16, 0x50, + 0xd0, 0x0, 0x4a, 0x10, 0x0, 0x0, 0x0, 0xd2, + 0x73, 0x3, 0xda, 0x61, 0x0, 0x0, 0xe9, 0x0, + 0x0, 0x7, 0x40, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+88AB "被" */ + 0x0, 0x20, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x49, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x6, + 0x0, 0x0, 0xb, 0x0, 0x0, 0x5, 0x55, 0xc1, + 0xb5, 0x5c, 0x55, 0xe1, 0x0, 0x2, 0xa0, 0xb0, + 0xb, 0x5, 0x30, 0x0, 0xa, 0x33, 0xb0, 0xb, + 0x0, 0x0, 0x0, 0x3b, 0x65, 0xc5, 0x5b, 0x5a, + 0x30, 0x0, 0x8d, 0x60, 0xc1, 0x30, 0xd, 0x0, + 0x6, 0xb, 0x94, 0xb0, 0x60, 0x66, 0x0, 0x0, + 0xb, 0x15, 0xa0, 0x55, 0xc0, 0x0, 0x0, 0xb, + 0x4, 0x50, 0xe, 0x50, 0x0, 0x0, 0xb, 0x8, + 0x1, 0x94, 0xa6, 0x0, 0x0, 0xc, 0x43, 0x56, + 0x0, 0x8, 0xd3, 0x0, 0x1, 0x11, 0x0, 0x0, + 0x0, 0x0, + + /* U+88CF "裏" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3a, 0x0, 0x5, 0x20, 0x5, 0x55, + 0x55, 0x55, 0x55, 0x65, 0x30, 0x0, 0xc, 0x55, + 0x69, 0x55, 0xd1, 0x0, 0x0, 0xc, 0x55, 0x6b, + 0x55, 0xc0, 0x0, 0x0, 0xb, 0x0, 0x19, 0x0, + 0xb0, 0x0, 0x0, 0x7, 0x55, 0x6b, 0x55, 0x70, + 0x0, 0x0, 0x36, 0x55, 0x6b, 0x55, 0x74, 0x0, + 0x4, 0x65, 0x55, 0x8a, 0x55, 0x58, 0x80, 0x0, + 0x0, 0x7, 0xa5, 0x1, 0xc4, 0x0, 0x0, 0x4, + 0xba, 0x3, 0x87, 0x20, 0x0, 0x3, 0x64, 0x48, + 0x15, 0x4a, 0x85, 0x30, 0x0, 0x0, 0x6d, 0x70, + 0x0, 0x49, 0x40, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+88DC "補" */ + 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x0, 0xd, 0x37, 0x0, 0x0, 0x7, + 0x0, 0x0, 0xb, 0x7, 0x40, 0x6, 0x55, 0xc4, + 0x65, 0x5c, 0x55, 0xb3, 0x0, 0x3, 0x90, 0x20, + 0xb, 0x0, 0x30, 0x0, 0xa, 0x23, 0xb5, 0x5c, + 0x57, 0xb0, 0x0, 0x4c, 0x57, 0xb0, 0xb, 0x2, + 0x90, 0x1, 0x8c, 0x70, 0xb5, 0x5c, 0x56, 0x90, + 0x6, 0xb, 0x95, 0xb0, 0xb, 0x2, 0x90, 0x10, + 0xb, 0x17, 0xb5, 0x5c, 0x56, 0x90, 0x0, 0xb, + 0x0, 0xb0, 0xb, 0x2, 0x90, 0x0, 0xb, 0x0, + 0xb0, 0xb, 0x2, 0x90, 0x0, 0xc, 0x0, 0xb0, + 0xa, 0x3b, 0x60, 0x0, 0x1, 0x0, 0x20, 0x0, + 0x1, 0x0, + + /* U+88E1 "裡" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0x0, 0x30, 0x0, 0x4, 0x0, 0x0, 0x7, + 0x0, 0xb5, 0x5c, 0x5c, 0x20, 0x6, 0x55, 0xc1, + 0xa0, 0xb, 0xa, 0x0, 0x0, 0x3, 0x90, 0xa5, + 0x5c, 0x5c, 0x0, 0x0, 0xa, 0x23, 0xa0, 0xb, + 0xa, 0x0, 0x0, 0x3c, 0x48, 0xa0, 0xb, 0xa, + 0x0, 0x0, 0x8c, 0x70, 0xb5, 0x5c, 0x5b, 0x0, + 0x6, 0xb, 0x95, 0x40, 0xb, 0x0, 0x0, 0x10, + 0xb, 0x17, 0x0, 0xb, 0x6, 0x10, 0x0, 0xb, + 0x0, 0x75, 0x5c, 0x55, 0x20, 0x0, 0xb, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x5, 0x55, + 0x5c, 0x57, 0xc1, 0x0, 0x3, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+88FD "製" */ + 0x0, 0x10, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x84, 0xa3, 0x1, 0x0, 0xb, 0x20, 0x2, 0x95, + 0xc5, 0x68, 0x8, 0xb, 0x0, 0x7, 0x55, 0xc5, + 0x5a, 0x1b, 0xb, 0x0, 0x0, 0x75, 0xc5, 0x58, + 0xb, 0xb, 0x0, 0x0, 0xa0, 0xa0, 0xa, 0xb, + 0xb, 0x0, 0x0, 0xa0, 0xa1, 0x79, 0x2, 0x1b, + 0x0, 0x0, 0x60, 0x90, 0x64, 0x0, 0x7a, 0x0, + 0x4, 0x55, 0x55, 0x5b, 0x55, 0x5d, 0x60, 0x1, + 0x0, 0x3a, 0x25, 0x0, 0x73, 0x0, 0x0, 0x17, + 0xd1, 0x0, 0x76, 0x50, 0x0, 0x15, 0x40, 0xa1, + 0x55, 0x1a, 0x51, 0x0, 0x0, 0x0, 0xbb, 0x30, + 0x0, 0x6c, 0x80, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8907 "複" */ + 0x0, 0x20, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x57, 0x0, 0xc, 0x40, 0x0, 0x10, 0x0, 0xa, + 0x0, 0x1d, 0x55, 0x56, 0xa1, 0x5, 0x55, 0xa0, + 0x76, 0x0, 0x4, 0x0, 0x0, 0x3, 0xa1, 0x6c, + 0x55, 0x5c, 0x20, 0x0, 0xa, 0x25, 0xc, 0x55, + 0x5c, 0x0, 0x0, 0x3b, 0x57, 0xb, 0x0, 0xb, + 0x0, 0x0, 0x9c, 0x70, 0x9, 0xd5, 0x58, 0x0, + 0x7, 0xa, 0x94, 0x4, 0xa5, 0x5b, 0x0, 0x0, + 0xa, 0x16, 0x17, 0x50, 0x67, 0x0, 0x0, 0xa, + 0x0, 0x40, 0x46, 0xa0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x6d, 0x60, 0x0, 0x0, 0xa, 0x1, 0x57, + 0x30, 0x5c, 0xa3, 0x0, 0x1, 0x12, 0x0, 0x0, + 0x0, 0x10, + + /* U+897F "西" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, 0x65, + 0x55, 0xc5, 0x5c, 0x55, 0x53, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0x0, 0x7, 0x55, 0xc5, 0x5c, + 0x55, 0x92, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb, + 0x0, 0xb, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0x0, + 0xb0, 0x1a, 0x0, 0xb0, 0xb, 0x0, 0xb, 0x6, + 0x40, 0xb, 0x1, 0xb0, 0x0, 0xb1, 0x70, 0x0, + 0x7a, 0x9b, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, + 0xb0, 0x0, 0xc5, 0x55, 0x55, 0x55, 0x5d, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8981 "要" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, + 0x55, 0x55, 0x55, 0x56, 0xd2, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0x0, 0x7, 0x55, 0xc5, 0x5c, + 0x5b, 0x20, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb0, + 0x0, 0xb, 0x0, 0xb0, 0xb, 0xb, 0x0, 0x0, + 0xa5, 0x5a, 0x65, 0x55, 0x90, 0x0, 0x0, 0x1, + 0xd1, 0x0, 0x0, 0x61, 0x26, 0x55, 0xc7, 0x55, + 0x89, 0x57, 0x40, 0x0, 0x39, 0x0, 0xb, 0x10, + 0x0, 0x0, 0x3, 0x66, 0x7b, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0x66, 0xca, 0x10, 0x3, 0x56, + 0x74, 0x0, 0x0, 0x59, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+898B "見" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x55, 0xe1, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, + 0x55, 0x55, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x55, + 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0xd, 0x5c, 0x65, 0xd5, 0xb0, 0x0, 0x0, + 0x3, 0xc, 0x0, 0xc0, 0x0, 0x10, 0x0, 0x0, + 0x1c, 0x0, 0xc0, 0x0, 0x50, 0x0, 0x0, 0xa4, + 0x0, 0xc0, 0x0, 0x90, 0x0, 0x48, 0x40, 0x0, + 0xdb, 0xaa, 0xe2, 0x14, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+898F "規" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x85, 0x55, 0x5b, 0x20, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0xb, 0x0, 0x4, 0x5c, 0x74, + 0xb5, 0x55, 0x5c, 0x0, 0x1, 0xb, 0x0, 0xb0, + 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0xb5, 0x55, + 0x5c, 0x0, 0x17, 0x5c, 0x59, 0xb0, 0x0, 0xb, + 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, 0xb, 0x0, + 0x0, 0x1c, 0x10, 0xb5, 0xd7, 0x9a, 0x0, 0x0, + 0x37, 0x76, 0x10, 0xc3, 0x70, 0x0, 0x0, 0x82, + 0xc, 0x14, 0x83, 0x70, 0x20, 0x1, 0x70, 0x1, + 0xb, 0x13, 0x70, 0x60, 0x6, 0x0, 0x3, 0x71, + 0x2, 0xca, 0xd1, 0x10, 0x0, 0x11, 0x0, 0x0, + 0x0, 0x0, + + /* U+8996 "視" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x85, 0x55, 0x5b, 0x30, 0x0, 0x8, + 0x20, 0xb0, 0x0, 0xb, 0x0, 0x6, 0x55, 0xb2, + 0xb5, 0x55, 0x5c, 0x0, 0x0, 0x2, 0xa0, 0xb0, + 0x0, 0xb, 0x0, 0x0, 0xa, 0x10, 0xb5, 0x55, + 0x5c, 0x0, 0x0, 0x5d, 0x10, 0xb0, 0x0, 0xb, + 0x0, 0x2, 0x7b, 0xa5, 0xb0, 0x0, 0xb, 0x0, + 0x15, 0xb, 0x19, 0xb5, 0xd7, 0x9b, 0x0, 0x0, + 0xb, 0x0, 0x0, 0xb3, 0x70, 0x0, 0x0, 0xb, + 0x0, 0x5, 0x73, 0x70, 0x30, 0x0, 0xc, 0x0, + 0x1a, 0x3, 0x70, 0x70, 0x0, 0xc, 0x3, 0x60, + 0x1, 0xca, 0xe2, 0x0, 0x1, 0x21, 0x0, 0x0, + 0x0, 0x0, + + /* U+899A "覚" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x72, 0xa, 0x10, 0x97, 0x0, 0x1, 0x1, 0xc0, + 0x57, 0x19, 0x0, 0x0, 0x75, 0x56, 0x55, 0x58, + 0x55, 0xa9, 0x3d, 0x1, 0x0, 0x0, 0x2, 0x9, + 0x1, 0x20, 0xa5, 0x55, 0x55, 0xd4, 0x10, 0x0, + 0xa, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x0, 0xa0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0xa, 0x55, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0xa5, 0x75, 0x75, 0xc0, + 0x0, 0x0, 0x3, 0xc, 0xb, 0x3, 0x0, 0x30, + 0x0, 0x7, 0x60, 0xb0, 0x0, 0x15, 0x0, 0x47, + 0x50, 0x8, 0xba, 0xac, 0x90, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+89AA "親" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x80, 0x6, 0x55, 0x56, 0x80, 0x2, 0x65, + 0xa6, 0x89, 0x10, 0x3, 0x60, 0x0, 0x51, 0xb, + 0x9, 0x65, 0x57, 0x60, 0x0, 0x1a, 0x16, 0x9, + 0x10, 0x3, 0x60, 0x5, 0x56, 0x85, 0xa9, 0x65, + 0x57, 0x60, 0x0, 0x1, 0x80, 0x9, 0x10, 0x3, + 0x60, 0x2, 0x56, 0xb6, 0x69, 0x65, 0x57, 0x60, + 0x0, 0x1, 0x80, 0x8, 0x47, 0xa2, 0x40, 0x0, + 0xa4, 0x95, 0x0, 0x55, 0xa0, 0x0, 0x2, 0x81, + 0x86, 0x80, 0x82, 0xa0, 0x20, 0x7, 0x1, 0x80, + 0x71, 0x90, 0xa0, 0x40, 0x1, 0x4c, 0x50, 0x26, + 0x0, 0x7a, 0xc4, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+89BA "覺" */ + 0x0, 0x0, 0x20, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x71, 0x6a, 0x36, 0x98, 0x0, 0x0, 0xa4, + 0x63, 0x47, 0x14, 0x94, 0x0, 0x0, 0x92, 0x31, + 0x4a, 0x12, 0xa2, 0x0, 0x0, 0x87, 0x43, 0x7a, + 0x16, 0xd0, 0x0, 0x9, 0x76, 0x55, 0x55, 0x55, + 0x97, 0xb0, 0x58, 0x8, 0x55, 0x55, 0x5a, 0x25, + 0x0, 0x0, 0xa, 0x55, 0x55, 0x5b, 0x0, 0x0, + 0x0, 0xa, 0x33, 0x33, 0x3b, 0x0, 0x0, 0x0, + 0xa, 0x11, 0x11, 0x1a, 0x10, 0x0, 0x0, 0x8, + 0x5c, 0x5c, 0x58, 0x0, 0x30, 0x0, 0x0, 0x56, + 0xa, 0x0, 0x0, 0x60, 0x0, 0x36, 0x50, 0x8, + 0xa9, 0x9a, 0xd0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+89C0 "觀" */ + 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x93, 0x56, 0x6, 0x55, 0x57, 0x60, 0x6, 0xb6, + 0x99, 0x99, 0x10, 0x5, 0x50, 0x1, 0x53, 0x42, + 0x28, 0x65, 0x58, 0x50, 0xa, 0x5b, 0xa5, 0xb8, + 0x10, 0x5, 0x50, 0xa, 0x59, 0xa5, 0x98, 0x65, + 0x58, 0x50, 0x2, 0xa5, 0x50, 0x8, 0x10, 0x5, + 0x50, 0x4, 0xa5, 0xa7, 0x78, 0x65, 0x58, 0x50, + 0xb, 0x52, 0x81, 0x8, 0x57, 0xa4, 0x30, 0x26, + 0x86, 0xa6, 0x30, 0x55, 0xa0, 0x0, 0x5, 0x86, + 0xa7, 0x40, 0x82, 0xa0, 0x20, 0x5, 0x52, 0x81, + 0x21, 0x90, 0xa0, 0x50, 0x6, 0x85, 0x55, 0x66, + 0x0, 0x9a, 0xd3, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+89D2 "角" */ + 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x90, 0x1, 0x0, 0x0, 0x0, 0x1, 0xd5, + 0x55, 0xc9, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x18, + 0x0, 0x0, 0x0, 0x7d, 0x55, 0x5a, 0x55, 0x5e, + 0x0, 0x63, 0xb0, 0x0, 0xc0, 0x0, 0xc0, 0x0, + 0xb, 0x55, 0x5d, 0x55, 0x5c, 0x0, 0x0, 0xb0, + 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xc, 0x55, 0x5d, + 0x55, 0x5c, 0x0, 0x0, 0xb0, 0x0, 0xc0, 0x0, + 0xc0, 0x0, 0x38, 0x0, 0xc, 0x0, 0xc, 0x0, + 0xa, 0x10, 0x0, 0xc0, 0x0, 0xc0, 0x7, 0x20, + 0x0, 0x1a, 0x6, 0xda, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+89E3 "解" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x4, 0x56, 0x55, 0xa0, 0x0, 0x2d, + 0x58, 0x0, 0x1b, 0x0, 0xb0, 0x0, 0x92, 0x58, + 0x0, 0x75, 0x0, 0xa0, 0x3, 0xc5, 0x97, 0x63, + 0x90, 0x4a, 0x70, 0x4, 0xa0, 0xa5, 0x74, 0x41, + 0x93, 0x0, 0x0, 0xc5, 0xc8, 0x50, 0xc2, 0xa0, + 0x20, 0x0, 0xa0, 0xa5, 0x55, 0x95, 0xc6, 0x70, + 0x0, 0xb3, 0xb7, 0x67, 0x1, 0xa0, 0x0, 0x0, + 0xa2, 0xb7, 0x77, 0x55, 0xc5, 0x95, 0x2, 0x70, + 0xa5, 0x50, 0x1, 0xa0, 0x0, 0x6, 0x20, 0xb5, + 0x50, 0x1, 0xa0, 0x0, 0x6, 0x0, 0x6b, 0x40, + 0x1, 0xb0, 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, + 0x10, 0x0, + + /* U+89E6 "触" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x2c, + 0x5a, 0x20, 0x0, 0xa0, 0x0, 0x0, 0x91, 0x28, + 0x0, 0x0, 0xa0, 0x10, 0x4, 0xc5, 0x95, 0xa3, + 0xa5, 0xc5, 0xd0, 0x13, 0xa0, 0x90, 0xa3, 0x70, + 0xa0, 0xa0, 0x0, 0xc5, 0xb5, 0xa3, 0x70, 0xa0, + 0xa0, 0x0, 0xa0, 0x90, 0xa3, 0x70, 0xa0, 0xa0, + 0x0, 0xc5, 0xb5, 0xa3, 0xa5, 0xc5, 0xa0, 0x0, + 0xa0, 0x90, 0xa1, 0x10, 0xa0, 0x0, 0x2, 0x60, + 0x90, 0xa0, 0x0, 0xa2, 0x60, 0x6, 0x10, 0xa0, + 0xa3, 0x56, 0xc4, 0xb3, 0x5, 0x0, 0x47, 0x98, + 0x62, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A00 "言" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x35, 0x0, 0x5, 0x20, 0x65, 0x55, 0x55, 0x55, + 0x55, 0x54, 0x0, 0x0, 0x0, 0x0, 0x2, 0x70, + 0x0, 0x0, 0x65, 0x55, 0x55, 0x55, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x65, + 0x55, 0x55, 0x56, 0x10, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x40, 0x0, 0x0, 0xc5, 0x55, 0x55, 0x6c, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x2, 0xa0, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x7a, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8A08 "計" */ + 0x0, 0x21, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x1d, 0x10, 0x0, 0xd, 0x10, 0x0, 0x15, 0x5d, + 0x67, 0x80, 0xc, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x3, 0x44, 0x49, 0x0, + 0xc, 0x0, 0x30, 0x2, 0x21, 0x11, 0x36, 0x5d, + 0x56, 0x80, 0x4, 0x55, 0x5a, 0x10, 0xc, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x7, 0x55, 0x59, 0x0, 0xc, 0x0, 0x0, 0xb, + 0x0, 0xb, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, + 0xb, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0x5b, + 0x0, 0xd, 0x0, 0x0, 0xb, 0x0, 0xb, 0x0, + 0xd, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+8A0A "訊" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x39, 0x4, 0x68, 0x55, 0xd0, 0x0, 0x15, 0x5c, + 0x6a, 0xb, 0x0, 0xc0, 0x0, 0x1, 0x0, 0x0, + 0xb, 0x0, 0xb0, 0x0, 0x4, 0x55, 0x91, 0xb, + 0x0, 0xb0, 0x0, 0x1, 0x0, 0x0, 0xb, 0x10, + 0xb0, 0x0, 0x4, 0x55, 0xa3, 0x6c, 0x74, 0xa0, + 0x0, 0x1, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, + 0x7, 0x55, 0x92, 0xb, 0x0, 0xb0, 0x0, 0xb, + 0x0, 0xa1, 0xb, 0x0, 0x93, 0x10, 0xb, 0x0, + 0xa1, 0xb, 0x0, 0x48, 0x60, 0xb, 0x55, 0xc1, + 0xc, 0x0, 0xc, 0xb0, 0xb, 0x0, 0xa1, 0xb, + 0x0, 0x1, 0xd0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A0E "討" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x46, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xa, + 0x6, 0x0, 0x0, 0xd0, 0x0, 0x26, 0x55, 0x55, + 0x10, 0x0, 0xd0, 0x10, 0x4, 0x55, 0x93, 0x54, + 0x44, 0xd5, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x50, 0x8, 0x0, 0xd0, + 0x0, 0x5, 0x55, 0x50, 0x4, 0xb0, 0xd0, 0x0, + 0x6, 0x55, 0x82, 0x0, 0x90, 0xd0, 0x0, 0xb, + 0x0, 0xa1, 0x0, 0x0, 0xd0, 0x0, 0xb, 0x0, + 0xa1, 0x0, 0x0, 0xd0, 0x0, 0xb, 0x55, 0xc1, + 0x1, 0x0, 0xd0, 0x0, 0xc, 0x0, 0xa1, 0x1, + 0x7e, 0xc0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, + 0x10, 0x0, + + /* U+8A13 "訓" */ + 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, + 0x39, 0x0, 0xc, 0x7, 0x11, 0xc0, 0x25, 0x5b, + 0x6a, 0xc, 0xb, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0xc, 0xb, 0x0, 0xa0, 0x5, 0x55, 0x91, 0xb, + 0xb, 0x0, 0xa0, 0x0, 0x0, 0x10, 0xc, 0xb, + 0x0, 0xa0, 0x4, 0x55, 0x81, 0xc, 0xb, 0x0, + 0xa0, 0x0, 0x0, 0x10, 0xc, 0xb, 0x0, 0xa0, + 0xb, 0x55, 0xc3, 0x1a, 0xb, 0x0, 0xa0, 0xb, + 0x0, 0xa1, 0x56, 0xb, 0x0, 0xa0, 0xb, 0x0, + 0xa1, 0xa1, 0xb, 0x0, 0xa0, 0xb, 0x55, 0x94, + 0x70, 0x7, 0x1, 0xa0, 0x5, 0x0, 0x16, 0x0, + 0x0, 0x1, 0xa0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A18 "記" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x25, 0x55, 0x5a, 0x20, 0x25, 0x5d, + 0x59, 0x31, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x4, 0x55, 0x58, 0x0, + 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, 0x9, 0x55, + 0x5d, 0x0, 0x4, 0x55, 0x76, 0xc, 0x0, 0x5, + 0x0, 0x1, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x7, 0x55, 0x5a, 0xc, 0x0, 0x0, 0x0, 0xb, + 0x0, 0xc, 0xc, 0x0, 0x0, 0x10, 0xb, 0x0, + 0xb, 0xc, 0x0, 0x0, 0x50, 0xb, 0x55, 0x5b, + 0xc, 0x0, 0x0, 0x90, 0xc, 0x0, 0xb, 0x9, + 0xcb, 0xbc, 0xb0, 0x2, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A2A "訪" */ + 0x0, 0x20, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x0, 0x4b, 0x0, 0x0, 0x25, 0x6b, + 0x68, 0x0, 0xb, 0x30, 0x10, 0x1, 0x0, 0x0, + 0x65, 0x85, 0x57, 0x90, 0x4, 0x55, 0x91, 0x0, + 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xd0, + 0x1, 0x0, 0x3, 0x55, 0x80, 0x0, 0xc5, 0x5c, + 0x40, 0x1, 0x0, 0x0, 0x2, 0x80, 0xa, 0x10, + 0x7, 0x55, 0xa2, 0x6, 0x50, 0xb, 0x0, 0xb, + 0x0, 0xb0, 0xa, 0x0, 0xc, 0x0, 0xb, 0x0, + 0xb0, 0x27, 0x0, 0xc, 0x0, 0xb, 0x55, 0xc0, + 0x80, 0x12, 0x2a, 0x0, 0xb, 0x0, 0x95, 0x20, + 0x5, 0xf3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x10, 0x0, + + /* U+8A2D "設" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x67, 0x0, 0xb, 0x55, 0xd2, 0x0, 0x25, 0x6b, + 0x67, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x0, 0xb0, 0x0, 0x5, 0x55, 0x91, 0x29, + 0x0, 0xb2, 0x30, 0x0, 0x0, 0x0, 0x80, 0x0, + 0x4a, 0x92, 0x4, 0x65, 0x84, 0x46, 0x55, 0x6d, + 0x10, 0x0, 0x0, 0x0, 0x6, 0x0, 0x88, 0x0, + 0xa, 0x55, 0xb2, 0x3, 0x41, 0xc0, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0x9a, 0x30, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0x9c, 0x0, 0x0, 0xb, 0x55, 0xc0, + 0x7, 0x46, 0xa0, 0x0, 0xb, 0x0, 0x72, 0x72, + 0x0, 0x7e, 0x81, 0x1, 0x0, 0x13, 0x0, 0x0, + 0x3, 0x40, + + /* U+8A31 "許" */ + 0x0, 0x20, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, + 0x49, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x15, 0x5d, + 0x59, 0x8, 0x30, 0x1, 0x0, 0x1, 0x0, 0x0, + 0xc, 0x58, 0x59, 0x40, 0x4, 0x55, 0x91, 0x45, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0xc, + 0x0, 0x0, 0x3, 0x55, 0x92, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x65, 0x5d, 0x55, 0xc1, + 0x7, 0x55, 0xa2, 0x0, 0xc, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, 0x70, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+8A33 "訳" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x29, 0x0, 0x5, 0x22, 0x22, 0x60, 0x26, 0x59, + 0x6a, 0x1d, 0x33, 0x34, 0xa0, 0x0, 0x0, 0x10, + 0xc, 0x0, 0x2, 0x90, 0x4, 0x55, 0x80, 0xc, + 0x0, 0x2, 0x90, 0x0, 0x0, 0x10, 0xd, 0x56, + 0x56, 0x90, 0x4, 0x55, 0x70, 0xb, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1a, 0x7, 0x0, 0x0, + 0xb, 0x55, 0xc4, 0x28, 0x8, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x64, 0x4, 0x60, 0x0, 0xb, 0x0, + 0xb0, 0x90, 0x0, 0xc1, 0x0, 0xb, 0x55, 0xc2, + 0x80, 0x0, 0x4c, 0x0, 0x6, 0x0, 0x27, 0x0, + 0x0, 0x9, 0xd4, 0x0, 0x0, 0x31, 0x0, 0x0, + 0x0, 0x40, + + /* U+8A34 "訴" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x68, 0x0, 0x3, 0x36, 0xac, 0x30, 0x16, 0x6a, + 0x69, 0xd, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x4, 0x65, 0x81, 0xd, + 0x55, 0x55, 0xb1, 0x0, 0x0, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0x3, 0x55, 0x80, 0xc, 0x22, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x1b, 0x4, 0xe8, 0x10, + 0xa, 0x55, 0xc2, 0x38, 0x0, 0xc5, 0xe0, 0xb, + 0x0, 0xb0, 0x74, 0x0, 0xc0, 0x30, 0xb, 0x0, + 0xb0, 0xa0, 0x0, 0xc0, 0x0, 0xb, 0x55, 0xc5, + 0x40, 0x0, 0xd0, 0x0, 0x7, 0x0, 0x36, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A55 "評" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x36, 0x59, 0x56, 0x70, 0x15, 0x5d, + 0x67, 0x20, 0xc, 0x1, 0x30, 0x1, 0x0, 0x0, + 0x56, 0xc, 0x6, 0xa0, 0x3, 0x55, 0x90, 0xe, + 0x1c, 0xa, 0x0, 0x1, 0x0, 0x0, 0x8, 0x1c, + 0x34, 0x0, 0x3, 0x44, 0x70, 0x0, 0xc, 0x10, + 0x50, 0x1, 0x11, 0x11, 0x65, 0x5d, 0x55, 0x71, + 0x7, 0x55, 0x92, 0x0, 0xc, 0x0, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0xc0, + 0x0, 0xd, 0x0, 0x0, 0xb, 0x0, 0xa0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A66 "試" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x74, 0x0, 0x0, 0xb, 0x43, 0x0, 0x0, 0x1a, + 0x4, 0x0, 0xb, 0xc, 0x10, 0x16, 0x55, 0x56, + 0x11, 0x1b, 0x13, 0x60, 0x3, 0x55, 0x82, 0x32, + 0x2b, 0x32, 0x20, 0x1, 0x0, 0x0, 0x0, 0x9, + 0x10, 0x0, 0x0, 0x0, 0x51, 0x67, 0xa9, 0x30, + 0x0, 0x4, 0x55, 0x50, 0xb, 0x6, 0x50, 0x0, + 0x6, 0x55, 0x81, 0xb, 0x3, 0x80, 0x0, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x10, 0xb, 0x0, + 0xb0, 0x4d, 0x62, 0x84, 0x50, 0xb, 0x55, 0xc3, + 0x91, 0x0, 0x1c, 0xa0, 0xb, 0x0, 0xa0, 0x0, + 0x0, 0x2, 0xb0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A71 "話" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0x0, 0x14, 0x7c, 0xa0, 0x15, 0x5c, + 0x59, 0x24, 0x5c, 0x31, 0x0, 0x1, 0x0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x2, 0x33, 0x80, 0x0, + 0xb, 0x0, 0x70, 0x2, 0x21, 0x12, 0x65, 0x5c, + 0x55, 0x51, 0x3, 0x55, 0x80, 0x0, 0xb, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x43, 0x3c, 0x37, 0x10, + 0x7, 0x55, 0x91, 0x94, 0x22, 0x2b, 0x10, 0xb, + 0x0, 0xb0, 0x92, 0x0, 0xb, 0x0, 0xb, 0x0, + 0xb0, 0x92, 0x0, 0xb, 0x0, 0xb, 0x55, 0xc0, + 0x96, 0x55, 0x5c, 0x0, 0xb, 0x0, 0x90, 0x91, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A72 "該" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x73, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x1a, + 0x4, 0x0, 0xc, 0x0, 0x0, 0x16, 0x55, 0x55, + 0x54, 0x54, 0x44, 0xa1, 0x3, 0x55, 0x80, 0x0, + 0xc4, 0x1, 0x0, 0x1, 0x0, 0x0, 0x8, 0x50, + 0x2e, 0x10, 0x0, 0x0, 0x40, 0xaa, 0x87, 0xc4, + 0x0, 0x4, 0x55, 0x50, 0x44, 0x17, 0x52, 0x0, + 0x6, 0x55, 0x81, 0x0, 0x73, 0x1d, 0x40, 0xb, + 0x0, 0xb0, 0x45, 0x0, 0xb4, 0x0, 0xb, 0x0, + 0xb1, 0x0, 0x1c, 0x86, 0x0, 0xb, 0x55, 0xc0, + 0x3, 0xa2, 0x6, 0xb0, 0xc, 0x0, 0xa2, 0x66, + 0x0, 0x0, 0xb2, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A73 "詳" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, + 0x67, 0x0, 0x9, 0x10, 0x2d, 0x10, 0x15, 0x5b, + 0x6a, 0x6, 0x90, 0x73, 0x0, 0x1, 0x0, 0x1, + 0x45, 0x84, 0xa4, 0xb1, 0x3, 0x55, 0x91, 0x21, + 0x1c, 0x11, 0x10, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x2, 0x0, 0x3, 0x55, 0x90, 0x26, 0x5d, 0x57, + 0x30, 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x6, 0x44, 0x81, 0x0, 0xc, 0x0, 0x70, 0xb, + 0x0, 0xb2, 0x65, 0x5d, 0x55, 0x52, 0xb, 0x0, + 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0x9, 0x0, 0x70, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+8A8C "誌" */ + 0x0, 0x20, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0xc, 0x0, 0x0, 0x15, 0x6b, + 0x68, 0x0, 0xb, 0x0, 0x20, 0x1, 0x0, 0x0, + 0x65, 0x5c, 0x56, 0xa0, 0x3, 0x55, 0x90, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x4, 0x10, 0x3, 0x55, 0x80, 0x26, 0x55, 0x55, + 0x20, 0x1, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, + 0x6, 0x55, 0x91, 0x8, 0x1c, 0x31, 0x0, 0xb, + 0x0, 0xb0, 0x6b, 0x3, 0x24, 0x90, 0xb, 0x0, + 0xb3, 0x8b, 0x0, 0x3, 0xa4, 0xb, 0x55, 0xc7, + 0x2b, 0x10, 0x19, 0x0, 0xb, 0x0, 0xb0, 0x3, + 0xaa, 0xa5, 0x0, 0x2, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A8D "認" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x57, 0x0, 0x14, 0x44, 0x45, 0x70, 0x15, 0x5c, + 0x68, 0x2, 0x76, 0x14, 0xa0, 0x1, 0x0, 0x0, + 0x42, 0x93, 0x4, 0x80, 0x3, 0x55, 0x91, 0xc1, + 0xc0, 0x6, 0x60, 0x1, 0x0, 0x0, 0x27, 0x60, + 0x9, 0x40, 0x3, 0x55, 0x70, 0x38, 0x3, 0x9d, + 0x0, 0x1, 0x0, 0x0, 0x40, 0x35, 0x21, 0x0, + 0x7, 0x55, 0x92, 0x7, 0x1b, 0x21, 0x0, 0xb, + 0x0, 0xb0, 0x6b, 0x3, 0x5, 0x60, 0xb, 0x0, + 0xb4, 0x8b, 0x0, 0x4, 0xb1, 0xb, 0x55, 0xc5, + 0x2b, 0x10, 0x29, 0x10, 0xb, 0x0, 0xa0, 0x3, + 0xaa, 0xa6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A95 "誕" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x84, 0x1, 0x15, 0x0, 0x16, 0x90, 0x15, 0x8a, + 0x97, 0x4d, 0x36, 0xb6, 0x20, 0x1, 0x0, 0x0, + 0x57, 0x0, 0x72, 0x0, 0x4, 0x55, 0x80, 0xb1, + 0x5, 0x72, 0x0, 0x0, 0x0, 0x3, 0xa2, 0xb, + 0x77, 0x90, 0x4, 0x55, 0x83, 0x6b, 0x4a, 0x72, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0x72, 0x0, + 0xa, 0x55, 0xc5, 0xa, 0xa, 0x72, 0x0, 0xa, + 0x0, 0xa1, 0xb6, 0x2c, 0x97, 0x90, 0xa, 0x0, + 0xa0, 0xb9, 0x2, 0x0, 0x0, 0xa, 0x55, 0xb7, + 0x34, 0xc8, 0x53, 0x21, 0x5, 0x0, 0x53, 0x0, + 0x5, 0xac, 0xa1, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A98 "誘" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x85, 0x0, 0x35, 0x7a, 0xbb, 0x20, 0x15, 0x79, + 0x92, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x65, 0x7d, 0x65, 0xb1, 0x4, 0x55, 0x80, 0x2, + 0xbb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x1b, + 0x2b, 0x10, 0x4, 0x55, 0x74, 0x70, 0xb, 0x3, + 0xd3, 0x0, 0x0, 0x10, 0x46, 0x95, 0x7a, 0x0, + 0xb, 0x55, 0xd1, 0x2, 0xb0, 0x85, 0x0, 0xb, + 0x0, 0xb0, 0x5, 0x70, 0xb5, 0xd1, 0xb, 0x0, + 0xb0, 0xb, 0x10, 0x0, 0xc0, 0xb, 0x55, 0xc0, + 0x75, 0x0, 0x4, 0x90, 0x4, 0x0, 0x26, 0x30, + 0x2, 0xae, 0x20, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x11, 0x0, + + /* U+8A9E "語" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x74, 0x0, 0x22, 0x22, 0x28, 0x0, 0x0, 0x1a, + 0x13, 0x33, 0xb3, 0x33, 0x0, 0x16, 0x55, 0x54, + 0x12, 0xb2, 0x52, 0x0, 0x3, 0x55, 0x80, 0x3, + 0xa2, 0xa3, 0x0, 0x1, 0x0, 0x0, 0x1, 0x80, + 0xa2, 0x0, 0x0, 0x0, 0x41, 0x35, 0x93, 0xc5, + 0xa0, 0x4, 0x55, 0x51, 0x42, 0x22, 0x22, 0x20, + 0x6, 0x55, 0x81, 0x1a, 0x44, 0x4d, 0x0, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0xc, 0x0, 0xb, 0x0, + 0xb0, 0xb, 0x0, 0xc, 0x0, 0xb, 0x55, 0xc0, + 0xd, 0x55, 0x5c, 0x0, 0xa, 0x0, 0x80, 0x1a, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AAA "說" */ + 0x0, 0x20, 0x0, 0x0, 0x30, 0x30, 0x0, 0x0, + 0x57, 0x0, 0x2, 0xd1, 0x70, 0x0, 0x15, 0x5c, + 0x68, 0xa, 0x20, 0x64, 0x0, 0x1, 0x0, 0x0, + 0x65, 0x0, 0xc, 0x40, 0x3, 0x55, 0x94, 0x58, + 0x55, 0x5c, 0xb2, 0x0, 0x0, 0x0, 0xb, 0x0, + 0xa, 0x0, 0x3, 0x55, 0x90, 0xb, 0x0, 0xa, + 0x0, 0x1, 0x0, 0x0, 0xc, 0x33, 0x3b, 0x0, + 0x7, 0x55, 0x92, 0x7, 0xb3, 0xc5, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0xb0, 0xb0, 0x0, 0xb, 0x0, + 0xb0, 0x1, 0xa0, 0xb0, 0x30, 0xb, 0x55, 0xc0, + 0x8, 0x30, 0xb0, 0x60, 0xb, 0x0, 0xa0, 0x64, + 0x0, 0xb9, 0xd1, 0x1, 0x0, 0x3, 0x10, 0x0, + 0x0, 0x0, + + /* U+8AAC "説" */ + 0x0, 0x20, 0x0, 0x10, 0x0, 0x23, 0x0, 0x0, + 0x77, 0x0, 0xa, 0x0, 0x78, 0x0, 0x15, 0x6b, + 0x75, 0x8, 0x50, 0x90, 0x0, 0x1, 0x0, 0x0, + 0x44, 0x44, 0x66, 0x0, 0x4, 0x55, 0x91, 0xb3, + 0x33, 0x3b, 0x10, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0xa, 0x0, 0x4, 0x55, 0x90, 0xb0, 0x0, 0xa, + 0x0, 0x0, 0x0, 0x0, 0xb6, 0x85, 0x8b, 0x0, + 0xa, 0x55, 0xc2, 0x32, 0xa1, 0xa0, 0x0, 0xb, + 0x0, 0xb0, 0x4, 0x91, 0xa0, 0x0, 0xb, 0x0, + 0xb0, 0x9, 0x41, 0xa0, 0x50, 0xb, 0x55, 0xc0, + 0x3a, 0x1, 0xa0, 0x70, 0x9, 0x0, 0x45, 0x80, + 0x0, 0xc9, 0xd2, 0x0, 0x0, 0x32, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AAD "読" */ + 0x0, 0x20, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x74, 0x0, 0x0, 0xc, 0x0, 0x0, 0x15, 0x78, + 0x94, 0x55, 0x5c, 0x56, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x4, 0x55, 0x91, 0x16, + 0x5a, 0x58, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x20, 0x4, 0x55, 0x81, 0xb5, 0x55, 0x55, + 0xe1, 0x0, 0x0, 0x13, 0x52, 0x80, 0x74, 0x10, + 0xb, 0x55, 0xd1, 0x3, 0xa0, 0xb0, 0x0, 0xb, + 0x0, 0xb0, 0x5, 0x80, 0xb0, 0x20, 0xb, 0x0, + 0xb0, 0xa, 0x30, 0xb0, 0x40, 0xb, 0x55, 0xc0, + 0x4a, 0x0, 0xb0, 0x70, 0x7, 0x0, 0x25, 0x80, + 0x0, 0xba, 0xd1, 0x0, 0x0, 0x32, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AB0 "誰" */ + 0x0, 0x10, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0x65, 0x0, 0x7, 0x59, 0x40, 0x0, 0x13, 0x3b, + 0x46, 0xb, 0x1, 0x71, 0x10, 0x3, 0x22, 0x22, + 0x3d, 0x59, 0x57, 0x60, 0x4, 0x55, 0x80, 0xab, + 0xa, 0x0, 0x0, 0x1, 0x0, 0x4, 0x5b, 0xa, + 0x5, 0x10, 0x4, 0x55, 0x93, 0xc, 0x4c, 0x54, + 0x20, 0x1, 0x0, 0x0, 0xb, 0xa, 0x0, 0x0, + 0x5, 0x44, 0x81, 0xb, 0xa, 0x4, 0x10, 0xb, + 0x11, 0xb1, 0xc, 0x5c, 0x55, 0x30, 0xb, 0x0, + 0xb0, 0xb, 0xa, 0x0, 0x0, 0xb, 0x55, 0xc0, + 0xb, 0xa, 0x2, 0x50, 0xb, 0x0, 0xa0, 0xd, + 0x55, 0x55, 0x50, 0x1, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+8AB2 "課" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x84, 0x0, 0xa5, 0x58, 0x5d, 0x20, 0x15, 0x89, + 0x84, 0xb0, 0xb, 0xb, 0x0, 0x1, 0x0, 0x0, + 0xb5, 0x5c, 0x5c, 0x0, 0x5, 0x55, 0x90, 0xb0, + 0xb, 0xb, 0x0, 0x0, 0x0, 0x0, 0xb5, 0x5c, + 0x5c, 0x0, 0x5, 0x55, 0x80, 0x40, 0xb, 0x3, + 0x0, 0x0, 0x0, 0x2, 0x55, 0x5c, 0x56, 0xc2, + 0xa, 0x55, 0xd1, 0x0, 0xec, 0x40, 0x0, 0xb, + 0x0, 0xb0, 0x8, 0x6b, 0x80, 0x0, 0xb, 0x0, + 0xb0, 0x3a, 0xb, 0x48, 0x0, 0xb, 0x55, 0xc2, + 0x90, 0xb, 0xa, 0xa2, 0x5, 0x0, 0x34, 0x0, + 0xc, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+8ABF "調" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0x0, 0x95, 0x56, 0x55, 0xd0, 0x14, 0x79, + 0x64, 0xb0, 0xb, 0x0, 0xb0, 0x2, 0x11, 0x11, + 0xb2, 0x5c, 0x74, 0xb0, 0x4, 0x54, 0x81, 0xb0, + 0xa, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb4, 0x5c, + 0x57, 0xb0, 0x5, 0x65, 0x91, 0xb1, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0xb2, 0xa5, 0xb3, 0xb0, + 0x9, 0x55, 0xb2, 0xb1, 0x80, 0x91, 0xb0, 0xb, + 0x0, 0xb0, 0xb2, 0xb5, 0xb1, 0xb0, 0xb, 0x0, + 0xb3, 0x71, 0x50, 0x50, 0xb0, 0xb, 0x55, 0xb8, + 0x10, 0x0, 0x32, 0xb0, 0x4, 0x0, 0x24, 0x0, + 0x0, 0x1b, 0x70, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AC7 "談" */ + 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x95, 0x0, 0x1, 0xa2, 0x5, 0x20, 0x15, 0x89, + 0x85, 0x17, 0xa1, 0x8a, 0x30, 0x1, 0x0, 0x0, + 0xc3, 0xb8, 0x30, 0x0, 0x5, 0x55, 0x90, 0x21, + 0xe5, 0x60, 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, + 0x3d, 0x20, 0x5, 0x55, 0x82, 0x72, 0x94, 0x3, + 0x30, 0x0, 0x0, 0x0, 0x2, 0xa3, 0x6, 0x0, + 0x9, 0x55, 0xb2, 0x55, 0xc6, 0x98, 0x20, 0xb, + 0x0, 0xb1, 0xb1, 0xc8, 0x0, 0x0, 0xb, 0x0, + 0xb0, 0x7, 0x67, 0x30, 0x0, 0xb, 0x55, 0xc0, + 0x1b, 0x1, 0xd2, 0x0, 0xb, 0x0, 0x83, 0x80, + 0x0, 0x4f, 0x91, 0x1, 0x0, 0x34, 0x0, 0x0, + 0x3, 0x30, + + /* U+8ACB "請" */ + 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x57, 0x0, 0x0, 0xc, 0x0, 0x0, 0x14, 0x4c, + 0x75, 0x55, 0x5c, 0x58, 0x80, 0x2, 0x11, 0x11, + 0x0, 0xb, 0x5, 0x0, 0x2, 0x44, 0x81, 0x16, + 0x5c, 0x55, 0x20, 0x1, 0x11, 0x12, 0x65, 0x5b, + 0x56, 0xa0, 0x2, 0x33, 0x71, 0x2, 0x0, 0x4, + 0x0, 0x1, 0x21, 0x10, 0xc, 0x55, 0x5c, 0x20, + 0x6, 0x55, 0x92, 0xc, 0x55, 0x5c, 0x0, 0xb, + 0x0, 0xb0, 0xb, 0x0, 0xb, 0x0, 0xb, 0x0, + 0xb0, 0xc, 0x55, 0x5c, 0x0, 0xb, 0x55, 0xc0, + 0xb, 0x0, 0xb, 0x0, 0x7, 0x0, 0x50, 0xa, + 0x4, 0xad, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x1, 0x0, + + /* U+8AD6 "論" */ + 0x0, 0x20, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x0, 0x6d, 0x0, 0x0, 0x15, 0x6b, + 0x67, 0x0, 0xd5, 0x20, 0x0, 0x1, 0x0, 0x0, + 0x8, 0x50, 0x90, 0x0, 0x3, 0x44, 0x80, 0x57, + 0x0, 0x5b, 0x10, 0x1, 0x21, 0x16, 0x56, 0x55, + 0x95, 0xd4, 0x3, 0x55, 0x90, 0x65, 0x55, 0x55, + 0x80, 0x1, 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0x90, + 0x6, 0x55, 0x90, 0xa0, 0xa0, 0xa0, 0x90, 0xa, + 0x0, 0xb0, 0xb5, 0xc5, 0xc5, 0x90, 0xa, 0x0, + 0xa0, 0xa0, 0xa0, 0xa0, 0x90, 0xa, 0x55, 0xb0, + 0xa0, 0xa0, 0x80, 0x90, 0xa, 0x0, 0xa0, 0xa0, + 0x0, 0x4b, 0x80, 0x1, 0x0, 0x0, 0x10, 0x0, + 0x2, 0x0, + + /* U+8AF8 "諸" */ + 0x0, 0x10, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x84, 0x0, 0x0, 0xb1, 0x2, 0x30, 0x14, 0x69, + 0x73, 0x0, 0xa0, 0x3a, 0x70, 0x2, 0x0, 0x0, + 0x45, 0xc5, 0x8a, 0x0, 0x5, 0x55, 0x90, 0x0, + 0xa0, 0xc1, 0x20, 0x0, 0x0, 0x3, 0x65, 0x8b, + 0x86, 0x90, 0x5, 0x55, 0x80, 0x0, 0x84, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1b, 0x85, 0x5b, 0x10, + 0x9, 0x55, 0xd4, 0x8a, 0x0, 0xb, 0x0, 0xb, + 0x0, 0xb2, 0x1c, 0x55, 0x5c, 0x0, 0xb, 0x0, + 0xb0, 0x1a, 0x0, 0xb, 0x0, 0xb, 0x44, 0xc0, + 0x1c, 0x55, 0x5c, 0x0, 0x7, 0x0, 0x50, 0x17, + 0x0, 0x8, 0x0, + + /* U+8B02 "謂" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x95, 0x57, 0x56, 0xb0, 0x25, 0x6b, + 0x78, 0xb0, 0xb, 0x1, 0x90, 0x0, 0x0, 0x0, + 0xb5, 0x5c, 0x56, 0x90, 0x5, 0x55, 0x92, 0xb0, + 0xb, 0x1, 0x90, 0x0, 0x0, 0x0, 0xb5, 0x57, + 0x56, 0x70, 0x5, 0x55, 0x81, 0x16, 0x55, 0x59, + 0x20, 0x0, 0x0, 0x0, 0x19, 0x0, 0xb, 0x0, + 0xa, 0x55, 0xc2, 0x1b, 0x55, 0x5c, 0x0, 0xb, + 0x0, 0xb0, 0x19, 0x0, 0xb, 0x0, 0xb, 0x0, + 0xb0, 0x1b, 0x44, 0x4c, 0x0, 0xb, 0x55, 0xc0, + 0x19, 0x0, 0xb, 0x0, 0x8, 0x0, 0x60, 0x29, + 0x1, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+8B1B "講" */ + 0x0, 0x10, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, + 0x85, 0x0, 0x9, 0x40, 0xb0, 0x10, 0x12, 0x4a, + 0x64, 0x6b, 0x65, 0xc5, 0x80, 0x14, 0x33, 0x31, + 0x9, 0x20, 0xa1, 0x20, 0x3, 0x44, 0x70, 0x6b, + 0x65, 0xc5, 0x40, 0x0, 0x0, 0x4, 0x57, 0x67, + 0x85, 0x82, 0x5, 0x55, 0x80, 0x55, 0x5d, 0x58, + 0x20, 0x0, 0x0, 0x0, 0x91, 0xa, 0xa, 0x0, + 0x9, 0x55, 0xb0, 0x95, 0x5c, 0x5c, 0x0, 0xa, + 0x0, 0xa0, 0x91, 0xa, 0xa, 0x10, 0xa, 0x0, + 0xa4, 0xb5, 0x59, 0x5c, 0x91, 0xb, 0x55, 0xa0, + 0x91, 0x0, 0xa, 0x0, 0x7, 0x0, 0x40, 0xa0, + 0x2, 0x8d, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x2, 0x0, + + /* U+8B1D "謝" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0xa, 0x0, 0xa, 0x10, 0x0, 0x57, + 0x43, 0x86, 0x80, 0xa, 0x0, 0x16, 0x55, 0x57, + 0x40, 0xa0, 0xa, 0x0, 0x4, 0x56, 0x75, 0x74, + 0xb4, 0x5c, 0x80, 0x1, 0x0, 0x5, 0x40, 0xa0, + 0xa, 0x0, 0x3, 0x55, 0x85, 0x75, 0xb6, 0x2a, + 0x0, 0x1, 0x0, 0x6, 0x41, 0xa0, 0xda, 0x0, + 0x7, 0x55, 0x95, 0x4c, 0xc0, 0x3a, 0x0, 0xa, + 0x0, 0xa0, 0x29, 0xa0, 0xa, 0x0, 0xa, 0x0, + 0xa0, 0x90, 0xa0, 0xa, 0x0, 0xa, 0x55, 0xa7, + 0x20, 0xa0, 0x1b, 0x0, 0x6, 0x0, 0x51, 0x1a, + 0xb1, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8B58 "識" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, + 0x70, 0x0, 0x83, 0x0, 0xb0, 0x0, 0x0, 0x84, + 0x25, 0x89, 0x83, 0xa6, 0x30, 0x16, 0x55, 0x35, + 0x10, 0xa1, 0xa0, 0xa0, 0x3, 0x48, 0x2, 0xa2, + 0x80, 0xa0, 0x0, 0x1, 0x0, 0x45, 0x79, 0x55, + 0xc5, 0xb0, 0x4, 0x59, 0x23, 0x0, 0x30, 0xa0, + 0x70, 0x1, 0x0, 0xb, 0x55, 0xc0, 0xa4, 0x90, + 0x8, 0x5a, 0x3a, 0x0, 0xa0, 0x9b, 0x20, 0xa, + 0x9, 0xa, 0x55, 0xa0, 0x6b, 0x0, 0xa, 0x9, + 0x1a, 0x0, 0xa0, 0xba, 0x4, 0xb, 0x5b, 0x1b, + 0x55, 0xa7, 0x48, 0xa3, 0x7, 0x6, 0x3, 0x0, + 0x64, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+8B70 "議" */ + 0x0, 0x10, 0x0, 0x3, 0x0, 0x52, 0x0, 0x0, + 0xa3, 0x0, 0x4, 0x90, 0xb2, 0x0, 0x25, 0x98, + 0x93, 0x65, 0x98, 0x68, 0x70, 0x1, 0x0, 0x0, + 0x1, 0x46, 0x15, 0x0, 0x5, 0x56, 0x60, 0x25, + 0x78, 0x44, 0x0, 0x0, 0x0, 0x2, 0x65, 0x78, + 0x56, 0xb0, 0x5, 0x56, 0x70, 0x3, 0x77, 0x25, + 0x0, 0x0, 0x0, 0x1, 0x6c, 0x39, 0x6, 0x30, + 0x9, 0x55, 0xc4, 0x5c, 0x5b, 0x65, 0xb2, 0xa, + 0x0, 0xa0, 0xa, 0x26, 0x46, 0x20, 0xa, 0x0, + 0xa5, 0x9d, 0x22, 0xc9, 0x0, 0xb, 0x55, 0xa3, + 0xa, 0x5, 0xd4, 0x21, 0x6, 0x0, 0x51, 0x7c, + 0x54, 0xa, 0xc1, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x31, + + /* U+8B77 "護" */ + 0x0, 0x20, 0x0, 0x3, 0x10, 0x40, 0x0, 0x0, + 0xa4, 0x0, 0x7, 0x40, 0xb0, 0x40, 0x25, 0x99, + 0x87, 0x5a, 0x95, 0xc5, 0x52, 0x1, 0x0, 0x0, + 0x66, 0x1b, 0x20, 0x10, 0x5, 0x55, 0x80, 0xd5, + 0x5c, 0x57, 0x80, 0x0, 0x0, 0x6, 0xd4, 0x4c, + 0x58, 0x20, 0x5, 0x55, 0x73, 0xa5, 0x5c, 0x58, + 0x20, 0x0, 0x0, 0x0, 0xa1, 0x1a, 0x11, 0x80, + 0xb, 0x55, 0xc0, 0x74, 0x44, 0x47, 0x41, 0xa, + 0x0, 0xa1, 0x68, 0x55, 0x8d, 0x0, 0xa, 0x0, + 0xa0, 0x3, 0x53, 0xa1, 0x0, 0xb, 0x55, 0xa0, + 0x1, 0xbc, 0x10, 0x0, 0x3, 0x0, 0x33, 0x55, + 0x1, 0x9a, 0x92, + + /* U+8B8A "變" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, + 0x85, 0x0, 0x44, 0x30, 0x2a, 0x0, 0x4, 0x77, + 0x36, 0x55, 0x82, 0x85, 0x70, 0x9, 0x8a, 0x14, + 0x66, 0x86, 0x9c, 0x30, 0x5, 0x96, 0x74, 0x33, + 0x51, 0x96, 0x80, 0x4, 0x86, 0x96, 0x75, 0xb0, + 0xa7, 0x82, 0x6, 0x44, 0x96, 0x75, 0x91, 0x57, + 0x71, 0x6, 0x15, 0x53, 0x10, 0x35, 0x15, 0x22, + 0x0, 0x3, 0xf6, 0x55, 0x56, 0x7a, 0x0, 0x0, + 0x2a, 0x33, 0x0, 0x49, 0x0, 0x0, 0x0, 0x40, + 0x4, 0x65, 0x90, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xbc, 0x40, 0x0, 0x0, 0x2, 0x46, 0x74, 0x0, + 0x5a, 0xbb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8B93 "讓" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, + 0x80, 0x0, 0x0, 0x57, 0x0, 0x20, 0x0, 0x75, + 0x34, 0x55, 0x57, 0x55, 0x91, 0x26, 0x55, 0x50, + 0x84, 0x95, 0x54, 0x80, 0x5, 0x55, 0x50, 0xb5, + 0xa6, 0x75, 0x90, 0x0, 0x0, 0x0, 0x34, 0x32, + 0x50, 0x20, 0x4, 0x57, 0x53, 0x6a, 0x65, 0xc6, + 0xa0, 0x0, 0x0, 0x0, 0x8, 0x10, 0x91, 0x40, + 0x8, 0x55, 0x90, 0x6a, 0x65, 0xb5, 0x60, 0x9, + 0x0, 0x95, 0x59, 0x96, 0x86, 0x92, 0x9, 0x0, + 0x90, 0x1c, 0x27, 0x38, 0x30, 0xa, 0x55, 0x93, + 0x8b, 0x3, 0xb3, 0x0, 0x5, 0x0, 0x23, 0xb, + 0x70, 0x9, 0xc2, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+8BA1 "计" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x46, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xb, + 0x40, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0x16, 0x5c, 0x16, 0x55, 0xc6, + 0x56, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb2, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x0, 0xb2, 0x0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, + 0xb, 0x3, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xb, + 0x82, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x1f, 0x60, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+8BDE "诞" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x20, 0x0, 0x40, 0x0, 0x2a, 0x80, 0x0, 0xd0, + 0x67, 0xd2, 0x68, 0xd3, 0x0, 0x0, 0x20, 0x7, + 0x50, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x50, 0xb0, 0x0, 0x26, 0xb2, 0x58, 0x30, 0xc0, + 0xc6, 0xa0, 0x0, 0xb0, 0x56, 0xc3, 0xa0, 0xb0, + 0x0, 0x0, 0xb0, 0x20, 0xb0, 0xa0, 0xb0, 0x0, + 0x0, 0xb0, 0x34, 0xb0, 0xa0, 0xb0, 0x10, 0x0, + 0xb0, 0x3c, 0x51, 0xc5, 0x85, 0x90, 0x0, 0xb9, + 0x1b, 0x90, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x81, + 0x2b, 0x96, 0x43, 0x20, 0x0, 0x16, 0x10, 0x0, + 0x37, 0xac, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8C50 "豐" */ + 0x0, 0x0, 0x30, 0x41, 0x2, 0x0, 0x0, 0x0, + 0xb0, 0x93, 0xa1, 0xb, 0x1a, 0x0, 0x0, 0xa4, + 0xc5, 0x93, 0x6b, 0x3a, 0x0, 0x0, 0xa4, 0xb7, + 0x93, 0x6c, 0x5a, 0x0, 0x0, 0xa3, 0xb7, 0x93, + 0x5b, 0x4a, 0x0, 0x1, 0xd5, 0xb5, 0xb5, 0x5b, + 0x5a, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x6, + 0x0, 0x2, 0x65, 0x55, 0x55, 0x55, 0x57, 0x30, + 0x0, 0x7, 0x55, 0x55, 0x55, 0xa0, 0x0, 0x0, + 0xa, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xa, + 0x65, 0x55, 0x56, 0xa0, 0x0, 0x0, 0x1, 0x47, + 0x0, 0x68, 0x0, 0x0, 0x5, 0x55, 0x5a, 0x55, + 0xa5, 0x57, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8C61 "象" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5d, 0x10, 0x13, 0x0, 0x0, 0x0, 0x4b, 0x55, + 0x5c, 0x80, 0x0, 0x0, 0x5d, 0x55, 0x58, 0x75, + 0x58, 0x0, 0x42, 0xb0, 0x3, 0xa0, 0x2, 0xa0, + 0x0, 0xd, 0x55, 0xa9, 0x55, 0x6a, 0x0, 0x0, + 0x70, 0x3d, 0x10, 0x2, 0x70, 0x0, 0x0, 0x67, + 0x3b, 0x6, 0x95, 0x0, 0x3, 0x62, 0x59, 0x79, + 0x60, 0x0, 0x0, 0x2, 0x85, 0x2b, 0xb3, 0x60, + 0x0, 0x4, 0x40, 0x59, 0xd, 0x9, 0x80, 0x0, + 0x3, 0x84, 0x2, 0xc0, 0x8, 0xe4, 0x35, 0x30, + 0x4b, 0xe4, 0x0, 0x1, 0x0, 0x0, 0x0, 0x12, + 0x0, 0x0, 0x0, + + /* U+8CA0 "負" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6c, 0x10, 0x21, 0x0, 0x0, 0x3, 0xc5, 0x55, + 0xd8, 0x0, 0x0, 0x3a, 0x10, 0x5, 0x60, 0x0, + 0x5, 0x75, 0x22, 0x38, 0x23, 0x70, 0x1, 0x2b, + 0x22, 0x22, 0x23, 0xb0, 0x0, 0x1c, 0x55, 0x55, + 0x56, 0xa0, 0x0, 0x1a, 0x0, 0x0, 0x1, 0xa0, + 0x0, 0x1c, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x2a, + 0x0, 0x0, 0x1, 0xa0, 0x0, 0x2a, 0x85, 0x55, + 0x76, 0x90, 0x0, 0x4, 0xd4, 0x0, 0x4a, 0x60, + 0x0, 0x77, 0x0, 0x0, 0x0, 0xb6, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x1, + + /* U+8CA1 "財" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x7, + 0x55, 0x59, 0x0, 0x0, 0xb2, 0x0, 0xb, 0x0, + 0xb, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xb, + 0x0, 0x0, 0xb0, 0x50, 0xb, 0x55, 0x5b, 0x35, + 0x59, 0xf5, 0x50, 0xb, 0x0, 0xb, 0x0, 0xc, + 0xc0, 0x0, 0xb, 0x55, 0x5b, 0x0, 0x49, 0xb0, + 0x0, 0xb, 0x0, 0xb, 0x0, 0xb1, 0xb0, 0x0, + 0xb, 0x0, 0xb, 0x7, 0x40, 0xb0, 0x0, 0xb, + 0x55, 0x5a, 0x36, 0x0, 0xb0, 0x0, 0x1, 0x82, + 0x52, 0x50, 0x0, 0xb0, 0x0, 0x4, 0x90, 0x1b, + 0x0, 0x0, 0xb0, 0x0, 0x28, 0x0, 0x8, 0x10, + 0x4a, 0xe0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, + 0x30, 0x0, + + /* U+8CA7 "貧" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x98, 0x0, 0x61, 0x0, 0x0, 0x0, 0x85, 0x0, + 0x0, 0x86, 0x0, 0x2, 0x73, 0x6a, 0x75, 0x5c, + 0x9d, 0x80, 0x0, 0x6, 0x80, 0x0, 0xc0, 0x0, + 0x0, 0x27, 0x40, 0x2, 0xa8, 0x0, 0x0, 0x12, + 0x95, 0x55, 0x56, 0x5c, 0x0, 0x0, 0xb, 0x55, + 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0xb, 0x55, 0x55, 0x55, 0xc0, + 0x0, 0x0, 0xb5, 0x55, 0x55, 0x5b, 0x0, 0x0, + 0x2, 0x5c, 0x0, 0x37, 0x82, 0x0, 0x4, 0x85, + 0x0, 0x0, 0x2, 0xc3, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8CA9 "販" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x55, 0x59, 0x1, 0x25, 0x9c, 0x70, 0xb, 0x0, + 0xb, 0xc, 0x31, 0x0, 0x0, 0xb, 0x11, 0x1b, + 0xa, 0x0, 0x0, 0x0, 0xb, 0x33, 0x3b, 0xc, + 0x55, 0x58, 0x10, 0xb, 0x0, 0xb, 0xa, 0x50, + 0xc, 0x0, 0xb, 0x55, 0x5b, 0x19, 0x60, 0x29, + 0x0, 0xb, 0x0, 0xb, 0x18, 0x43, 0x65, 0x0, + 0xb, 0x0, 0xb, 0x46, 0x8, 0xb0, 0x0, 0xb, + 0x55, 0x5b, 0x63, 0x9, 0x80, 0x0, 0x1, 0xb1, + 0x91, 0x80, 0x1b, 0xa0, 0x0, 0x6, 0x60, 0x57, + 0x60, 0x91, 0x5b, 0x10, 0x17, 0x0, 0x5, 0x25, + 0x0, 0x7, 0xa0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CAC "責" */ + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x7, 0x0, 0x6, 0x55, 0x56, + 0xb5, 0x56, 0x52, 0x0, 0x6, 0x55, 0x6b, 0x55, + 0x85, 0x0, 0x11, 0x11, 0x13, 0xa1, 0x11, 0x2a, + 0x4, 0x47, 0x44, 0x44, 0x44, 0x75, 0x41, 0x0, + 0xc5, 0x55, 0x55, 0x59, 0x60, 0x0, 0xc, 0x44, + 0x44, 0x44, 0x95, 0x0, 0x0, 0xc5, 0x55, 0x55, + 0x59, 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, 0x75, + 0x0, 0x0, 0xb5, 0x75, 0x55, 0x59, 0x40, 0x0, + 0x0, 0x8c, 0x10, 0x48, 0x82, 0x0, 0x5, 0x94, + 0x0, 0x0, 0x3, 0xd3, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+8CB7 "買" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, + 0x85, 0x58, 0x55, 0xc0, 0xc, 0x0, 0xb0, 0xb, + 0x1, 0xa0, 0xc, 0x0, 0xb0, 0xb, 0x1, 0xa0, + 0x9, 0x55, 0x55, 0x55, 0x55, 0x70, 0x0, 0x95, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xb5, 0x75, 0x55, + 0x59, 0x0, 0x0, 0x1b, 0x90, 0x3, 0x78, 0x20, + 0x6, 0x82, 0x0, 0x0, 0x3, 0xd0, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+8CB8 "貸" */ + 0x0, 0x0, 0x11, 0x1, 0x11, 0x0, 0x0, 0x0, + 0xc, 0x60, 0xc0, 0xa5, 0x0, 0x0, 0x1c, 0x40, + 0xa, 0x12, 0x39, 0x20, 0x48, 0x93, 0x55, 0x7a, + 0x43, 0x32, 0x11, 0x8, 0x20, 0x0, 0x86, 0x0, + 0x50, 0x0, 0x71, 0x0, 0x0, 0x7b, 0x78, 0x0, + 0xb, 0x55, 0x55, 0x55, 0xd5, 0x50, 0x0, 0xc5, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xc5, 0x55, 0x55, 0x5c, + 0x0, 0x0, 0xc, 0x55, 0x55, 0x55, 0xc0, 0x0, + 0x0, 0x19, 0xa0, 0x2, 0x78, 0x20, 0x0, 0x59, + 0x30, 0x0, 0x0, 0x4d, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8CBB "費" */ + 0x0, 0x0, 0x20, 0x2, 0x0, 0x0, 0x0, 0x0, + 0xa1, 0xc, 0x3, 0x0, 0x4, 0x55, 0xc5, 0x5c, + 0x5c, 0x20, 0x5, 0x95, 0xc5, 0x5c, 0x5a, 0x0, + 0x9, 0x95, 0xc5, 0x5c, 0x55, 0x69, 0x0, 0x8, + 0x20, 0xa, 0x3, 0x84, 0x14, 0x95, 0x44, 0x49, + 0x48, 0x60, 0x0, 0xb1, 0x11, 0x11, 0x1c, 0x0, + 0x0, 0xb5, 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb5, + 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb5, 0x55, 0x55, + 0x5b, 0x0, 0x0, 0x49, 0x50, 0x4, 0x78, 0x0, + 0x5, 0x94, 0x0, 0x0, 0x5, 0xd1, 0x21, 0x0, + 0x0, 0x0, 0x0, 0x20, + + /* U+8CBF "貿" */ + 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x5, 0x58, + 0x63, 0x55, 0x55, 0x93, 0xb, 0x1, 0x50, 0x1c, + 0x0, 0xb0, 0xb, 0x0, 0xa5, 0x29, 0x0, 0xc0, + 0xc, 0x87, 0x23, 0xa1, 0x58, 0x90, 0x5, 0x10, + 0x16, 0x10, 0x7, 0x10, 0x0, 0x95, 0x55, 0x55, + 0x5d, 0x10, 0x0, 0xb5, 0x55, 0x55, 0x5c, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xb5, + 0x55, 0x55, 0x5d, 0x0, 0x0, 0xb5, 0x65, 0x55, + 0x5c, 0x0, 0x0, 0x17, 0xc0, 0x2, 0x78, 0x10, + 0x4, 0x84, 0x0, 0x0, 0x4, 0xd0, 0x21, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+8CC3 "賃" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, + 0x23, 0x68, 0x9b, 0x70, 0x3, 0xc0, 0x11, 0x1b, + 0x0, 0x0, 0x37, 0xb3, 0x65, 0x5c, 0x55, 0x86, + 0x20, 0xb0, 0x0, 0xb, 0x0, 0x20, 0x0, 0x70, + 0x36, 0x57, 0x57, 0x70, 0x0, 0x95, 0x55, 0x55, + 0x5d, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x5b, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb5, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0xb5, 0x55, 0x55, + 0x5b, 0x0, 0x0, 0x16, 0xb0, 0x2, 0x67, 0x10, + 0x3, 0x95, 0x0, 0x0, 0x3, 0xd1, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+8CC7 "資" */ + 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x8, 0x50, + 0x1c, 0x10, 0x0, 0x10, 0x0, 0x46, 0x3a, 0x56, + 0x57, 0xb0, 0x0, 0x80, 0x90, 0x3d, 0x5, 0x0, + 0x3e, 0x12, 0x10, 0xb4, 0x70, 0x0, 0xc, 0x0, + 0x9, 0x50, 0x6a, 0x41, 0xa, 0x34, 0x72, 0x11, + 0x19, 0x94, 0x0, 0xc3, 0x33, 0x33, 0x3d, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc5, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc5, 0x55, 0x55, + 0x5c, 0x0, 0x0, 0x3a, 0x80, 0x2, 0x78, 0x0, + 0x5, 0x94, 0x0, 0x0, 0x5, 0xd0, 0x21, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+8CEA "質" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x7, + 0x58, 0xa2, 0x66, 0x8a, 0x30, 0x0, 0xb0, 0x2, + 0xc, 0x0, 0x3, 0x0, 0xc, 0x5b, 0x63, 0xd5, + 0x97, 0x60, 0x4, 0x70, 0xb0, 0x37, 0x8, 0x30, + 0x0, 0x90, 0xa, 0x19, 0x0, 0x83, 0x0, 0x40, + 0x55, 0x68, 0x55, 0x5a, 0x10, 0x0, 0x8, 0x40, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x87, 0x55, 0x55, + 0x5d, 0x0, 0x0, 0x8, 0x75, 0x55, 0x55, 0xd0, + 0x0, 0x0, 0x87, 0x55, 0x55, 0x5d, 0x0, 0x0, + 0x2, 0x3b, 0x10, 0x26, 0x60, 0x0, 0x1, 0x77, + 0x10, 0x0, 0x6, 0xd0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+8CFD "賽" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x39, 0x0, 0x1, 0x0, 0x0, 0xa5, + 0x59, 0x55, 0x85, 0x5b, 0x40, 0x1, 0x56, 0x5c, + 0x55, 0xc5, 0x85, 0x0, 0x0, 0x5, 0x5c, 0x55, + 0xc5, 0x71, 0x0, 0x1, 0x56, 0x5c, 0x55, 0xc5, + 0x59, 0x30, 0x0, 0x10, 0x95, 0x0, 0x25, 0x0, + 0x0, 0x0, 0x19, 0xd5, 0x55, 0x5d, 0xb3, 0x0, + 0x4, 0x50, 0xc5, 0x55, 0x5b, 0x2a, 0xc1, 0x0, + 0x0, 0xc3, 0x33, 0x3b, 0x10, 0x0, 0x0, 0x0, + 0xc1, 0x11, 0x1a, 0x10, 0x0, 0x0, 0x0, 0x9a, + 0x55, 0xa9, 0x0, 0x0, 0x0, 0x2, 0x96, 0x10, + 0x6, 0xc1, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, + 0x21, 0x0, + + /* U+8D39 "费" */ + 0x0, 0x0, 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x10, 0xd0, 0x1, 0x0, 0x6, 0x55, 0xc5, + 0x5c, 0x56, 0xc0, 0x0, 0x75, 0x5c, 0x55, 0xc5, + 0x69, 0x0, 0xc, 0x0, 0xb0, 0xb, 0x0, 0x34, + 0x1, 0x75, 0xa8, 0x55, 0xd5, 0x57, 0xc0, 0x0, + 0x66, 0x0, 0xb, 0x4, 0xc3, 0x3, 0x59, 0x55, + 0x55, 0x55, 0xb2, 0x0, 0x0, 0xc0, 0x6, 0x50, + 0x1a, 0x0, 0x0, 0xc, 0x0, 0x92, 0x1, 0xb0, + 0x0, 0x0, 0xb0, 0xb, 0x21, 0x17, 0x0, 0x0, + 0x0, 0xa, 0x30, 0x5b, 0x81, 0x0, 0x2, 0x67, + 0x10, 0x0, 0x9, 0xa0, 0x3, 0x20, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+8D64 "赤" */ + 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x65, 0x0, 0x52, 0x0, 0x0, 0x16, 0x55, + 0x99, 0x55, 0x53, 0x0, 0x0, 0x0, 0x0, 0x65, + 0x0, 0x0, 0x0, 0x4, 0x55, 0x55, 0x99, 0x55, + 0x56, 0xc1, 0x0, 0x1, 0xa, 0x20, 0xc0, 0x0, + 0x0, 0x0, 0xd, 0x3b, 0x0, 0xc1, 0x60, 0x0, + 0x0, 0x57, 0xc, 0x0, 0xc0, 0x2b, 0x10, 0x1, + 0x70, 0x39, 0x0, 0xc0, 0x7, 0xa0, 0x5, 0x0, + 0x92, 0x0, 0xc0, 0x0, 0x60, 0x0, 0x6, 0x50, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x63, 0x0, 0x5b, + 0xe0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x20, + 0x0, 0x0, + + /* U+8D70 "走" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0x1, 0x70, 0x0, 0x0, 0x45, 0x55, + 0xc6, 0x55, 0x50, 0x0, 0x0, 0x0, 0x0, 0xa1, + 0x0, 0x0, 0x0, 0x16, 0x55, 0x55, 0xb6, 0x55, + 0x5c, 0x50, 0x0, 0x1, 0x0, 0xa3, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x30, 0xa1, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0xa6, 0x55, 0xc4, 0x0, 0x0, + 0x4b, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x92, + 0x81, 0xa1, 0x0, 0x0, 0x0, 0x2, 0x90, 0xa, + 0xe6, 0x31, 0x11, 0x20, 0x8, 0x0, 0x0, 0x48, + 0xbd, 0xff, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8D77 "起" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0x60, 0x65, 0x5b, 0x10, 0x2, 0x65, 0xc5, + 0x50, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0xb, 0x0, 0x6, 0x55, 0xc5, 0xa5, 0x95, + 0x5c, 0x0, 0x0, 0x0, 0xb2, 0x0, 0xb0, 0x4, + 0x0, 0x0, 0xc0, 0xb0, 0x0, 0xb0, 0x0, 0x10, + 0x0, 0xc0, 0xb5, 0xb2, 0xb0, 0x0, 0x50, 0x3, + 0xa0, 0xb0, 0x0, 0xb0, 0x0, 0xa0, 0x6, 0x75, + 0xb0, 0x0, 0x89, 0x9a, 0x90, 0x8, 0x3, 0xc7, + 0x42, 0x0, 0x0, 0x10, 0x23, 0x0, 0x3, 0x8b, + 0xde, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8D85 "超" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x2, 0x22, 0x23, 0x40, 0x0, 0xa, + 0x4, 0x4, 0xc5, 0x38, 0x60, 0x4, 0x5c, 0x56, + 0x10, 0xd0, 0x8, 0x40, 0x0, 0xa, 0x0, 0x2, + 0xa0, 0xa, 0x20, 0x5, 0x5c, 0x5a, 0x3a, 0x11, + 0x9d, 0x0, 0x1, 0x8, 0x20, 0x63, 0x0, 0x3, + 0x0, 0x3, 0x78, 0x20, 0xc, 0x55, 0x5d, 0x30, + 0x5, 0x68, 0x68, 0x5c, 0x0, 0xb, 0x0, 0x6, + 0x48, 0x20, 0xc, 0x0, 0xb, 0x0, 0x8, 0x5a, + 0x20, 0xc, 0x55, 0x5d, 0x0, 0x8, 0x6, 0x84, + 0x15, 0x0, 0x1, 0x0, 0x31, 0x0, 0x5, 0x9b, + 0xcd, 0xde, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8D8A "越" */ + 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x0, 0xd, 0x33, 0x0, 0x1, 0x1b, + 0x17, 0x10, 0xb, 0xc, 0x0, 0x4, 0x3c, 0x33, + 0x17, 0x5d, 0x58, 0xa0, 0x0, 0xb, 0x0, 0xb, + 0xb, 0x0, 0x0, 0x36, 0x5b, 0x58, 0x6b, 0xb, + 0xa, 0x30, 0x1, 0x7, 0x40, 0xb, 0xa, 0x1c, + 0x0, 0x4, 0xa7, 0x31, 0x1b, 0x7, 0xb4, 0x0, + 0x6, 0x67, 0x76, 0x4c, 0x64, 0xd0, 0x50, 0x8, + 0x47, 0x30, 0x1c, 0x1a, 0x96, 0x80, 0xa, 0x6a, + 0x30, 0x1, 0x81, 0x9, 0xc0, 0x8, 0x7, 0xa4, + 0x14, 0x0, 0x0, 0x30, 0x41, 0x0, 0x17, 0xbc, + 0xcc, 0xdd, 0xa1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x0, + + /* U+8DA3 "趣" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xa, + 0x16, 0xa5, 0xa7, 0x20, 0x0, 0x4, 0x5c, 0x73, + 0xa0, 0xa2, 0x65, 0xb0, 0x0, 0xa, 0x0, 0xa5, + 0xc0, 0x2, 0x80, 0x15, 0x5c, 0x5a, 0xa0, 0xa1, + 0x45, 0x50, 0x1, 0x9, 0x10, 0xa0, 0xa0, 0x5b, + 0x10, 0x5, 0x4a, 0x0, 0xa5, 0xc0, 0xd, 0x0, + 0x8, 0x4a, 0x67, 0xa0, 0xa3, 0x68, 0x70, 0x9, + 0x1a, 0x4, 0xc7, 0xc2, 0x60, 0xb0, 0x9, 0x6b, + 0x3, 0x10, 0xa3, 0x0, 0x10, 0x7, 0x9, 0x72, + 0x0, 0x60, 0x0, 0x0, 0x31, 0x0, 0x27, 0xbc, + 0xcd, 0xde, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8DB3 "足" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x9, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xa, + 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x0, 0xa0, 0x0, 0x0, 0xa, 0x0, 0x0, + 0x0, 0xa0, 0x0, 0x0, 0xa, 0x55, 0xc5, 0x55, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x10, 0xc0, 0x0, 0x34, 0x0, + 0x0, 0x2d, 0x0, 0xc5, 0x55, 0x55, 0x0, 0x0, + 0x7a, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc1, + 0x70, 0xc0, 0x0, 0x0, 0x0, 0x5, 0x40, 0x19, + 0xe3, 0x21, 0x1, 0x21, 0x16, 0x0, 0x0, 0x49, + 0xce, 0xef, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8DDF "跟" */ + 0x4, 0x55, 0x59, 0x7, 0x55, 0x59, 0x0, 0x7, + 0x40, 0xb, 0xb, 0x0, 0xc, 0x0, 0x7, 0x40, + 0xa, 0xb, 0x0, 0xb, 0x0, 0x7, 0x40, 0xa, + 0xd, 0x55, 0x5b, 0x0, 0x7, 0x7b, 0x57, 0xb, + 0x0, 0xb, 0x0, 0x1, 0xa, 0x0, 0xc, 0x65, + 0x5b, 0x0, 0xa, 0x2b, 0x59, 0x1b, 0x41, 0x6, + 0x40, 0xa, 0xa, 0x0, 0xb, 0x16, 0x59, 0x20, + 0xa, 0xa, 0x0, 0xb, 0x9, 0x40, 0x0, 0xa, + 0xb, 0x55, 0x1b, 0x3, 0xb1, 0x0, 0x4d, 0xb7, + 0x10, 0xd, 0x80, 0x3d, 0x91, 0x35, 0x0, 0x0, + 0x8, 0x0, 0x1, 0x30, + + /* U+8DEF "路" */ + 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x3, + 0x22, 0x25, 0x6, 0xa0, 0x0, 0x0, 0x8, 0x53, + 0x4a, 0xa, 0x65, 0x5c, 0x0, 0x8, 0x20, 0x19, + 0x1b, 0x0, 0x66, 0x0, 0x9, 0x20, 0x19, 0x61, + 0x71, 0xa0, 0x0, 0x8, 0x6b, 0x66, 0x50, 0x4e, + 0x20, 0x0, 0x0, 0xa, 0x0, 0x0, 0xa9, 0xb2, + 0x0, 0xa, 0x2b, 0x68, 0x9, 0x30, 0x3d, 0xb1, + 0xa, 0xa, 0x3, 0x6c, 0x55, 0x5c, 0x20, 0xa, + 0xa, 0x0, 0xb, 0x0, 0xb, 0x0, 0xa, 0xc, + 0x64, 0xb, 0x0, 0xb, 0x0, 0x3d, 0x94, 0x0, + 0xc, 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8EAB "身" */ + 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0xa, 0x58, + 0x55, 0x5d, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0xd, 0x55, 0x55, 0x5c, 0x3, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc5, 0xc0, 0x0, + 0xd, 0x55, 0x55, 0x5e, 0xb0, 0x0, 0x0, 0xc0, + 0x0, 0x4, 0xe1, 0x0, 0x36, 0x57, 0x55, 0x58, + 0xbc, 0x0, 0x0, 0x0, 0x0, 0x6, 0x90, 0xc0, + 0x0, 0x0, 0x0, 0x19, 0x50, 0xc, 0x0, 0x0, + 0x0, 0x67, 0x10, 0x0, 0xc0, 0x0, 0x24, 0x50, + 0x0, 0x5, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, + + /* U+8ECA "車" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x2, + 0x65, 0x55, 0x5c, 0x55, 0x56, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0xa0, 0x0, 0x20, 0x0, 0x0, 0x1b, + 0x55, 0x5c, 0x55, 0x5e, 0x10, 0x0, 0x1, 0x90, + 0x0, 0xa0, 0x0, 0xb0, 0x0, 0x0, 0x1b, 0x55, + 0x5c, 0x55, 0x5b, 0x0, 0x0, 0x1, 0x90, 0x0, + 0xa0, 0x0, 0xb0, 0x0, 0x0, 0x1b, 0x55, 0x5c, + 0x55, 0x5c, 0x0, 0x0, 0x0, 0x10, 0x0, 0xa0, + 0x0, 0x2, 0x20, 0x6, 0x55, 0x55, 0x5c, 0x55, + 0x55, 0x88, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, + + /* U+8EDF "軟" */ + 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x0, 0xc3, 0x0, 0x0, 0x6, 0x5c, + 0x59, 0x50, 0xb0, 0x0, 0x0, 0x0, 0xa, 0x0, + 0x5, 0x95, 0x57, 0x90, 0xa, 0x5c, 0x5c, 0x29, + 0x45, 0x7, 0x30, 0xb, 0xa, 0xa, 0x33, 0x48, + 0x2, 0x0, 0xb, 0x5c, 0x5b, 0x10, 0x5a, 0x0, + 0x0, 0xb, 0xa, 0xa, 0x0, 0x7a, 0x0, 0x0, + 0xb, 0x5c, 0x5b, 0x0, 0xa6, 0x20, 0x0, 0x2, + 0xa, 0x1, 0x41, 0xb1, 0x90, 0x0, 0x36, 0x5c, + 0x55, 0x58, 0x30, 0xa3, 0x0, 0x0, 0xa, 0x0, + 0x55, 0x0, 0x2d, 0x30, 0x0, 0xb, 0x4, 0x40, + 0x0, 0x4, 0xa1, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8EE2 "転" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x6, 0x5c, + 0x5a, 0x45, 0x65, 0x5b, 0x10, 0x0, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x5c, 0x5c, 0x10, + 0x0, 0x0, 0x0, 0xb, 0xa, 0xa, 0x0, 0x0, + 0x0, 0x40, 0xb, 0x5c, 0x5b, 0x46, 0x59, 0x56, + 0x70, 0xb, 0xa, 0xa, 0x0, 0x4a, 0x0, 0x0, + 0xb, 0x5c, 0x5b, 0x0, 0xa1, 0x0, 0x0, 0x2, + 0xa, 0x4, 0x12, 0x70, 0x31, 0x0, 0x36, 0x5c, + 0x55, 0x38, 0x0, 0xa, 0x20, 0x0, 0xa, 0x0, + 0x7b, 0x97, 0x67, 0xa0, 0x0, 0xb, 0x0, 0x23, + 0x0, 0x0, 0x50, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8EFD "軽" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x36, 0x55, 0x5b, 0x40, 0x6, 0x5c, + 0x5a, 0x24, 0x0, 0x2a, 0x0, 0x0, 0xa, 0x0, + 0x0, 0x70, 0xa1, 0x0, 0xa, 0x5c, 0x5d, 0x10, + 0x5b, 0x30, 0x0, 0xb, 0xa, 0xa, 0x0, 0x89, + 0x91, 0x0, 0xb, 0x5c, 0x5b, 0x27, 0x22, 0x4d, + 0xa1, 0xb, 0xa, 0xb, 0x30, 0xd, 0x10, 0x10, + 0xb, 0x5c, 0x5b, 0x0, 0xb, 0x5, 0x20, 0x3, + 0xa, 0x2, 0x46, 0x5c, 0x55, 0x30, 0x26, 0x5c, + 0x55, 0x40, 0xb, 0x0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0xb, 0x0, 0x30, 0x0, 0xb, 0x1, 0x65, + 0x57, 0x56, 0x81, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8F03 "較" */ + 0x0, 0x4, 0x10, 0x0, 0x11, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x0, 0xb, 0x30, 0x0, 0x6, 0x5c, + 0x5b, 0x20, 0x3, 0x20, 0x30, 0x0, 0xa, 0x0, + 0x26, 0x75, 0x56, 0x70, 0xa, 0x5c, 0x5c, 0x20, + 0xc3, 0x26, 0x0, 0xb, 0xa, 0xa, 0x6, 0x50, + 0x3, 0xc0, 0xb, 0x5c, 0x5b, 0x37, 0x20, 0x26, + 0x62, 0xb, 0xa, 0xa, 0x40, 0x60, 0x69, 0x0, + 0xb, 0x5c, 0x5b, 0x0, 0x71, 0xb1, 0x0, 0x2, + 0xa, 0x3, 0x20, 0x1c, 0x80, 0x0, 0x26, 0x5c, + 0x56, 0x40, 0x2c, 0x80, 0x0, 0x0, 0xa, 0x0, + 0x4, 0x80, 0x8b, 0x30, 0x0, 0xb, 0x1, 0x64, + 0x0, 0x5, 0xa2, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8F09 "載" */ + 0x0, 0x0, 0x41, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0x51, 0xd, 0x73, 0x0, 0x0, 0x65, + 0xc5, 0x53, 0xb, 0x19, 0x0, 0x6, 0x55, 0xb5, + 0x55, 0x5c, 0x55, 0xb3, 0x0, 0x0, 0x92, 0x21, + 0xb, 0x0, 0x0, 0x2, 0x65, 0xc5, 0x66, 0xb, + 0x2, 0x30, 0x0, 0x95, 0xc5, 0xa5, 0xb, 0x7, + 0x70, 0x0, 0xb0, 0xa0, 0x91, 0xb, 0xb, 0x0, + 0x0, 0xc5, 0xc5, 0xb1, 0x9, 0x68, 0x0, 0x0, + 0xd5, 0xc5, 0xb1, 0x5, 0xe1, 0x0, 0x0, 0x20, + 0xa0, 0x26, 0x9, 0xd0, 0x3, 0x5, 0x55, 0xc5, + 0x55, 0xa6, 0x59, 0x15, 0x0, 0x0, 0xa0, 0x38, + 0x20, 0x7, 0xd5, 0x0, 0x0, 0x40, 0x20, 0x0, + 0x0, 0x34, + + /* U+8F15 "輕" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x12, 0x22, 0x25, 0x60, 0x16, 0x5c, + 0x5a, 0x36, 0x45, 0x45, 0x40, 0x0, 0xa, 0x0, + 0x9, 0x3a, 0x3a, 0x30, 0xa, 0x5c, 0x5c, 0x37, + 0x34, 0x25, 0x0, 0xb, 0xa, 0xa, 0x35, 0x36, + 0x18, 0x0, 0xb, 0x5c, 0x5b, 0xa, 0x3a, 0x37, + 0x60, 0xb, 0xa, 0xa, 0x3, 0x43, 0x12, 0x20, + 0xb, 0x5c, 0x5b, 0x6, 0x58, 0x59, 0x50, 0x3, + 0xa, 0x1, 0x30, 0xb, 0x0, 0x0, 0x36, 0x5c, + 0x55, 0x50, 0xb, 0x0, 0x0, 0x0, 0xa, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, 0x55, + 0x5c, 0x55, 0xd2, 0x0, 0x8, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+8F2A "輪" */ + 0x0, 0x5, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x6, 0x5c, + 0x5a, 0x0, 0x95, 0x50, 0x0, 0x0, 0xa, 0x0, + 0x2, 0xa0, 0x84, 0x0, 0xb, 0x5c, 0x5d, 0x19, + 0x0, 0x3d, 0xa2, 0xb, 0xa, 0xb, 0x62, 0x65, + 0x53, 0x40, 0xb, 0x4c, 0x4a, 0x45, 0x55, 0x55, + 0x80, 0xb, 0xa, 0xa, 0x64, 0x90, 0x90, 0xa0, + 0xb, 0x5c, 0x5a, 0x64, 0x90, 0x90, 0xa0, 0x2, + 0xa, 0x5, 0x68, 0xb5, 0xb5, 0xa0, 0x26, 0x5c, + 0x55, 0x74, 0x90, 0x90, 0xa0, 0x0, 0xa, 0x0, + 0x64, 0x90, 0x90, 0xa0, 0x0, 0xb, 0x0, 0x64, + 0x60, 0x67, 0x90, 0x0, 0x4, 0x0, 0x10, 0x0, + 0x1, 0x0, + + /* U+8F38 "輸" */ + 0x0, 0x1, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0xc, 0x10, 0x0, 0x6c, 0x0, 0x0, 0x6, 0x5c, + 0x5a, 0x0, 0xd4, 0x40, 0x0, 0x0, 0xa, 0x0, + 0x6, 0x80, 0x84, 0x0, 0x9, 0x5c, 0x5c, 0x39, + 0x65, 0x8c, 0xa2, 0xb, 0xa, 0xb, 0x60, 0x1, + 0x4, 0x50, 0xb, 0x5c, 0x5a, 0x68, 0x69, 0x39, + 0x20, 0xb, 0xa, 0xa, 0x65, 0x29, 0xa8, 0x10, + 0xc, 0x5c, 0x5a, 0x68, 0x59, 0x98, 0x10, 0x2, + 0xa, 0x6, 0x67, 0x49, 0x98, 0x10, 0x26, 0x5c, + 0x55, 0x76, 0x39, 0xa8, 0x10, 0x0, 0xa, 0x0, + 0x65, 0x18, 0x18, 0x10, 0x0, 0xc, 0x0, 0x66, + 0xa7, 0x6d, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8F9B "辛" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x71, 0x0, 0x6, 0x57, 0x55, 0x58, + 0x65, 0x30, 0x0, 0x0, 0x75, 0x0, 0xa6, 0x0, + 0x0, 0x0, 0x2, 0xd0, 0x9, 0x0, 0x0, 0x6, + 0x55, 0x57, 0x68, 0x65, 0x5c, 0x60, 0x0, 0x0, + 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x0, 0x30, 0x0, 0x6, 0x55, 0x5c, 0x75, 0x5b, + 0x30, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+8F9E "辞" */ + 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, + 0x0, 0x6c, 0x0, 0x1b, 0x0, 0x0, 0x3, 0x6a, + 0x93, 0x36, 0x57, 0x56, 0x90, 0x0, 0x4, 0x70, + 0x2, 0x0, 0x15, 0x0, 0x0, 0x4, 0x72, 0x46, + 0x50, 0x5b, 0x0, 0x5, 0x57, 0x95, 0x41, 0xa0, + 0x91, 0x0, 0x0, 0x4, 0x70, 0x45, 0x45, 0x84, + 0x92, 0x1, 0x77, 0x98, 0x20, 0xb, 0x0, 0x0, + 0x1, 0xb0, 0xb, 0x0, 0xb, 0x0, 0x0, 0x1, + 0xb0, 0xb, 0x26, 0x5c, 0x57, 0x70, 0x1, 0xb0, + 0xb, 0x0, 0xb, 0x0, 0x0, 0x1, 0xc5, 0x5c, + 0x0, 0xb, 0x0, 0x0, 0x1, 0x80, 0x3, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+8FA6 "辦" */ + 0x0, 0x0, 0x0, 0x10, 0x2, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0xc0, 0x1, 0xc0, 0x0, 0x3, 0x97, + 0x40, 0xa0, 0x13, 0x75, 0x40, 0x4, 0x26, 0x35, + 0xc9, 0x53, 0x25, 0x20, 0x7, 0x2a, 0x20, 0xa7, + 0x29, 0xb, 0x20, 0x3, 0x57, 0x11, 0x97, 0x17, + 0x37, 0x0, 0x36, 0xa6, 0x83, 0x78, 0x55, 0x96, + 0xa0, 0x0, 0xa0, 0x5, 0x49, 0x0, 0xa0, 0x0, + 0x3, 0xb6, 0x49, 0xa, 0x0, 0xa1, 0x20, 0x3, + 0xa1, 0x29, 0xa, 0x26, 0xc6, 0x50, 0x0, 0x90, + 0x81, 0xa, 0x0, 0xa0, 0x0, 0x6, 0x34, 0x43, + 0xb7, 0x0, 0xa0, 0x0, 0x25, 0x24, 0x0, 0x20, + 0x0, 0xb0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x30, 0x0, + + /* U+8FB2 "農" */ + 0x0, 0x0, 0x16, 0x0, 0x60, 0x0, 0x0, 0x5, + 0x56, 0xc5, 0x5d, 0x58, 0x20, 0x0, 0x92, 0x1a, + 0x0, 0xb0, 0xa1, 0x0, 0x9, 0x66, 0xc5, 0x5c, + 0x5c, 0x0, 0x0, 0x92, 0x1a, 0x0, 0xb0, 0xa1, + 0x0, 0x7, 0x55, 0x65, 0x56, 0x59, 0x10, 0x0, + 0x85, 0x55, 0x55, 0x55, 0x87, 0x0, 0x9, 0x33, + 0x33, 0x33, 0x62, 0x0, 0x0, 0x93, 0x21, 0x11, + 0x11, 0x15, 0x0, 0xb, 0x5b, 0x57, 0x65, 0x58, + 0x61, 0x0, 0xb0, 0xa0, 0x7, 0x18, 0x70, 0x0, + 0x55, 0xa, 0x1, 0x3a, 0xa0, 0x0, 0x17, 0x0, + 0xda, 0x60, 0x6, 0xdb, 0x52, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x30, + + /* U+8FBA "辺" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1e, + 0x6, 0x57, 0x75, 0x5c, 0x60, 0x0, 0x0, 0x0, + 0x8, 0x30, 0xa, 0x10, 0x0, 0x6, 0x0, 0xa, + 0x10, 0xa, 0x0, 0x6, 0x5d, 0x0, 0xc, 0x0, + 0xb, 0x0, 0x0, 0xa, 0x0, 0x1a, 0x0, 0xb, + 0x0, 0x0, 0xa, 0x0, 0x74, 0x0, 0xc, 0x0, + 0x0, 0xa, 0x0, 0xa0, 0x0, 0xb, 0x0, 0x0, + 0xa, 0x7, 0x20, 0x0, 0x58, 0x0, 0x0, 0x7c, + 0x32, 0x0, 0x19, 0xe2, 0x0, 0x1d, 0x51, 0xa4, + 0x0, 0x0, 0x10, 0x0, 0x2, 0x0, 0x6, 0xbc, + 0xdd, 0xde, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FBC "込" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x3d, + 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x0, 0x60, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x6, 0x5e, 0x10, 0x5, 0x94, + 0x0, 0x0, 0x0, 0xb, 0x0, 0xb, 0x9, 0x0, + 0x0, 0x0, 0xb, 0x0, 0x55, 0x7, 0x30, 0x0, + 0x0, 0xb, 0x1, 0x80, 0x0, 0xc1, 0x0, 0x0, + 0xb, 0x17, 0x0, 0x0, 0x5c, 0x20, 0x0, 0x6c, + 0x40, 0x0, 0x0, 0x8, 0xb1, 0xc, 0x61, 0x94, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x5, 0xbc, + 0xcc, 0xdd, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FCE "迎" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x70, 0x0, 0x7, 0xb1, 0x0, 0x0, 0x0, 0x78, + 0xa, 0x41, 0x8, 0x55, 0xa0, 0x0, 0x13, 0xb, + 0x0, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, + 0xb, 0x0, 0xb0, 0x6, 0x6c, 0xb, 0x0, 0xb, + 0x0, 0xb0, 0x0, 0xa, 0xb, 0x0, 0xb, 0x0, + 0xb0, 0x0, 0xa, 0xb, 0x4, 0x2b, 0x0, 0xb0, + 0x0, 0xa, 0xc, 0xb3, 0xb, 0x26, 0xa0, 0x0, + 0xa, 0x5, 0x10, 0xb, 0x5, 0x30, 0x1, 0x89, + 0x20, 0x0, 0xb, 0x0, 0x0, 0x1d, 0x20, 0x68, + 0x42, 0x14, 0x11, 0x23, 0x0, 0x0, 0x1, 0x69, + 0xbc, 0xcd, 0xc1, + + /* U+8FD1 "近" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x70, 0x0, 0x10, 0x14, 0x8d, 0x20, 0x0, 0x59, + 0x0, 0xb5, 0x53, 0x10, 0x0, 0x0, 0x2, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xb0, + 0x0, 0x0, 0x40, 0x7, 0x6d, 0x0, 0xb5, 0x55, + 0xb5, 0x62, 0x0, 0xa, 0x0, 0xb0, 0x0, 0xb0, + 0x0, 0x0, 0xa, 0x0, 0xa0, 0x0, 0xb0, 0x0, + 0x0, 0xa, 0x4, 0x60, 0x0, 0xb0, 0x0, 0x0, + 0xa, 0x8, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x3b, + 0x21, 0x0, 0x0, 0xc0, 0x0, 0x6, 0x80, 0x74, + 0x0, 0x0, 0x40, 0x0, 0x9, 0x0, 0x5, 0xbc, + 0xdd, 0xdd, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FD4 "返" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x62, 0x1, 0x1, 0x37, 0xca, 0x0, 0x0, 0x1d, + 0x3, 0xb4, 0x31, 0x0, 0x0, 0x0, 0x5, 0x3, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb5, + 0x55, 0x69, 0x0, 0x7, 0x5c, 0x4, 0x80, 0x0, + 0x67, 0x0, 0x0, 0xb, 0x5, 0x74, 0x0, 0xc0, + 0x0, 0x0, 0xb, 0x6, 0x30, 0x89, 0x60, 0x0, + 0x0, 0xb, 0x9, 0x0, 0x2c, 0xb1, 0x0, 0x0, + 0xb, 0x26, 0x2, 0xa1, 0x3d, 0x10, 0x0, 0xb, + 0x40, 0x47, 0x0, 0x5, 0x30, 0x4, 0x83, 0x75, + 0x10, 0x0, 0x0, 0x0, 0x9, 0x0, 0x6, 0xbc, + 0xdd, 0xde, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FEB "迫" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x40, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x2b, 0x0, + 0xa7, 0x65, 0x5d, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0x1b, 0x0, 0x5, 0x5a, 0x0, 0xc0, 0x0, + 0x1b, 0x0, 0x1, 0xc, 0x0, 0xd5, 0x55, 0x5b, + 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x1b, 0x0, + 0x0, 0xc, 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x0, + 0xc, 0x0, 0xd5, 0x55, 0x5b, 0x0, 0x0, 0x7d, + 0x10, 0xc0, 0x0, 0x9, 0x0, 0xc, 0x60, 0x86, + 0x31, 0x0, 0x1, 0x22, 0x3, 0x0, 0x3, 0x8b, + 0xcd, 0xee, 0xc1, + + /* U+8FFD "追" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x60, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x79, + 0x0, 0x75, 0x95, 0x59, 0x0, 0x0, 0x17, 0x0, + 0xb0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x1a, 0x0, 0x6, 0x5b, 0x0, 0xc5, 0x55, + 0x6a, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x0, 0xc5, 0x55, 0x5b, 0x50, + 0x0, 0xb, 0x0, 0xb0, 0x0, 0x9, 0x20, 0x0, + 0xb, 0x0, 0xb0, 0x0, 0x9, 0x20, 0x0, 0x6c, + 0x10, 0xd5, 0x55, 0x5b, 0x20, 0xb, 0x60, 0x85, + 0x40, 0x0, 0x1, 0x0, 0x4, 0x0, 0x5, 0xac, + 0xcc, 0xdd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x10, + + /* U+9000 "退" */ + 0x0, 0x60, 0x0, 0x20, 0x0, 0x5, 0x0, 0x0, + 0x6a, 0x0, 0xd5, 0x55, 0x5d, 0x0, 0x0, 0x6, + 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, + 0xd5, 0x55, 0x5c, 0x0, 0x5, 0x5b, 0x0, 0xc0, + 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, 0xd5, 0x55, + 0x58, 0x30, 0x0, 0xc, 0x0, 0xc1, 0x40, 0x2a, + 0x40, 0x0, 0xc, 0x0, 0xc0, 0x18, 0xa0, 0x0, + 0x0, 0xc, 0x0, 0xc2, 0x62, 0x5d, 0x30, 0x0, + 0x6b, 0x21, 0xf7, 0x0, 0x4, 0x80, 0xc, 0x40, + 0x67, 0x50, 0x0, 0x0, 0x12, 0x1, 0x0, 0x3, + 0x9b, 0xde, 0xef, 0xe2, + + /* U+9001 "送" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x70, 0x0, 0x81, 0x1, 0xd0, 0x0, 0x0, 0x88, + 0x0, 0x4a, 0x7, 0x30, 0x0, 0x0, 0x13, 0x3, + 0x57, 0x59, 0x5b, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x7, 0x6b, 0x0, 0x0, 0xc0, + 0x0, 0x40, 0x0, 0x19, 0x26, 0x55, 0xd5, 0x56, + 0x80, 0x0, 0x19, 0x0, 0x2, 0xb0, 0x0, 0x0, + 0x0, 0x19, 0x0, 0x9, 0x69, 0x40, 0x0, 0x0, + 0x19, 0x0, 0x48, 0x0, 0xa9, 0x0, 0x0, 0x5c, + 0x4, 0x60, 0x0, 0xc, 0x0, 0xa, 0x61, 0xa6, + 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x7, 0xbb, + 0xcc, 0xde, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9003 "逃" */ + 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, + 0x60, 0x0, 0xb, 0x2c, 0x20, 0x0, 0x0, 0x59, + 0x11, 0xb, 0xb, 0x5, 0x40, 0x0, 0x6, 0xb, + 0xb, 0xb, 0x39, 0x10, 0x0, 0x0, 0x8, 0x2b, + 0xb, 0x40, 0x0, 0x6, 0x5c, 0x0, 0xb, 0xb, + 0x10, 0x0, 0x0, 0xa, 0x1, 0x7d, 0xb, 0x6b, + 0x10, 0x0, 0xa, 0x5a, 0xc, 0xb, 0x5, 0x60, + 0x0, 0xa, 0x0, 0x38, 0xb, 0x0, 0x50, 0x0, + 0xa, 0x0, 0x91, 0xb, 0x20, 0xa1, 0x0, 0x6b, + 0x15, 0x10, 0x4, 0x99, 0x80, 0xb, 0x60, 0x84, + 0x0, 0x0, 0x0, 0x11, 0x3, 0x0, 0x5, 0xac, + 0xde, 0xef, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+900F "透" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, + 0x30, 0x0, 0x14, 0x79, 0xb4, 0x0, 0x0, 0xa4, + 0x1, 0x31, 0xa0, 0x0, 0x20, 0x0, 0x32, 0x36, + 0x58, 0xd6, 0x56, 0xa0, 0x0, 0x0, 0x0, 0x2a, + 0xa4, 0x50, 0x0, 0x4, 0x59, 0x3, 0x70, 0xa0, + 0x5b, 0x61, 0x2, 0x1a, 0x46, 0x67, 0x85, 0x92, + 0x60, 0x0, 0xa, 0x0, 0xb, 0x4, 0x72, 0x0, + 0x0, 0xa, 0x0, 0x19, 0x6, 0x5d, 0x0, 0x0, + 0xa, 0x0, 0x72, 0x0, 0x1a, 0x0, 0x0, 0x3b, + 0x3, 0x50, 0x16, 0x96, 0x0, 0x9, 0x71, 0x84, + 0x0, 0x3, 0x80, 0x0, 0x6, 0x0, 0x7, 0xab, + 0xcc, 0xcd, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+9010 "逐" */ + 0x0, 0x82, 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, + 0x3c, 0x6, 0x55, 0xd5, 0x55, 0x50, 0x0, 0x3, + 0x0, 0x9, 0x40, 0x4, 0x10, 0x0, 0x0, 0x1, + 0x71, 0x90, 0x3a, 0x20, 0x6, 0x5c, 0x3, 0x5, + 0xaa, 0x50, 0x0, 0x0, 0xb, 0x0, 0x65, 0xc, + 0x0, 0x0, 0x0, 0xb, 0x15, 0x20, 0xad, 0x76, + 0x0, 0x0, 0xb, 0x0, 0x9, 0x4a, 0x19, 0x80, + 0x0, 0xb, 0x3, 0x81, 0xc, 0x0, 0xb0, 0x0, + 0x4c, 0x23, 0x5, 0x7c, 0x0, 0x0, 0xa, 0x50, + 0x94, 0x0, 0x72, 0x0, 0x0, 0x4, 0x0, 0x6, + 0xbc, 0xcc, 0xcd, 0xa1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x0, + + /* U+9019 "這" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x92, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x3c, + 0x0, 0x0, 0x42, 0x4, 0x30, 0x0, 0x1, 0x6, + 0x55, 0x55, 0x55, 0x40, 0x0, 0x1, 0x0, 0x55, + 0x55, 0x79, 0x0, 0x6, 0x7d, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x19, 0x0, 0x65, 0x55, 0x77, + 0x0, 0x0, 0x19, 0x0, 0x20, 0x0, 0x3, 0x0, + 0x0, 0x19, 0x0, 0xd5, 0x55, 0x5d, 0x0, 0x0, + 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x1, 0xab, + 0x20, 0xc5, 0x55, 0x5b, 0x0, 0x1d, 0x30, 0x86, + 0x70, 0x0, 0x3, 0x1, 0x2, 0x0, 0x3, 0x9b, + 0xcd, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+901A "通" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x60, 0x3, 0x65, 0x55, 0x7e, 0x20, 0x0, 0x87, + 0x0, 0x5, 0x54, 0x60, 0x0, 0x0, 0x23, 0x4, + 0x0, 0xc4, 0x0, 0x40, 0x0, 0x0, 0xc, 0x55, + 0xc5, 0x56, 0xa0, 0x5, 0x4b, 0xb, 0x55, 0xc5, + 0x56, 0x90, 0x0, 0xa, 0xb, 0x0, 0xb0, 0x2, + 0x90, 0x0, 0xa, 0xb, 0x55, 0xc5, 0x56, 0x90, + 0x0, 0xa, 0xb, 0x0, 0xb0, 0x2, 0x90, 0x0, + 0xa, 0xb, 0x0, 0xb0, 0x2, 0x90, 0x0, 0x3c, + 0xb, 0x0, 0xa0, 0x4a, 0x80, 0x8, 0x80, 0x75, + 0x0, 0x0, 0x5, 0x10, 0x6, 0x0, 0x5, 0xac, + 0xdd, 0xde, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x10, + + /* U+901F "速" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, + 0x10, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xc2, + 0x35, 0x55, 0xd5, 0x57, 0x90, 0x0, 0x63, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x55, + 0xc5, 0x5c, 0x0, 0x3, 0x38, 0x9, 0x10, 0xb0, + 0xb, 0x0, 0x3, 0x1b, 0x9, 0x65, 0xc5, 0x5b, + 0x0, 0x0, 0xb, 0x6, 0x6, 0xf0, 0x5, 0x0, + 0x0, 0xb, 0x0, 0x39, 0xb6, 0x71, 0x0, 0x0, + 0xb, 0x2, 0x80, 0xb0, 0x3d, 0x30, 0x0, 0x4b, + 0x33, 0x0, 0xc0, 0x2, 0x40, 0xa, 0x60, 0x84, + 0x0, 0x90, 0x0, 0x0, 0x4, 0x0, 0x5, 0xab, + 0xcd, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9020 "造" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, + 0x50, 0x0, 0x30, 0xb2, 0x0, 0x0, 0x0, 0xa6, + 0x0, 0xd2, 0xb0, 0x3, 0x0, 0x0, 0x33, 0x3, + 0xa5, 0xc5, 0x69, 0x10, 0x0, 0x0, 0x7, 0x0, + 0xb0, 0x0, 0x0, 0x6, 0x6b, 0x26, 0x55, 0xc5, + 0x55, 0xc2, 0x0, 0x19, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x19, 0x0, 0xa5, 0x55, 0x5d, 0x0, + 0x0, 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, + 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x1, 0x8b, + 0x0, 0xc5, 0x55, 0x5b, 0x0, 0x1d, 0x40, 0x95, + 0x50, 0x0, 0x1, 0x0, 0x3, 0x0, 0x6, 0xbc, + 0xcd, 0xee, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9023 "連" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x93, 0x0, 0x0, 0xa2, 0x1, 0x0, 0x0, 0x2c, + 0x5, 0x55, 0xc5, 0x57, 0x50, 0x0, 0x1, 0x0, + 0x30, 0xa0, 0x5, 0x0, 0x0, 0x1, 0x0, 0xc5, + 0xc5, 0x5c, 0x10, 0x16, 0x5e, 0x10, 0xc5, 0xc5, + 0x5b, 0x0, 0x0, 0xb, 0x0, 0xb0, 0xa0, 0xa, + 0x0, 0x0, 0xb, 0x0, 0xc5, 0xc5, 0x5b, 0x0, + 0x0, 0xb, 0x0, 0x10, 0xa0, 0x0, 0x30, 0x0, + 0xb, 0x46, 0x55, 0xc5, 0x55, 0x71, 0x2, 0xaa, + 0x20, 0x0, 0xa0, 0x0, 0x0, 0xd, 0x20, 0x78, + 0x31, 0x70, 0x0, 0x22, 0x1, 0x0, 0x2, 0x7a, + 0xcc, 0xdd, 0xa1, + + /* U+902E "逮" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x71, 0x0, 0x0, 0xc1, 0x1, 0x0, 0x0, 0x2c, + 0x3, 0x65, 0xc5, 0x5d, 0x0, 0x0, 0x2, 0x0, + 0x0, 0xb0, 0xc, 0x40, 0x0, 0x0, 0x26, 0x55, + 0xc5, 0x5d, 0x52, 0x7, 0x6d, 0x2, 0x55, 0xc5, + 0x5c, 0x0, 0x0, 0xa, 0x4, 0x20, 0xb0, 0x4, + 0x0, 0x0, 0xa, 0x0, 0xb3, 0xb2, 0xa7, 0x0, + 0x0, 0xa, 0x0, 0x26, 0xd8, 0x0, 0x0, 0x0, + 0xa, 0x3a, 0x70, 0xb2, 0x98, 0x0, 0x0, 0x5a, + 0x13, 0x33, 0xc0, 0x7, 0x40, 0x9, 0x50, 0x83, + 0x8, 0x90, 0x0, 0x0, 0x4, 0x0, 0x6, 0xab, + 0xbc, 0xcd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9031 "週" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x8, 0x55, 0x65, 0x5b, 0x30, 0x0, 0xd, + 0xb, 0x0, 0xa2, 0xa, 0x0, 0x0, 0x0, 0xa, + 0x6, 0xc7, 0x4a, 0x0, 0x0, 0x5, 0xa, 0x0, + 0xa0, 0x3a, 0x0, 0x16, 0x5d, 0xa, 0x36, 0x65, + 0x7a, 0x0, 0x0, 0xa, 0x9, 0x8, 0x59, 0x4a, + 0x0, 0x0, 0xa, 0x9, 0xa, 0x8, 0x2a, 0x0, + 0x0, 0xa, 0x8, 0xc, 0x5a, 0x2a, 0x0, 0x0, + 0xa, 0x24, 0x7, 0x2, 0xa, 0x0, 0x0, 0x7b, + 0x50, 0x0, 0x2, 0x7c, 0x0, 0x1c, 0x30, 0x94, + 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0xbb, + 0xcc, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9032 "進" */ + 0x0, 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, + 0x84, 0x0, 0xa7, 0x49, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0xd0, 0x9, 0x2, 0x0, 0x0, 0x1, 0x5, + 0xc5, 0x59, 0x58, 0x40, 0x0, 0x4, 0xa, 0xa0, + 0xa, 0x1, 0x0, 0x6, 0x5d, 0x63, 0xc5, 0x5c, + 0x59, 0x10, 0x0, 0xb, 0x0, 0xa0, 0xa, 0x0, + 0x0, 0x0, 0xb, 0x0, 0xc5, 0x5c, 0x5b, 0x10, + 0x0, 0xb, 0x0, 0xa0, 0xa, 0x0, 0x0, 0x0, + 0xb, 0x0, 0xa0, 0xa, 0x5, 0x30, 0x1, 0x8b, + 0x10, 0xc5, 0x55, 0x55, 0x30, 0xd, 0x40, 0x96, + 0x20, 0x0, 0x0, 0x1, 0x3, 0x0, 0x5, 0xbc, + 0xcd, 0xef, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9045 "遅" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x84, 0x2, 0x95, 0x55, 0x55, 0xc0, 0x0, 0x1d, + 0x1, 0xa0, 0x0, 0x0, 0xb0, 0x0, 0x1, 0x0, + 0xc5, 0x55, 0x55, 0xb0, 0x0, 0x4, 0x0, 0xa2, + 0x70, 0x67, 0x0, 0x6, 0x5d, 0x11, 0xa5, 0xb5, + 0xb6, 0x90, 0x0, 0xb, 0x3, 0x71, 0xb, 0x1, + 0x0, 0x0, 0xb, 0x6, 0x36, 0x5c, 0x59, 0x40, + 0x0, 0xb, 0x8, 0x0, 0xb, 0x0, 0x51, 0x0, + 0xb, 0x33, 0x55, 0x5d, 0x55, 0x52, 0x0, 0x7c, + 0x40, 0x0, 0xc, 0x0, 0x0, 0xc, 0x50, 0x95, + 0x0, 0x8, 0x0, 0x0, 0x4, 0x0, 0x5, 0xab, + 0xbb, 0xcd, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+904A "遊" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x93, 0x0, 0xc1, 0x0, 0x0, 0x1c, + 0x0, 0x24, 0x5, 0x60, 0x41, 0x0, 0x0, 0x16, + 0x75, 0x9a, 0x55, 0x53, 0x0, 0x3, 0x1, 0x90, + 0x44, 0x55, 0xa1, 0x6, 0x6d, 0x2, 0xb6, 0xa0, + 0x5, 0x50, 0x0, 0x19, 0x4, 0x63, 0x70, 0x1a, + 0x10, 0x0, 0x19, 0x7, 0x24, 0x77, 0x5b, 0x75, + 0x0, 0x19, 0x9, 0x6, 0x40, 0x18, 0x0, 0x0, + 0x19, 0x43, 0x9, 0x10, 0x18, 0x0, 0x0, 0x7b, + 0x41, 0x9b, 0x3, 0x88, 0x0, 0x1d, 0x31, 0x82, + 0x0, 0x0, 0x41, 0x0, 0x2, 0x0, 0x6, 0xaa, + 0xbb, 0xcc, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x0, + + /* U+904B "運" */ + 0x1, 0x80, 0x5, 0x65, 0x55, 0x56, 0x70, 0x0, + 0x6a, 0xc, 0x0, 0x72, 0x6, 0x30, 0x0, 0x5, + 0x6, 0x55, 0xc5, 0x59, 0x20, 0x0, 0x1, 0x0, + 0x30, 0xa0, 0x4, 0x0, 0x6, 0x6e, 0x10, 0xc5, + 0xc5, 0x5c, 0x0, 0x0, 0xa, 0x0, 0xc5, 0xc5, + 0x5b, 0x0, 0x0, 0xa, 0x0, 0xa0, 0xa0, 0xa, + 0x0, 0x0, 0xa, 0x0, 0xa5, 0xc5, 0x58, 0x0, + 0x0, 0xa, 0x26, 0x55, 0xc5, 0x55, 0xa0, 0x0, + 0x7c, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x1d, 0x51, + 0x93, 0x0, 0xa0, 0x0, 0x0, 0x2, 0x0, 0x6, + 0xbb, 0xcc, 0xcd, 0xb2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+904E "過" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0x0, 0x75, 0x55, 0x69, 0x0, 0x0, 0x2d, + 0x0, 0x91, 0x3, 0x46, 0x0, 0x0, 0x1, 0x0, + 0x86, 0x89, 0x46, 0x0, 0x0, 0x3, 0x1, 0x81, + 0x46, 0x46, 0x20, 0x16, 0x6d, 0xb, 0x65, 0x56, + 0x56, 0xd0, 0x0, 0x19, 0xa, 0x7, 0x55, 0x90, + 0xa0, 0x0, 0x19, 0xa, 0xa, 0x0, 0xa0, 0xa0, + 0x0, 0x19, 0xa, 0xb, 0x55, 0xb0, 0xa0, 0x0, + 0x19, 0xb, 0x9, 0x0, 0x70, 0xa0, 0x0, 0x7a, + 0xa, 0x0, 0x0, 0x3a, 0x80, 0x1d, 0x41, 0x84, + 0x0, 0x0, 0x1, 0x0, 0x2, 0x0, 0x5, 0xac, + 0xcd, 0xdd, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9053 "道" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, + 0x84, 0x0, 0x67, 0x0, 0xc4, 0x0, 0x0, 0x2c, + 0x0, 0xa, 0x4, 0x40, 0x40, 0x0, 0x1, 0x16, + 0x55, 0xa6, 0x55, 0x82, 0x0, 0x4, 0x0, 0x75, + 0xa5, 0x59, 0x0, 0x7, 0x6d, 0x0, 0xc0, 0x0, + 0xc, 0x0, 0x0, 0xa, 0x0, 0xc5, 0x55, 0x5b, + 0x0, 0x0, 0xa, 0x0, 0xb0, 0x0, 0xb, 0x0, + 0x0, 0xa, 0x0, 0xc5, 0x55, 0x5b, 0x0, 0x0, + 0xa, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x1, 0x88, + 0x20, 0xc5, 0x55, 0x5b, 0x0, 0xc, 0x20, 0x77, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8b, + 0xcc, 0xde, 0xd2, + + /* U+9054 "達" */ + 0x0, 0x20, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x0, 0xa3, 0x2, 0x0, 0x0, 0xd, + 0x2, 0x65, 0xb6, 0x67, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0x1, 0x70, 0x0, 0x3, 0x26, 0x88, + 0x55, 0xb5, 0x51, 0x16, 0x6c, 0x0, 0xc, 0x6, + 0x62, 0x20, 0x0, 0x19, 0x6, 0x55, 0xb6, 0x56, + 0x50, 0x0, 0x19, 0x1, 0x55, 0xb6, 0x69, 0x0, + 0x0, 0x19, 0x0, 0x10, 0xa1, 0x0, 0x10, 0x0, + 0x19, 0x17, 0x55, 0xb6, 0x56, 0x70, 0x2, 0xbb, + 0x10, 0x0, 0xa1, 0x0, 0x0, 0x1e, 0x20, 0xa6, + 0x10, 0x81, 0x0, 0x0, 0x1, 0x0, 0x5, 0xbd, + 0xde, 0xef, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9055 "違" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, + 0x90, 0x0, 0xc, 0x10, 0x40, 0x0, 0x0, 0xb5, + 0x6, 0x8a, 0x55, 0xc0, 0x0, 0x0, 0x20, 0x22, + 0x77, 0x22, 0xb4, 0x70, 0x0, 0x20, 0x35, 0x22, + 0x22, 0x43, 0x20, 0x46, 0xc5, 0x9, 0x65, 0x55, + 0xb4, 0x0, 0x0, 0x92, 0x9, 0x65, 0x75, 0xb1, + 0x0, 0x0, 0x92, 0x2, 0x0, 0xa0, 0x34, 0x0, + 0x0, 0x92, 0x4a, 0x55, 0xc5, 0x54, 0x0, 0x0, + 0x92, 0x4c, 0x55, 0xc5, 0x57, 0x80, 0x5, 0xc6, + 0x11, 0x0, 0xb0, 0x0, 0x0, 0x8b, 0x5, 0x81, + 0x0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x3a, 0xcb, + 0xbc, 0xde, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+9060 "遠" */ + 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, + 0x74, 0x0, 0x0, 0xb2, 0x2, 0x0, 0x0, 0xe, + 0x1, 0x75, 0xc5, 0x59, 0x10, 0x0, 0x3, 0x0, + 0x0, 0xb0, 0x0, 0x60, 0x0, 0x0, 0x26, 0x65, + 0x55, 0x57, 0x51, 0x16, 0x6c, 0x0, 0xc4, 0x44, + 0x4d, 0x0, 0x0, 0x19, 0x0, 0xc5, 0x55, 0x5b, + 0x0, 0x0, 0x19, 0x0, 0x77, 0xb0, 0x6, 0x0, + 0x0, 0x19, 0x0, 0x78, 0xa4, 0x58, 0x20, 0x0, + 0x19, 0x27, 0x31, 0x90, 0x79, 0x10, 0x1, 0x8b, + 0x10, 0x2, 0x90, 0x3, 0x90, 0x1d, 0x40, 0x94, + 0x1, 0x60, 0x0, 0x0, 0x2, 0x0, 0x5, 0xab, + 0xcc, 0xdd, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9069 "適" */ + 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, + 0x91, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x5a, + 0x6, 0x55, 0x65, 0x58, 0x80, 0x0, 0x2, 0x0, + 0x46, 0x6, 0x50, 0x0, 0x0, 0x2, 0x6, 0x5a, + 0x5a, 0x58, 0x30, 0x16, 0x6d, 0xa, 0x0, 0xa2, + 0x9, 0x20, 0x0, 0x19, 0xa, 0x26, 0xc5, 0x89, + 0x10, 0x0, 0x19, 0xa, 0x2, 0xa1, 0x19, 0x10, + 0x0, 0x19, 0xa, 0xc, 0x59, 0x59, 0x10, 0x0, + 0x19, 0xa, 0xc, 0x59, 0x49, 0x10, 0x0, 0x7b, + 0xb, 0x5, 0x3, 0x3a, 0x10, 0x1d, 0x41, 0x94, + 0x0, 0x0, 0x39, 0x0, 0x2, 0x0, 0x7, 0xbb, + 0xcc, 0xcd, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9078 "選" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x95, 0x7, 0x59, 0x48, 0x5a, 0x20, 0x0, 0x1d, + 0x9, 0x9, 0x19, 0x9, 0x0, 0x0, 0x0, 0x9, + 0x57, 0x39, 0x57, 0x30, 0x0, 0x2, 0x8, 0x65, + 0x98, 0x65, 0x90, 0x16, 0x6d, 0x0, 0x3a, 0x11, + 0x72, 0x0, 0x0, 0x19, 0x4, 0x5c, 0x57, 0xb8, + 0x50, 0x0, 0x19, 0x1, 0x9, 0x2, 0x70, 0x0, + 0x0, 0x19, 0x35, 0x5b, 0x56, 0x95, 0xa1, 0x0, + 0x19, 0x0, 0xa, 0x23, 0x61, 0x0, 0x1, 0xac, + 0x3, 0x93, 0x0, 0x1c, 0x30, 0x1e, 0x41, 0xa6, + 0x0, 0x0, 0x1, 0x10, 0x3, 0x0, 0x6, 0xaa, + 0xbb, 0xbc, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x0, + + /* U+907F "避" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, + 0x60, 0x32, 0x25, 0x2, 0xa0, 0x0, 0x0, 0xa4, + 0x94, 0x3c, 0x65, 0x86, 0x70, 0x0, 0x10, 0x91, + 0xa, 0x31, 0xa, 0x0, 0x0, 0x0, 0x96, 0x5b, + 0xb, 0x26, 0x0, 0x46, 0xa5, 0x90, 0x3, 0x57, + 0x95, 0xa0, 0x0, 0x92, 0xa4, 0x25, 0x10, 0xa0, + 0x0, 0x0, 0x92, 0x8c, 0x3b, 0x0, 0xa0, 0x30, + 0x0, 0x93, 0x6b, 0xa, 0x55, 0xc5, 0x40, 0x0, + 0x97, 0xb, 0xa, 0x0, 0xa0, 0x0, 0x1, 0x94, + 0xc, 0x5a, 0x0, 0xb0, 0x0, 0x3b, 0x4, 0x72, + 0x0, 0x0, 0x50, 0x0, 0x1, 0x0, 0x18, 0xbc, + 0xcc, 0xde, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9084 "還" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xa0, 0xa, 0x58, 0x58, 0x5b, 0x30, 0x0, 0x97, + 0xb, 0xa, 0xa, 0x9, 0x0, 0x0, 0x11, 0xc, + 0x59, 0x59, 0x5b, 0x10, 0x0, 0x10, 0x57, 0x55, + 0x55, 0x56, 0xb0, 0x36, 0xb5, 0x4, 0x55, 0x55, + 0x58, 0x0, 0x0, 0x92, 0x7, 0x30, 0x0, 0xb, + 0x0, 0x0, 0x92, 0x7, 0x7c, 0x55, 0x59, 0x0, + 0x0, 0x92, 0x0, 0xb6, 0x42, 0x96, 0x0, 0x0, + 0x92, 0x29, 0x94, 0x2a, 0x60, 0x0, 0x1, 0xb5, + 0x40, 0x79, 0x72, 0x8a, 0x0, 0x3c, 0x15, 0x71, + 0x35, 0x0, 0x2, 0x0, 0x43, 0x0, 0x29, 0xbc, + 0xcc, 0xcd, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+908A "邊" */ + 0x0, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, + 0x71, 0x0, 0x55, 0xb7, 0x58, 0x0, 0x0, 0x3d, + 0x0, 0xb5, 0x55, 0x5b, 0x0, 0x0, 0x7, 0x0, + 0xa5, 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb5, + 0x55, 0x5c, 0x0, 0x14, 0x5a, 0x2, 0x30, 0x55, + 0x2, 0x30, 0x1, 0x1a, 0x2a, 0x5a, 0x77, 0x85, + 0xb1, 0x0, 0x19, 0x12, 0x54, 0x45, 0x35, 0x30, + 0x0, 0x19, 0x6, 0x58, 0x75, 0x57, 0x70, 0x0, + 0x19, 0x0, 0xb, 0x55, 0x5d, 0x10, 0x1, 0x9b, + 0x11, 0x92, 0x3, 0x58, 0x0, 0x1d, 0x31, 0xaa, + 0x10, 0x1, 0x91, 0x0, 0x2, 0x0, 0x6, 0xbc, + 0xdd, 0xde, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+90A3 "那" */ + 0x2, 0x55, 0x55, 0x93, 0x75, 0x56, 0x70, 0x0, + 0x11, 0xa0, 0xa1, 0xb0, 0x7, 0x70, 0x0, 0x1, + 0xa0, 0xa1, 0xb0, 0xa, 0x0, 0x1, 0x55, 0xc5, + 0xc1, 0xb0, 0x25, 0x0, 0x0, 0x11, 0xa0, 0xa1, + 0xb0, 0x50, 0x0, 0x0, 0x2, 0x90, 0xa1, 0xb0, + 0x7, 0x0, 0x2, 0x67, 0xa5, 0xc1, 0xb0, 0x5, + 0x40, 0x0, 0x6, 0x30, 0xa1, 0xb0, 0x0, 0xa0, + 0x0, 0x9, 0x0, 0xa1, 0xb0, 0x13, 0xb0, 0x0, + 0x27, 0x0, 0xb0, 0xb1, 0x7f, 0x40, 0x0, 0x80, + 0x5b, 0xc0, 0xb0, 0x0, 0x0, 0x5, 0x0, 0x3, + 0x10, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x0, + + /* U+90AA "邪" */ + 0x2, 0x55, 0x55, 0x87, 0x75, 0x57, 0x70, 0x1, + 0x0, 0xb0, 0xb, 0x0, 0x95, 0x0, 0xb2, 0xb, + 0x0, 0xb0, 0xa, 0x0, 0x1c, 0x0, 0xb0, 0xb, + 0x4, 0x40, 0x7, 0xa5, 0x5c, 0x7a, 0xb0, 0x60, + 0x0, 0x10, 0x9, 0xd0, 0xb, 0x4, 0x30, 0x0, + 0x2, 0xab, 0x0, 0xb0, 0x9, 0x0, 0x0, 0xa1, + 0xb0, 0xb, 0x0, 0x47, 0x0, 0x64, 0xb, 0x0, + 0xb0, 0x3, 0xa0, 0x44, 0x0, 0xb0, 0xb, 0x28, + 0xe6, 0x22, 0x3, 0x3c, 0x0, 0xb0, 0x4, 0x0, + 0x0, 0x9, 0x90, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, + + /* U+90E8 "部" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xa0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, + 0x92, 0x15, 0xc, 0x55, 0xd2, 0x3, 0x75, 0x55, + 0x75, 0xb, 0x1, 0xa0, 0x0, 0x37, 0x2, 0xc0, + 0xb, 0x6, 0x30, 0x0, 0xb, 0x7, 0x10, 0xb, + 0x7, 0x0, 0x6, 0x55, 0x57, 0x58, 0x6b, 0x6, + 0x0, 0x0, 0x10, 0x0, 0x30, 0xb, 0x3, 0x60, + 0x0, 0xc5, 0x55, 0xd2, 0xb, 0x0, 0xb0, 0x0, + 0xb0, 0x0, 0xb0, 0xb, 0x0, 0xa2, 0x0, 0xb0, + 0x0, 0xb0, 0xb, 0x59, 0xd0, 0x0, 0xb5, 0x55, + 0xc0, 0xb, 0x6, 0x20, 0x0, 0x90, 0x0, 0x70, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, + + /* U+90F5 "郵" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, + 0x47, 0xab, 0xa0, 0x65, 0x58, 0x50, 0x1, 0x10, + 0xa0, 0x0, 0x82, 0xc, 0x30, 0x5, 0x55, 0xc5, + 0x5a, 0x92, 0x36, 0x0, 0x0, 0xa0, 0xa0, 0xa0, + 0x82, 0x70, 0x0, 0x0, 0xa0, 0xa0, 0xa1, 0x82, + 0x50, 0x0, 0x5, 0xc5, 0xc5, 0xb6, 0x82, 0x33, + 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0x82, 0x7, 0x30, + 0x5, 0xc5, 0xc5, 0xc9, 0x92, 0x0, 0xa0, 0x1, + 0x0, 0xa0, 0x0, 0x82, 0x0, 0xc0, 0x0, 0x0, + 0xb4, 0x53, 0x85, 0x7e, 0x80, 0x7, 0xca, 0x52, + 0x0, 0x82, 0x3, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+90FD "都" */ + 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x3, 0x6, 0x44, 0x72, 0x0, 0x45, + 0xc7, 0x8d, 0x3c, 0x11, 0xd1, 0x0, 0x10, 0xb1, + 0x67, 0xb, 0x3, 0x70, 0x0, 0x0, 0xb3, 0xb0, + 0x3b, 0x7, 0x10, 0x5, 0x55, 0x7d, 0x65, 0x5b, + 0x6, 0x0, 0x0, 0x1, 0xa2, 0x3, 0xb, 0x6, + 0x10, 0x0, 0x4d, 0x55, 0x6c, 0xb, 0x0, 0xa0, + 0x5, 0x4a, 0x0, 0x19, 0xb, 0x0, 0xa3, 0x0, + 0xc, 0x55, 0x69, 0xb, 0x0, 0x94, 0x0, 0xa, + 0x0, 0x1a, 0xb, 0x3b, 0xd0, 0x0, 0x1c, 0x55, + 0x6a, 0xb, 0x1, 0x0, 0x0, 0x1a, 0x0, 0x16, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+914D "配" */ + 0x25, 0x55, 0x55, 0xb3, 0x55, 0x58, 0x10, 0x1, + 0xa, 0x91, 0x0, 0x10, 0xb, 0x0, 0x3, 0xa, + 0x91, 0x40, 0x0, 0xb, 0x0, 0xb, 0x5b, 0xb6, + 0xc0, 0x0, 0xb, 0x0, 0xb, 0x18, 0x91, 0xb0, + 0x75, 0x5c, 0x0, 0xb, 0x44, 0x91, 0xb0, 0xb0, + 0x7, 0x0, 0xb, 0x70, 0x4a, 0xb0, 0xb0, 0x0, + 0x0, 0xb, 0x0, 0x0, 0xb0, 0xb0, 0x0, 0x0, + 0xb, 0x55, 0x55, 0xb0, 0xb0, 0x0, 0x10, 0xb, + 0x0, 0x0, 0xb0, 0xb0, 0x0, 0x50, 0xb, 0x55, + 0x55, 0xb0, 0xb0, 0x0, 0x90, 0xb, 0x0, 0x0, + 0xb0, 0xaa, 0x9b, 0xb0, 0x4, 0x0, 0x0, 0x30, + 0x0, 0x0, 0x0, + + /* U+9152 "酒" */ + 0x1, 0x60, 0x45, 0x55, 0x55, 0x56, 0xa0, 0x0, + 0x75, 0x10, 0xa, 0xa, 0x0, 0x0, 0x0, 0x1, + 0x32, 0xa, 0xa, 0x3, 0x0, 0x7, 0x1, 0x4d, + 0x5c, 0x5c, 0x5c, 0x20, 0x4, 0x95, 0xb, 0xa, + 0xa, 0xb, 0x0, 0x0, 0x27, 0xb, 0x9, 0xa, + 0xb, 0x0, 0x0, 0x26, 0xb, 0x53, 0x6, 0x9d, + 0x0, 0x1, 0x92, 0xb, 0x30, 0x0, 0xb, 0x0, + 0x4, 0xe0, 0xc, 0x55, 0x55, 0x5c, 0x0, 0x0, + 0xb0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, 0xe0, + 0xd, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x80, 0xb, + 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9154 "酔" */ + 0x0, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x15, + 0x55, 0x55, 0x90, 0x85, 0x0, 0x0, 0x1, 0x54, + 0x90, 0x4, 0xa7, 0x58, 0x0, 0x1, 0x54, 0x92, + 0x1, 0x91, 0xa, 0x0, 0xa, 0x88, 0xba, 0x50, + 0xa0, 0xa, 0x10, 0x9, 0x53, 0x97, 0x24, 0x60, + 0x9, 0x50, 0x9, 0x71, 0x97, 0x46, 0x8, 0x4a, + 0xa3, 0x9, 0x70, 0xac, 0x40, 0xc, 0x10, 0x0, + 0xa, 0x0, 0x7, 0x43, 0x3c, 0x43, 0x80, 0xa, + 0x55, 0x5a, 0x43, 0x2c, 0x32, 0x20, 0x9, 0x0, + 0x7, 0x20, 0xb, 0x10, 0x0, 0xa, 0x55, 0x5a, + 0x30, 0xc, 0x10, 0x0, 0xa, 0x0, 0x7, 0x20, + 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+9178 "酸" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x15, + 0x55, 0x56, 0x80, 0x3a, 0x11, 0x0, 0x1, 0x36, + 0x90, 0x2, 0x70, 0x8, 0x40, 0x1, 0x36, 0x91, + 0x2c, 0x86, 0x55, 0xd0, 0xa, 0x79, 0xbb, 0x32, + 0x51, 0x33, 0x30, 0xa, 0x45, 0x99, 0x13, 0xa1, + 0x7, 0xb0, 0xa, 0x53, 0x99, 0x45, 0x57, 0x0, + 0x81, 0xa, 0x70, 0x9c, 0x10, 0xc6, 0x5b, 0x30, + 0xa, 0x20, 0x9, 0x16, 0x70, 0x1b, 0x0, 0xa, + 0x55, 0x5b, 0x44, 0x51, 0xa3, 0x0, 0xa, 0x0, + 0x9, 0x20, 0xc, 0x70, 0x0, 0xa, 0x55, 0x5b, + 0x10, 0x59, 0xa1, 0x0, 0xb, 0x0, 0x8, 0x27, + 0x50, 0x3d, 0x92, 0x3, 0x0, 0x1, 0x40, 0x0, + 0x1, 0x50, + + /* U+91AB "醫" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, + 0xb5, 0x85, 0x82, 0x95, 0xb3, 0x0, 0x0, 0xa6, + 0x96, 0x80, 0x90, 0x86, 0x30, 0x0, 0xa4, 0x27, + 0x34, 0x30, 0x16, 0x20, 0x0, 0xa5, 0xaa, 0x52, + 0x75, 0xb7, 0x0, 0x0, 0xa3, 0x51, 0x61, 0x29, + 0xb1, 0x0, 0x2, 0xa6, 0x55, 0x57, 0x53, 0x29, + 0x10, 0x5, 0x55, 0x55, 0x95, 0x95, 0x55, 0x91, + 0x0, 0x17, 0x55, 0xc5, 0xc5, 0x76, 0x0, 0x0, + 0x1a, 0x5, 0x50, 0xa0, 0x55, 0x0, 0x0, 0x1a, + 0x44, 0x0, 0x57, 0xa5, 0x0, 0x0, 0x1b, 0x55, + 0x55, 0x55, 0x85, 0x0, 0x0, 0x1b, 0x55, 0x55, + 0x55, 0x85, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, + 0x22, 0x0, + + /* U+91CD "重" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x23, 0x57, 0x9b, 0x90, 0x0, 0x0, 0x23, + 0x22, 0xb1, 0x0, 0x2, 0x0, 0x5, 0x65, 0x55, + 0xc5, 0x55, 0x5a, 0x40, 0x0, 0x2, 0x0, 0xa1, + 0x0, 0x40, 0x0, 0x0, 0xd, 0x55, 0xc5, 0x55, + 0xc0, 0x0, 0x0, 0xd, 0x55, 0xc5, 0x55, 0xb0, + 0x0, 0x0, 0xc, 0x0, 0xa1, 0x0, 0xb0, 0x0, + 0x0, 0xd, 0x55, 0xc5, 0x55, 0xc0, 0x0, 0x0, + 0x4, 0x0, 0xa1, 0x0, 0x50, 0x0, 0x0, 0x65, + 0x55, 0xc5, 0x55, 0x86, 0x0, 0x0, 0x0, 0x0, + 0xa1, 0x0, 0x1, 0x40, 0x26, 0x55, 0x55, 0x85, + 0x55, 0x57, 0x91, + + /* U+91CE "野" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, + 0x75, 0x5b, 0x45, 0x55, 0xd2, 0xb, 0x9, 0x10, + 0xb0, 0x0, 0x75, 0x0, 0xb0, 0x91, 0xb, 0x5, + 0x93, 0x0, 0xb, 0x5b, 0x65, 0xb0, 0x9, 0x60, + 0x0, 0xb0, 0x91, 0xb, 0x65, 0x86, 0x89, 0xb, + 0x5b, 0x65, 0xb0, 0xa, 0x8, 0x0, 0x40, 0x91, + 0x2, 0x0, 0xa1, 0x10, 0x1, 0x19, 0x10, 0x70, + 0xa, 0x0, 0x0, 0x54, 0xb6, 0x55, 0x0, 0xa0, + 0x0, 0x0, 0x9, 0x10, 0x11, 0xa, 0x0, 0x1, + 0x46, 0xb7, 0x53, 0x0, 0xa0, 0x0, 0x59, 0x30, + 0x0, 0x3, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, 0x0, + + /* U+91CF "量" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xb, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xb, + 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb, 0x55, + 0x55, 0x55, 0xb0, 0x0, 0x0, 0x8, 0x0, 0x0, + 0x0, 0x40, 0x50, 0x17, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x72, 0x0, 0xa, 0x55, 0x57, 0x55, 0xb0, + 0x0, 0x0, 0xb, 0x0, 0x19, 0x0, 0xb0, 0x0, + 0x0, 0xc, 0x55, 0x6b, 0x55, 0xc0, 0x0, 0x0, + 0xd, 0x55, 0x6b, 0x55, 0xb0, 0x0, 0x0, 0x2, + 0x0, 0x19, 0x0, 0x34, 0x0, 0x0, 0x56, 0x55, + 0x6b, 0x55, 0x54, 0x0, 0x5, 0x55, 0x55, 0x6b, + 0x55, 0x56, 0xc1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+91D1 "金" */ + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, + 0x3, 0x80, 0x0, 0x0, 0x0, 0x5, 0x90, 0x0, + 0x4b, 0x20, 0x0, 0x0, 0x56, 0x0, 0x0, 0x6, + 0xdb, 0x71, 0x15, 0x21, 0x65, 0xc5, 0x56, 0x5, + 0x50, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x65, 0x55, 0xd5, 0x55, 0x95, 0x0, 0x0, + 0x4, 0x0, 0xc0, 0x7, 0x10, 0x0, 0x0, 0x3, + 0xc0, 0xc0, 0x1c, 0x10, 0x0, 0x0, 0x0, 0xb3, + 0xc0, 0x72, 0x0, 0x0, 0x15, 0x55, 0x65, 0xd5, + 0x95, 0x58, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+91DD "針" */ + 0x0, 0x3, 0x10, 0x0, 0x6, 0x10, 0x0, 0x0, + 0xe, 0x50, 0x0, 0xc, 0x10, 0x0, 0x0, 0x58, + 0x79, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa0, 0x8, + 0x30, 0xc, 0x0, 0x0, 0x6, 0x30, 0x22, 0x0, + 0xc, 0x0, 0x0, 0x24, 0x5b, 0x63, 0x35, 0x5d, + 0x56, 0xb0, 0x0, 0x9, 0x10, 0x1, 0xc, 0x0, + 0x0, 0x4, 0x6b, 0x6b, 0x10, 0xc, 0x0, 0x0, + 0x1, 0x9, 0x15, 0x0, 0xc, 0x0, 0x0, 0x0, + 0xa9, 0x2c, 0x0, 0xc, 0x0, 0x0, 0x0, 0xba, + 0x62, 0x0, 0xc, 0x0, 0x0, 0x2, 0x5c, 0x85, + 0x10, 0xc, 0x0, 0x0, 0x9, 0x61, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x0, 0x0, + + /* U+9244 "鉄" */ + 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xe, 0x30, 0x0, 0xd, 0x0, 0x0, 0x0, 0x59, + 0x84, 0xd, 0x1b, 0x0, 0x0, 0x0, 0xa0, 0xc, + 0x5a, 0xb, 0x3, 0x0, 0x6, 0x30, 0x32, 0x77, + 0x5c, 0x57, 0x30, 0x24, 0x6c, 0x53, 0x90, 0xb, + 0x0, 0x0, 0x0, 0xb, 0x3, 0x10, 0x1a, 0x0, + 0x30, 0x5, 0x6c, 0x57, 0x56, 0x7d, 0x55, 0x71, + 0x3, 0xb, 0x9, 0x10, 0x78, 0x20, 0x0, 0x4, + 0x7b, 0x29, 0x0, 0xb0, 0x90, 0x0, 0x1, 0x8b, + 0x42, 0x16, 0x50, 0x75, 0x0, 0x5, 0x8b, 0x73, + 0x47, 0x0, 0xd, 0x70, 0x7, 0x20, 0x4, 0x40, + 0x0, 0x1, 0x92, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+925B "鉛" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x30, 0x2, 0x0, 0x3, 0x0, 0x0, 0x59, + 0x85, 0x7, 0x95, 0x5c, 0x0, 0x0, 0xa0, 0xc, + 0x27, 0x50, 0xa, 0x0, 0x6, 0x30, 0x32, 0x8, + 0x30, 0xa, 0x0, 0x24, 0x6c, 0x52, 0xa, 0x0, + 0xb, 0x0, 0x0, 0xb, 0x0, 0x45, 0x0, 0x7, + 0x93, 0x5, 0x5c, 0x5b, 0x33, 0x0, 0x4, 0x0, + 0x2, 0xb, 0x7, 0xc, 0x55, 0x5b, 0x40, 0x4, + 0x6b, 0x2a, 0xb, 0x0, 0x9, 0x20, 0x1, 0x9b, + 0x42, 0x1b, 0x0, 0x9, 0x20, 0x5, 0x8c, 0x74, + 0xc, 0x55, 0x5b, 0x20, 0x7, 0x20, 0x0, 0xb, + 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9280 "銀" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x10, 0x2, 0x0, 0x3, 0x0, 0x0, 0x97, + 0x82, 0x1c, 0x55, 0x5d, 0x0, 0x1, 0xa0, 0x2c, + 0xa, 0x0, 0xb, 0x0, 0x9, 0x10, 0x41, 0xc, + 0x55, 0x5b, 0x0, 0x23, 0x6c, 0x52, 0xa, 0x0, + 0xb, 0x0, 0x0, 0xb, 0x0, 0xc, 0x55, 0x5b, + 0x0, 0x6, 0x5c, 0x6a, 0x1a, 0x40, 0x6, 0x50, + 0x2, 0xb, 0x7, 0xa, 0x6, 0x19, 0x30, 0x8, + 0x2b, 0x57, 0xa, 0x8, 0x50, 0x0, 0x5, 0x4b, + 0x61, 0x1a, 0x2, 0xb2, 0x0, 0x4, 0x7c, 0x74, + 0x2c, 0x71, 0x2c, 0xa2, 0xa, 0x20, 0x0, 0x19, + 0x0, 0x0, 0x20, + + /* U+9322 "錢" */ + 0x0, 0x6, 0x0, 0x6, 0x33, 0x20, 0x0, 0x0, + 0x4d, 0x0, 0x6, 0x60, 0xa3, 0x20, 0x0, 0xa2, + 0xa5, 0x46, 0xc5, 0x55, 0x20, 0x4, 0x60, 0x8, + 0x0, 0xb1, 0xa7, 0x0, 0x8, 0x55, 0x92, 0x0, + 0x6e, 0x40, 0x10, 0x10, 0x1b, 0x0, 0x37, 0x77, + 0xb3, 0x51, 0x0, 0xb, 0x4, 0x27, 0x47, 0x5b, + 0xe3, 0x5, 0x5c, 0x66, 0x5, 0x73, 0x42, 0x60, + 0x4, 0xb, 0x1a, 0x56, 0xc5, 0x54, 0x20, 0x5, + 0x6b, 0x63, 0x0, 0xb1, 0x96, 0x0, 0x2, 0x4b, + 0x65, 0x0, 0x4d, 0x80, 0x0, 0xb, 0x96, 0x10, + 0x2, 0x8a, 0x91, 0x41, 0x2, 0x0, 0x1, 0x44, + 0x0, 0x4b, 0xc3, + + /* U+932F "錯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x3d, 0x0, 0x1, 0xc0, 0xc1, 0x0, 0x0, 0xa7, + 0x81, 0x0, 0xa0, 0xc4, 0x20, 0x2, 0x90, 0x4b, + 0x36, 0xc5, 0xd5, 0x30, 0x9, 0x10, 0x42, 0x0, + 0xa0, 0xc0, 0x0, 0x31, 0x5c, 0x43, 0x55, 0xc5, + 0xd5, 0xb2, 0x0, 0xb, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x6, 0x5c, 0x78, 0xa, 0x55, 0x5b, 0x30, + 0x3, 0xb, 0x9, 0xc, 0x0, 0xb, 0x0, 0x7, + 0x4b, 0x56, 0xd, 0x55, 0x5d, 0x0, 0x4, 0x4b, + 0x52, 0x1c, 0x0, 0xb, 0x0, 0x6, 0x9b, 0x73, + 0xd, 0x55, 0x5d, 0x10, 0x8, 0x10, 0x0, 0xb, + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9332 "録" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0x25, 0x55, 0x59, 0x10, 0x0, 0xb5, + 0x92, 0x1, 0x0, 0xb, 0x0, 0x2, 0x80, 0x3a, + 0x4, 0x55, 0x5b, 0x0, 0x9, 0x11, 0x60, 0x1, + 0x0, 0xb, 0x0, 0x32, 0x5c, 0x42, 0x55, 0x55, + 0x5c, 0xb3, 0x0, 0xb, 0x0, 0x20, 0xb, 0x0, + 0x20, 0x6, 0x5c, 0x76, 0x39, 0xe, 0x8, 0x80, + 0x3, 0xb, 0x28, 0x8, 0xc, 0x92, 0x0, 0x8, + 0x3b, 0x74, 0x1, 0x3b, 0x72, 0x0, 0x5, 0x3b, + 0x53, 0x47, 0xb, 0xc, 0x30, 0x16, 0x9a, 0x64, + 0x90, 0xb, 0x2, 0xc2, 0x7, 0x10, 0x0, 0x5, + 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+9577 "長" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x65, 0x55, 0x55, 0xa2, 0x0, 0x0, 0x8, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x85, + 0x55, 0x58, 0x50, 0x0, 0x0, 0x8, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x85, 0x55, 0x58, + 0x70, 0x0, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x16, 0x5b, 0x85, 0x55, 0x55, 0x57, 0x90, + 0x0, 0xd, 0x0, 0x60, 0x0, 0x60, 0x0, 0x0, + 0xd, 0x0, 0x17, 0x29, 0x60, 0x0, 0x0, 0xd, + 0x0, 0x14, 0xb0, 0x0, 0x0, 0x0, 0xd, 0x37, + 0x10, 0x4c, 0x71, 0x0, 0x0, 0xd, 0x80, 0x0, + 0x0, 0x8e, 0x80, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9589 "閉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x55, + 0xd3, 0xa, 0x55, 0xb5, 0xc, 0x0, 0xb0, 0xa, + 0x0, 0xa2, 0xd, 0x55, 0xc0, 0xb, 0x55, 0xb2, + 0xd, 0x55, 0xc0, 0xc, 0x55, 0xb2, 0xc, 0x0, + 0x30, 0x24, 0x0, 0xa2, 0xc, 0x0, 0x0, 0xb1, + 0x0, 0xa2, 0xc, 0x26, 0x58, 0xe5, 0x83, 0xa2, + 0xc, 0x0, 0x2b, 0xb0, 0x0, 0xa2, 0xc, 0x2, + 0x91, 0xb0, 0x0, 0xa2, 0xc, 0x36, 0x0, 0xb0, + 0x0, 0xa2, 0xc, 0x0, 0x29, 0xd0, 0x0, 0xa2, + 0xc, 0x0, 0x0, 0x20, 0x3a, 0xe0, 0x2, 0x0, + 0x0, 0x0, 0x1, 0x10, + + /* U+958B "開" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x55, + 0xa5, 0xb, 0x55, 0xb4, 0xc, 0x0, 0x83, 0xc, + 0x0, 0xa2, 0xd, 0x55, 0xa3, 0xc, 0x55, 0xb2, + 0xd, 0x55, 0xa3, 0xc, 0x55, 0xb2, 0xc, 0x0, + 0x20, 0x5, 0x0, 0xa2, 0xc, 0x4, 0x65, 0x56, + 0x80, 0xa2, 0xc, 0x0, 0x55, 0xa, 0x0, 0xa2, + 0xc, 0x15, 0x88, 0x5c, 0x85, 0xa2, 0xc, 0x1, + 0x74, 0xa, 0x0, 0xa2, 0xc, 0x0, 0xa0, 0xa, + 0x0, 0xa2, 0xc, 0x7, 0x30, 0xa, 0x0, 0xa2, + 0xc, 0x10, 0x0, 0x1, 0x2a, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+9593 "間" */ + 0x1, 0x0, 0x10, 0x1, 0x0, 0x20, 0xd, 0x55, + 0x97, 0xb, 0x55, 0xc4, 0xc, 0x0, 0x54, 0xb, + 0x0, 0xa2, 0xd, 0x55, 0x94, 0xc, 0x55, 0xb2, + 0xd, 0x55, 0x95, 0xc, 0x55, 0xb2, 0xc, 0x0, + 0x10, 0x3, 0x0, 0xa2, 0xc, 0x0, 0xa5, 0x59, + 0x50, 0xa2, 0xc, 0x0, 0xc0, 0x7, 0x30, 0xa2, + 0xc, 0x0, 0xd5, 0x5a, 0x30, 0xa2, 0xc, 0x0, + 0xc0, 0x7, 0x30, 0xa2, 0xc, 0x0, 0xd5, 0x5a, + 0x30, 0xa2, 0xc, 0x0, 0x70, 0x4, 0x20, 0xa2, + 0xc, 0x0, 0x0, 0x0, 0x2a, 0xe0, 0x2, 0x0, + 0x0, 0x0, 0x1, 0x10, + + /* U+95A2 "関" */ + 0x1, 0x0, 0x10, 0x1, 0x0, 0x1, 0x0, 0xd5, + 0x5c, 0x30, 0xc5, 0x56, 0xc0, 0xd, 0x55, 0xc0, + 0xc, 0x55, 0x6a, 0x0, 0xc0, 0xb, 0x0, 0xb0, + 0x2, 0xa0, 0xd, 0x55, 0xc0, 0xc, 0x55, 0x6a, + 0x0, 0xc0, 0x6, 0x0, 0x71, 0x2, 0xa0, 0xc, + 0x0, 0x73, 0x29, 0x0, 0x2a, 0x0, 0xc0, 0x55, + 0x6a, 0x57, 0x32, 0xa0, 0xc, 0x0, 0x5, 0x70, + 0x3, 0x2a, 0x0, 0xc1, 0x65, 0xd8, 0x55, 0x42, + 0xa0, 0xc, 0x0, 0x67, 0x4a, 0x60, 0x2a, 0x0, + 0xc0, 0x65, 0x0, 0x6, 0x2, 0xa0, 0xc, 0x10, + 0x0, 0x0, 0x17, 0xc9, 0x0, 0x40, 0x0, 0x0, + 0x0, 0x4, 0x0, + + /* U+95DC "關" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0xb5, + 0x59, 0x60, 0xc5, 0x56, 0xc0, 0x1b, 0x55, 0x95, + 0xc, 0x55, 0x6a, 0x1, 0xa0, 0x6, 0x50, 0xb0, + 0x1, 0xa0, 0x1b, 0x55, 0x92, 0x9, 0x85, 0x6a, + 0x1, 0xa0, 0x38, 0x21, 0x82, 0x31, 0xa0, 0x1a, + 0x1a, 0x88, 0x67, 0xa5, 0x1a, 0x1, 0xa0, 0x76, + 0x84, 0x93, 0x71, 0xa0, 0x1a, 0x8, 0x37, 0x55, + 0x14, 0x1a, 0x1, 0xa0, 0xa0, 0xb4, 0x70, 0xa1, + 0xa0, 0x1a, 0x17, 0x59, 0x39, 0x5a, 0x1a, 0x1, + 0xa0, 0x6, 0x44, 0x60, 0x1, 0xa0, 0x1a, 0x2, + 0x20, 0x12, 0x5, 0xc7, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x3, 0x0, + + /* U+95F0 "闰" */ + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x20, 0x55, 0x55, 0x55, 0x90, 0x15, 0x64, 0x1, + 0x0, 0x0, 0xc, 0x2, 0xb0, 0x0, 0x0, 0x0, + 0x30, 0xc0, 0x2a, 0x17, 0x55, 0xb5, 0x67, 0xc, + 0x2, 0xa0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x2a, + 0x0, 0x0, 0xc0, 0x42, 0xc, 0x2, 0xa0, 0x36, + 0x5d, 0x55, 0x30, 0xc0, 0x2a, 0x0, 0x0, 0xc0, + 0x0, 0xc, 0x2, 0xa0, 0x0, 0xc, 0x0, 0x60, + 0xc0, 0x2a, 0x46, 0x55, 0x55, 0x55, 0x2c, 0x2, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x29, 0x0, + 0x0, 0x0, 0x5, 0xd8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+9633 "阳" */ + 0x65, 0x58, 0x51, 0x0, 0x0, 0x10, 0x92, 0xb, + 0x3b, 0x55, 0x55, 0xd0, 0x92, 0x17, 0xb, 0x0, + 0x0, 0xb0, 0x92, 0x60, 0xb, 0x0, 0x0, 0xb0, + 0x92, 0x60, 0xb, 0x0, 0x0, 0xb0, 0x92, 0x9, + 0xb, 0x55, 0x55, 0xb0, 0x92, 0x6, 0x6b, 0x0, + 0x0, 0xb0, 0x92, 0x7, 0x7b, 0x0, 0x0, 0xb0, + 0x95, 0xbe, 0x1b, 0x0, 0x0, 0xb0, 0x92, 0x31, + 0xb, 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb, 0x55, + 0x55, 0xc0, 0x92, 0x0, 0x8, 0x0, 0x0, 0x70, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9644 "附" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x85, + 0x93, 0xb, 0x40, 0xc, 0x0, 0x1a, 0xa, 0x1, + 0xb0, 0x0, 0xb0, 0x1, 0xa0, 0x80, 0x73, 0x0, + 0xb, 0x0, 0x1a, 0x52, 0xd, 0x24, 0x55, 0xc8, + 0x31, 0xa3, 0x15, 0xa1, 0x10, 0xb, 0x0, 0x1a, + 0x8, 0x29, 0x14, 0x0, 0xb0, 0x1, 0xa0, 0x72, + 0x91, 0x3b, 0xb, 0x0, 0x1a, 0x7, 0x49, 0x10, + 0x50, 0xb0, 0x1, 0xba, 0xc0, 0x91, 0x0, 0xb, + 0x0, 0x1a, 0x10, 0x9, 0x10, 0x0, 0xb0, 0x1, + 0xa0, 0x0, 0x91, 0x2, 0x1b, 0x0, 0x19, 0x0, + 0x8, 0x10, 0x2c, 0x60, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+964D "降" */ + 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x2, 0xa5, + 0x89, 0x7, 0xa5, 0x59, 0x10, 0x1a, 0xa, 0x20, + 0xb2, 0x3, 0xb0, 0x1, 0xa0, 0x90, 0x53, 0x71, + 0xb0, 0x0, 0x1a, 0x32, 0x13, 0x3, 0xe2, 0x0, + 0x1, 0xa1, 0x40, 0x2, 0x94, 0xa6, 0x20, 0x1a, + 0x6, 0x35, 0x50, 0xa1, 0x59, 0x11, 0xa0, 0x2a, + 0x36, 0x5c, 0x58, 0x50, 0x1a, 0x3, 0xa5, 0x30, + 0xb0, 0x0, 0x1, 0xb9, 0xe3, 0xb1, 0xb, 0x0, + 0x30, 0x1a, 0x1, 0x28, 0x55, 0xc5, 0x57, 0x21, + 0xa0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x1a, 0x0, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x3, 0x0, 0x0, + + /* U+9650 "限" */ + 0x75, 0x5a, 0x8, 0x55, 0x5a, 0x40, 0xa, 0x12, + 0x90, 0xb0, 0x0, 0xa1, 0x0, 0xa1, 0x62, 0xb, + 0x0, 0xa, 0x10, 0xa, 0x16, 0x0, 0xd5, 0x55, + 0xc1, 0x0, 0xa1, 0x50, 0xb, 0x0, 0xa, 0x20, + 0xa, 0x12, 0x50, 0xd6, 0x55, 0xc2, 0x0, 0xa1, + 0xa, 0xb, 0x14, 0x2, 0x90, 0xa, 0x10, 0xb0, + 0xb0, 0x71, 0xa5, 0x0, 0xa5, 0xbd, 0xb, 0x7, + 0x70, 0x0, 0xa, 0x14, 0x10, 0xb0, 0x1b, 0x20, + 0x0, 0xa1, 0x0, 0xd, 0x82, 0x2d, 0x93, 0xa, + 0x10, 0x1, 0xc1, 0x0, 0x1a, 0x40, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9662 "院" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x65, 0x58, + 0x0, 0xa, 0x10, 0x0, 0xa0, 0x48, 0x55, 0x5b, + 0x65, 0x83, 0xa0, 0x71, 0xb0, 0x0, 0x0, 0x80, + 0xa0, 0x60, 0x40, 0x0, 0x5, 0x0, 0xa0, 0x40, + 0x5, 0x55, 0x55, 0x0, 0xa0, 0x53, 0x0, 0x0, + 0x0, 0x40, 0xa0, 0xb, 0x56, 0xb5, 0xb5, 0x71, + 0xa0, 0xc, 0x0, 0xb0, 0xb0, 0x0, 0xa3, 0xbb, + 0x1, 0xa0, 0xb0, 0x0, 0xa0, 0x30, 0x6, 0x60, + 0xb0, 0x4, 0xa0, 0x0, 0x1a, 0x0, 0xb0, 0x17, + 0xa0, 0x3, 0x70, 0x0, 0xaa, 0xba, 0x40, 0x11, + 0x0, 0x0, 0x0, 0x0, + + /* U+9664 "除" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x6, 0x55, + 0xa1, 0x4, 0xe1, 0x0, 0x0, 0xa0, 0x2a, 0x0, + 0xc2, 0x70, 0x0, 0xa, 0x7, 0x20, 0x66, 0x4, + 0x80, 0x0, 0xa0, 0x60, 0x38, 0x0, 0x6, 0xc5, + 0xa, 0x4, 0x25, 0x46, 0x85, 0x83, 0x70, 0xa0, + 0x54, 0x0, 0xb, 0x0, 0x0, 0xa, 0x0, 0xc3, + 0x55, 0xc5, 0x5b, 0x20, 0xa0, 0x1c, 0x12, 0xb, + 0x0, 0x0, 0xa, 0x4e, 0x50, 0xd3, 0xb0, 0x61, + 0x0, 0xa0, 0x0, 0x85, 0xb, 0x1, 0xb2, 0xa, + 0x0, 0x64, 0x0, 0xb0, 0x5, 0x90, 0xb0, 0x1, + 0x4, 0xbd, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+9678 "陸" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7, 0x55, + 0x91, 0x0, 0xc1, 0x0, 0x0, 0xb0, 0xb, 0x0, + 0xb, 0x0, 0x60, 0xb, 0x5, 0x32, 0x65, 0xc5, + 0x55, 0x0, 0xb0, 0x50, 0x0, 0xb, 0x0, 0x3, + 0xb, 0x5, 0x16, 0x58, 0x65, 0x55, 0x60, 0xb0, + 0x34, 0x7, 0xa1, 0x6, 0x91, 0xb, 0x0, 0xb5, + 0x50, 0xb1, 0x5, 0x70, 0xb0, 0x2b, 0x10, 0xb, + 0x0, 0x0, 0xb, 0x6d, 0x23, 0x65, 0xc5, 0x69, + 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x20, 0xb0, 0x6, + 0x55, 0x58, 0x55, 0x77, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+967D "陽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x55, + 0xb2, 0xa5, 0x55, 0x5c, 0x0, 0xb0, 0x1b, 0xb, + 0x0, 0x0, 0xb0, 0xb, 0x6, 0x20, 0xb5, 0x55, + 0x5b, 0x0, 0xb0, 0x50, 0xb, 0x55, 0x55, 0xc0, + 0xb, 0x6, 0x0, 0x50, 0x0, 0x3, 0x10, 0xb0, + 0x27, 0x65, 0x85, 0x55, 0x59, 0xb, 0x0, 0xb0, + 0x2b, 0x0, 0x0, 0x30, 0xb1, 0x1d, 0x1a, 0x5d, + 0x6c, 0x6b, 0xb, 0x4d, 0x67, 0x17, 0x57, 0x53, + 0x80, 0xb0, 0x2, 0x5, 0x62, 0xa0, 0x56, 0xb, + 0x0, 0x4, 0x22, 0x91, 0x9, 0x30, 0xa0, 0x0, + 0x4, 0x60, 0x4b, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x30, 0x0, + + /* U+968E "階" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x9, 0x55, + 0xb5, 0xb0, 0xc, 0x0, 0x0, 0xa0, 0xb, 0x1a, + 0x1, 0xb0, 0xb5, 0xa, 0x6, 0x21, 0xc6, 0x5c, + 0x82, 0x0, 0xa0, 0x60, 0x1a, 0x0, 0xb0, 0x4, + 0xa, 0x6, 0x1, 0xc6, 0x2b, 0x0, 0x90, 0xa0, + 0x18, 0x19, 0x4, 0x49, 0x97, 0xa, 0x0, 0xb0, + 0x11, 0x80, 0x2, 0x0, 0xa4, 0x8d, 0xc, 0x55, + 0x55, 0xd0, 0xa, 0x5, 0x10, 0xb0, 0x0, 0xb, + 0x0, 0xa0, 0x0, 0xc, 0x55, 0x55, 0xb0, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xa0, 0x0, + 0xc, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, + + /* U+969B "際" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x7, 0x55, + 0xa1, 0x86, 0x24, 0x0, 0x20, 0xb0, 0x3a, 0xb, + 0x5c, 0x85, 0x97, 0xb, 0x8, 0x17, 0x75, 0xa3, + 0x38, 0x0, 0xb1, 0x53, 0x75, 0x93, 0xb, 0x20, + 0xb, 0x6, 0x0, 0x57, 0x0, 0x3c, 0x40, 0xb0, + 0x45, 0x35, 0x55, 0x58, 0x58, 0x1b, 0x0, 0xc1, + 0x1, 0x0, 0x0, 0x0, 0xb3, 0x5b, 0x26, 0x55, + 0x75, 0x77, 0xb, 0x8, 0x10, 0x13, 0xb, 0x20, + 0x0, 0xb0, 0x0, 0xb, 0x60, 0xb1, 0xa2, 0xb, + 0x0, 0x17, 0x20, 0xb, 0x2, 0xe0, 0xb0, 0x3, + 0x0, 0x6d, 0x80, 0x3, 0x1, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x0, + + /* U+969C "障" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x6, 0x45, + 0x70, 0x0, 0xc0, 0x1, 0x0, 0xc0, 0x77, 0x17, + 0x57, 0x57, 0x90, 0xb, 0x9, 0x0, 0x19, 0x4, + 0xa0, 0x0, 0xb0, 0x61, 0x33, 0xa3, 0x83, 0x49, + 0xb, 0x5, 0x3, 0x42, 0x22, 0x25, 0x20, 0xb0, + 0x54, 0xc, 0x55, 0x55, 0xd1, 0xb, 0x0, 0xc0, + 0xc5, 0x55, 0x5c, 0x0, 0xb0, 0xe, 0xb, 0x0, + 0x0, 0xb0, 0xb, 0x5d, 0x80, 0xa5, 0xc5, 0x59, + 0x0, 0xb0, 0x12, 0x65, 0x5c, 0x55, 0x5b, 0x1b, + 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x30, 0x0, 0x0, + + /* U+96A3 "隣" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7, 0x56, + 0x80, 0x71, 0x94, 0xa, 0x0, 0xb0, 0x74, 0x2, + 0x89, 0x27, 0x40, 0xb, 0x8, 0x4, 0x66, 0xc8, + 0x85, 0x70, 0xb3, 0x10, 0x2, 0xaa, 0x65, 0x0, + 0xb, 0x14, 0x5, 0x60, 0x92, 0x5c, 0x70, 0xb0, + 0x74, 0x14, 0x6, 0x10, 0x31, 0xb, 0x3, 0x86, + 0x92, 0x10, 0x19, 0x20, 0xb5, 0x97, 0xa5, 0xc4, + 0x86, 0xb5, 0xb, 0x6, 0x78, 0x1b, 0x3b, 0x19, + 0x0, 0xb0, 0x0, 0x49, 0x37, 0x65, 0xb7, 0x1b, + 0x0, 0x4, 0x70, 0x0, 0x19, 0x0, 0xb0, 0x4, + 0x50, 0x0, 0x1, 0x90, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+96A8 "隨" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x8, 0x5a, + 0x40, 0x0, 0xd, 0x0, 0x20, 0xa0, 0xb2, 0x64, + 0x69, 0x95, 0x55, 0xa, 0x35, 0xb, 0x3, 0xb5, + 0x78, 0x30, 0xa5, 0x0, 0x13, 0x62, 0x3a, 0x27, + 0xa, 0x33, 0x2, 0x2, 0x42, 0x24, 0x20, 0xa0, + 0x95, 0xb5, 0xb, 0x55, 0xa3, 0xa, 0x8, 0x39, + 0x10, 0xc5, 0x5a, 0x10, 0xb7, 0xc1, 0x91, 0xa, + 0x0, 0x81, 0xa, 0x33, 0x9, 0x10, 0xc5, 0x5a, + 0x10, 0xa0, 0x0, 0x91, 0xa, 0x4, 0xa1, 0xa, + 0x0, 0x83, 0x65, 0x30, 0x17, 0x0, 0xa0, 0x26, + 0x0, 0x4a, 0xdc, 0xdb, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+96BB "隻" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc1, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x70, 0x4, 0x0, 0x8, 0x0, 0x0, 0x5f, 0x55, + 0x5d, 0x55, 0x55, 0x10, 0x3, 0x5b, 0x55, 0x5d, + 0x55, 0x83, 0x0, 0x2, 0xb, 0x0, 0xc, 0x0, + 0x33, 0x0, 0x0, 0xb, 0x55, 0x5d, 0x55, 0x54, + 0x0, 0x0, 0xb, 0x44, 0x49, 0x44, 0x49, 0x30, + 0x0, 0x36, 0x55, 0x55, 0x58, 0x50, 0x0, 0x0, + 0x10, 0x61, 0x0, 0x3c, 0x30, 0x0, 0x0, 0x0, + 0x8, 0x57, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xcc, 0x62, 0x0, 0x0, 0x2, 0x46, 0x72, 0x0, + 0x49, 0xbc, 0xb1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+96C6 "集" */ + 0x0, 0x0, 0x50, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xc1, 0x1c, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x75, 0x59, 0x55, 0x5a, 0x40, 0x0, 0x5d, 0x0, + 0xb, 0x0, 0x0, 0x0, 0x2, 0x7c, 0x55, 0x5c, + 0x55, 0x77, 0x0, 0x15, 0xb, 0x0, 0xb, 0x0, + 0x33, 0x0, 0x0, 0xc, 0x55, 0x5c, 0x55, 0x54, + 0x0, 0x0, 0xc, 0x55, 0x5a, 0x55, 0x5a, 0x20, + 0x0, 0x7, 0x0, 0x1b, 0x0, 0x0, 0x30, 0x16, + 0x55, 0x57, 0xbc, 0x85, 0x55, 0x73, 0x0, 0x0, + 0x3b, 0x2a, 0x35, 0x0, 0x0, 0x0, 0x7, 0x70, + 0x1a, 0x4, 0xb5, 0x0, 0x4, 0x61, 0x0, 0x1b, + 0x0, 0x19, 0xe3, 0x10, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+96D1 "雑" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x76, 0x70, 0x0, 0x3, 0x6c, + 0x6a, 0x0, 0xc1, 0xc0, 0x0, 0x0, 0x28, 0x47, + 0x1, 0xc5, 0x75, 0xb1, 0x0, 0x83, 0x74, 0x57, + 0xa0, 0xb0, 0x0, 0x3, 0x61, 0x4a, 0x99, 0xa0, + 0xb0, 0x0, 0x3, 0x5, 0x70, 0x32, 0xc5, 0xc5, + 0x80, 0x2, 0x37, 0x83, 0x81, 0xa0, 0xb0, 0x0, + 0x2, 0x26, 0x72, 0x21, 0xa0, 0xb0, 0x40, 0x0, + 0xb6, 0x95, 0x1, 0xc5, 0xc5, 0x50, 0x3, 0x65, + 0x67, 0x71, 0xa0, 0xb0, 0x0, 0x6, 0x5, 0x60, + 0x51, 0xa0, 0xb0, 0x51, 0x0, 0x3c, 0x50, 0x1, + 0xc5, 0x55, 0x52, 0x0, 0x2, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+96D6 "雖" */ + 0x1, 0x10, 0x4, 0x1, 0xb2, 0x70, 0x0, 0x2, + 0xa5, 0x5c, 0x5, 0x90, 0x94, 0x0, 0x1, 0x70, + 0xa, 0x9, 0x65, 0x65, 0x90, 0x2, 0xa8, 0x5a, + 0xe, 0x10, 0xa0, 0x0, 0x0, 0x1a, 0x0, 0x5a, + 0x10, 0xa0, 0x0, 0x9, 0x5b, 0x58, 0x49, 0x65, + 0xc6, 0x70, 0xa, 0xa, 0x4, 0x29, 0x10, 0xa0, + 0x0, 0xa, 0xa, 0x4, 0x29, 0x10, 0xa1, 0x30, + 0x8, 0x5b, 0x56, 0x19, 0x65, 0xc5, 0x40, 0x0, + 0xa, 0x5, 0x9, 0x10, 0xa0, 0x0, 0x4, 0x6c, + 0x78, 0x49, 0x10, 0xa0, 0x60, 0x9, 0x52, 0x2, + 0x6a, 0x65, 0x55, 0x51, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, + + /* U+96D9 "雙" */ + 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x67, 0x92, 0x5, 0x87, 0x50, 0x0, 0x0, 0xd5, + 0x67, 0x69, 0x68, 0x69, 0x20, 0x7, 0xb0, 0xa0, + 0xf, 0xa, 0x1, 0x0, 0x13, 0xc5, 0xc7, 0x6b, + 0x5c, 0x57, 0x0, 0x0, 0xa0, 0xa2, 0x1a, 0xa, + 0x3, 0x0, 0x0, 0xc5, 0xc5, 0x2a, 0x5c, 0x55, + 0x0, 0x0, 0xc5, 0x95, 0x6b, 0x5b, 0x58, 0x30, + 0x0, 0x40, 0x0, 0x3, 0x0, 0x30, 0x0, 0x0, + 0x66, 0x95, 0x55, 0x5d, 0x80, 0x0, 0x0, 0x0, + 0x26, 0x2, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xcd, 0x20, 0x0, 0x0, 0x0, 0x15, 0x65, 0x12, + 0x8a, 0x98, 0x72, 0x4, 0x30, 0x0, 0x0, 0x0, + 0x14, 0x30, + + /* U+96E2 "離" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x80, 0x10, 0x84, 0x70, 0x0, 0x6, 0x56, + 0x85, 0x91, 0xa0, 0x83, 0x0, 0x4, 0x34, 0x85, + 0x30, 0xc5, 0x66, 0x90, 0x7, 0x26, 0xb1, 0x95, + 0xb0, 0xb0, 0x0, 0x7, 0x51, 0x52, 0x95, 0xb0, + 0xb0, 0x0, 0x8, 0x57, 0x85, 0x80, 0xc5, 0xc6, + 0x60, 0x3, 0x19, 0x51, 0x60, 0xb0, 0xb0, 0x0, + 0xa, 0x3a, 0x53, 0xc0, 0xb0, 0xb0, 0x20, 0xa, + 0x65, 0x75, 0xa0, 0xd5, 0xc5, 0x40, 0xa, 0x54, + 0x13, 0xa0, 0xb0, 0xb0, 0x0, 0xa, 0x0, 0x0, + 0xa0, 0xb0, 0xb0, 0x40, 0xa, 0x0, 0x3b, 0x80, + 0xd5, 0x55, 0x50, 0x2, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+96E3 "難" */ + 0x0, 0x10, 0x0, 0x0, 0x40, 0x10, 0x0, 0x0, + 0xa0, 0x74, 0x3, 0xe1, 0x93, 0x0, 0x15, 0xb5, + 0x97, 0x87, 0x60, 0x35, 0x20, 0x1, 0x90, 0x73, + 0xb, 0x65, 0xa6, 0x80, 0x0, 0x8a, 0x82, 0x2e, + 0x20, 0xb0, 0x0, 0x6, 0x5c, 0x5a, 0x69, 0x20, + 0xb0, 0x0, 0x9, 0x1a, 0xa, 0x9, 0x65, 0xc6, + 0x40, 0x8, 0x5c, 0x58, 0x9, 0x20, 0xb0, 0x0, + 0x4, 0x5c, 0x58, 0x19, 0x30, 0xb2, 0x20, 0x15, + 0x5c, 0x56, 0x79, 0x64, 0xc4, 0x20, 0x1, 0x9, + 0x11, 0x9, 0x20, 0xb0, 0x0, 0x0, 0x83, 0xa, + 0x49, 0x20, 0xb0, 0x40, 0x6, 0x30, 0x1, 0x49, + 0x65, 0x65, 0x60, 0x10, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+96E8 "雨" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x45, 0x55, + 0x5c, 0x55, 0x55, 0x54, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x20, 0xc, 0x55, 0x5c, 0x55, 0x55, 0xe0, + 0xc, 0x26, 0xb, 0x6, 0x0, 0xc0, 0xc, 0x8, + 0x7b, 0x4, 0xb0, 0xc0, 0xc, 0x0, 0x2b, 0x0, + 0x30, 0xc0, 0xc, 0x33, 0xb, 0x3, 0x0, 0xc0, + 0xc, 0xb, 0x4b, 0x6, 0xa0, 0xc0, 0xc, 0x1, + 0x2b, 0x0, 0x50, 0xc0, 0xc, 0x0, 0xb, 0x0, + 0x45, 0xb0, 0xa, 0x0, 0x7, 0x0, 0x1b, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+96EA "雪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x46, 0x55, 0x65, 0x55, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x73, 0x0, 0x0, 0x10, 0x4, 0x75, 0x55, + 0xa7, 0x55, 0x58, 0xb0, 0xb, 0x35, 0x53, 0x73, + 0x45, 0x44, 0x0, 0x3, 0x0, 0x0, 0x74, 0x0, + 0x0, 0x0, 0x0, 0x5, 0x53, 0x84, 0x45, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x40, 0x0, + 0x0, 0x46, 0x55, 0x55, 0x55, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x16, + 0x55, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x65, 0x55, 0x55, + 0x55, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x0, + + /* U+96F2 "雲" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x7, + 0x55, 0x77, 0x55, 0x83, 0x0, 0x3, 0x0, 0x5, + 0x60, 0x0, 0x12, 0x2, 0xa5, 0x55, 0x89, 0x55, + 0x59, 0xb0, 0x93, 0x55, 0x35, 0x63, 0x54, 0x50, + 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0x0, 0x0, + 0x55, 0x34, 0x44, 0x54, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x70, 0x0, 0x1, 0x65, 0x55, 0x55, + 0x55, 0x20, 0x3, 0x65, 0x55, 0x65, 0x55, 0x58, + 0x80, 0x0, 0x0, 0xa8, 0x2, 0x20, 0x0, 0x0, + 0x5, 0x71, 0x0, 0x6, 0xa1, 0x0, 0x6, 0xeb, + 0x98, 0x65, 0x57, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, + + /* U+96FB "電" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x6, + 0x55, 0x59, 0x55, 0x91, 0x0, 0x7, 0x55, 0x56, + 0xc5, 0x55, 0x69, 0x3, 0x90, 0x0, 0x1a, 0x0, + 0x5, 0x60, 0x32, 0x45, 0x42, 0xa3, 0x55, 0x30, + 0x0, 0x4, 0x54, 0x29, 0x35, 0x50, 0x0, 0x0, + 0x20, 0x0, 0x0, 0x3, 0x0, 0x0, 0xc, 0x55, + 0x6b, 0x55, 0xc3, 0x0, 0x0, 0xc5, 0x56, 0xc5, + 0x5c, 0x0, 0x0, 0xb, 0x0, 0x1a, 0x0, 0xb0, + 0x0, 0x0, 0xc5, 0x56, 0xc5, 0x5c, 0x3, 0x0, + 0x5, 0x0, 0x1a, 0x0, 0x30, 0x70, 0x0, 0x0, + 0x0, 0xe9, 0x99, 0x9d, 0x10, + + /* U+9700 "需" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x36, 0x55, 0x77, 0x55, 0x85, 0x0, 0x1, 0x65, + 0x55, 0x99, 0x55, 0x56, 0x80, 0x8, 0x40, 0x0, + 0x66, 0x0, 0x6, 0x50, 0x4, 0x4, 0x52, 0x66, + 0x45, 0x31, 0x0, 0x0, 0x5, 0x52, 0x66, 0x45, + 0x30, 0x0, 0x3, 0x55, 0x55, 0x55, 0x55, 0x5b, + 0x40, 0x1, 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x85, 0x59, 0x55, 0x75, 0x5b, 0x0, 0x0, + 0xb1, 0xb, 0x0, 0xb0, 0x1a, 0x0, 0x0, 0xb1, + 0xb, 0x0, 0xb0, 0x1a, 0x0, 0x0, 0xb1, 0xb, + 0x0, 0xb0, 0x1a, 0x0, 0x0, 0xb0, 0x7, 0x0, + 0x52, 0xb8, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+9707 "震" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x26, 0x55, 0x95, 0x56, 0x80, 0x0, 0x0, 0x85, + 0x55, 0xc5, 0x55, 0x59, 0x40, 0x8, 0x50, 0x0, + 0xb0, 0x0, 0x9, 0x10, 0x3, 0x5, 0x52, 0xb0, + 0x55, 0x30, 0x0, 0x0, 0x24, 0x42, 0x80, 0x44, + 0x52, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x55, 0x65, + 0x0, 0x0, 0xb0, 0x65, 0x55, 0x55, 0x90, 0x0, + 0x0, 0xc5, 0x55, 0x55, 0x55, 0x5a, 0x50, 0x0, + 0xb0, 0xb0, 0x42, 0x2, 0x80, 0x0, 0x0, 0xa0, + 0xb0, 0x8, 0x57, 0x20, 0x0, 0x6, 0x30, 0xb3, + 0x51, 0x99, 0x30, 0x0, 0x15, 0x0, 0xb6, 0x0, + 0x3, 0xaf, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9752 "青" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x1, 0x20, 0x6, 0x55, 0x55, + 0xd5, 0x55, 0x88, 0x0, 0x4, 0x55, 0x5d, 0x55, + 0x6a, 0x0, 0x0, 0x10, 0x0, 0xc0, 0x0, 0x2, + 0x3, 0x65, 0x55, 0x59, 0x55, 0x55, 0x96, 0x0, + 0x7, 0x55, 0x55, 0x58, 0x20, 0x0, 0x0, 0xc0, + 0x0, 0x0, 0xb1, 0x0, 0x0, 0xc, 0x55, 0x55, + 0x5c, 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb1, + 0x0, 0x0, 0xc, 0x55, 0x55, 0x5c, 0x10, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, + 0x0, 0x3, 0xae, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x1, 0x10, 0x0, + + /* U+9759 "静" */ + 0x0, 0x3, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0xb, 0x11, 0x1, 0xc1, 0x10, 0x0, 0x7, 0x5c, + 0x57, 0x48, 0x75, 0xd2, 0x0, 0x4, 0x5c, 0x58, + 0x36, 0x2, 0x50, 0x0, 0x1, 0xa, 0x0, 0x36, + 0x69, 0x5c, 0x10, 0x26, 0x58, 0x57, 0x80, 0xa, + 0xa, 0x0, 0x5, 0x55, 0x59, 0x35, 0x5b, 0x5c, + 0x90, 0x9, 0x10, 0xa, 0x1, 0xa, 0xa, 0x0, + 0x9, 0x65, 0x5a, 0x1, 0x1a, 0x1b, 0x0, 0x9, + 0x65, 0x5a, 0x5, 0x4b, 0x36, 0x0, 0x9, 0x10, + 0xa, 0x0, 0xa, 0x0, 0x0, 0x9, 0x10, 0xa, + 0x0, 0x9, 0x0, 0x0, 0x9, 0x14, 0xc7, 0x5, + 0xc7, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x20, + 0x0, 0x0, + + /* U+975E "非" */ + 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x10, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0x0, 0x4, 0x55, 0x5d, + 0x0, 0xd5, 0x57, 0x80, 0x0, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, + 0x0, 0x0, 0x1, 0x75, 0x5d, 0x0, 0xd5, 0x58, + 0x40, 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0x6, + 0x55, 0x5d, 0x0, 0xd5, 0x55, 0xb1, 0x0, 0x0, + 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x10, + 0x0, 0x0, + + /* U+9762 "面" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, + 0x55, 0x55, 0x75, 0x55, 0x56, 0xc1, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x10, 0x4, + 0x30, 0x0, 0x2, 0x0, 0x0, 0xd5, 0x5b, 0x55, + 0xb5, 0x5d, 0x10, 0x0, 0xc0, 0xb, 0x0, 0xb0, + 0xc, 0x0, 0x0, 0xc0, 0xb, 0x55, 0xc0, 0xc, + 0x0, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, + 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, + 0xc0, 0xb, 0x55, 0xc0, 0xc, 0x0, 0x0, 0xc0, + 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xd5, 0x5c, + 0x55, 0xd5, 0x5d, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9769 "革" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0x0, 0x38, 0x1, 0x0, 0x1, 0x65, + 0x5c, 0x55, 0x6a, 0x59, 0x50, 0x0, 0x0, 0x1b, + 0x0, 0x27, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x5a, + 0x65, 0x0, 0x0, 0x0, 0x3, 0x0, 0xc, 0x0, + 0x30, 0x0, 0x0, 0xd, 0x55, 0x5d, 0x55, 0xb4, + 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0x92, 0x0, + 0x0, 0xc, 0x55, 0x5d, 0x55, 0x91, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x50, 0x6, 0x55, + 0x55, 0x5d, 0x55, 0x56, 0x71, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+9774 "靴" */ + 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0x84, 0x5, 0x8a, 0x10, 0x0, 0x16, 0xb5, + 0xa9, 0x49, 0x3b, 0x0, 0x0, 0x0, 0xa0, 0x82, + 0xb, 0xa, 0x4, 0x50, 0x1, 0xaa, 0x82, 0x28, + 0xa, 0xb, 0x20, 0x5, 0x5c, 0x57, 0x7b, 0xa, + 0x55, 0x0, 0x9, 0x1a, 0xb, 0x4a, 0xa, 0x80, + 0x0, 0x9, 0x1a, 0xb, 0xa, 0xd, 0x10, 0x0, + 0x8, 0x5c, 0x57, 0xa, 0x5a, 0x10, 0x0, 0x0, + 0xa, 0x4, 0x1a, 0x9, 0x10, 0x0, 0x26, 0x5c, + 0x55, 0x2a, 0x9, 0x10, 0x40, 0x0, 0xb, 0x0, + 0xa, 0x9, 0x10, 0x70, 0x0, 0xb, 0x0, 0xb, + 0x6, 0xba, 0xc0, 0x0, 0x4, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+97F3 "音" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x65, + 0x55, 0x87, 0x55, 0x98, 0x0, 0x0, 0x0, 0x53, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, + 0x84, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x70, + 0x5, 0x70, 0x26, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x50, 0x0, 0x7, 0x55, 0x55, 0x56, 0xa0, 0x0, + 0x0, 0x9, 0x20, 0x0, 0x2, 0x90, 0x0, 0x0, + 0x9, 0x65, 0x55, 0x56, 0x90, 0x0, 0x0, 0x9, + 0x20, 0x0, 0x2, 0x90, 0x0, 0x0, 0xa, 0x65, + 0x55, 0x56, 0xa0, 0x0, 0x0, 0x9, 0x20, 0x0, + 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+97FF "響" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x2, + 0xa0, 0x66, 0x76, 0x54, 0x71, 0x1, 0x71, 0x49, + 0x0, 0xa9, 0x18, 0x0, 0xa6, 0x93, 0xa5, 0x5a, + 0x95, 0x0, 0x2, 0x62, 0x9a, 0x57, 0x59, 0x8, + 0x0, 0x46, 0x93, 0xa6, 0x67, 0x94, 0xa1, 0x0, + 0x67, 0x4, 0x71, 0x18, 0x14, 0x0, 0x46, 0x55, + 0x57, 0x76, 0x5a, 0x0, 0x0, 0x0, 0x47, 0x2, + 0xa0, 0x1, 0x0, 0x65, 0x55, 0x65, 0x75, 0x55, + 0x91, 0x0, 0xa, 0x55, 0x55, 0x5b, 0x20, 0x0, + 0x0, 0xa5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0xa, + 0x55, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x20, 0x0, + + /* U+9803 "頃" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, + 0x0, 0x46, 0x57, 0x55, 0xa3, 0xd, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x8, 0x67, + 0x55, 0xb0, 0xb, 0x0, 0x10, 0xb0, 0x0, 0xb, + 0x0, 0xc5, 0x65, 0xc, 0x55, 0x55, 0xb0, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xb0, 0x0, + 0xc, 0x55, 0x55, 0xb0, 0xb, 0x0, 0x20, 0xb0, + 0x0, 0xb, 0x0, 0xb2, 0x82, 0xd, 0x55, 0x55, + 0xb0, 0x1f, 0xa0, 0x0, 0x1a, 0x23, 0x20, 0x0, + 0x40, 0x0, 0x7, 0x70, 0xa, 0x50, 0x0, 0x0, + 0x5, 0x30, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9805 "項" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x46, 0x56, 0x55, 0xb3, 0x5, 0x67, + 0x77, 0x0, 0xc, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x7, 0x68, 0x55, 0x90, 0x0, 0xb, 0x0, 0xc, + 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xd, 0x55, + 0x55, 0xb0, 0x0, 0xb, 0x0, 0xb, 0x0, 0x0, + 0xb0, 0x0, 0xb, 0x0, 0xc, 0x55, 0x55, 0xb0, + 0x0, 0xb, 0x3, 0xb, 0x0, 0x0, 0xb0, 0x0, + 0x5d, 0x61, 0xd, 0x55, 0x55, 0xb0, 0x1e, 0x70, + 0x0, 0x2, 0x82, 0x31, 0x10, 0x0, 0x0, 0x0, + 0x6, 0x80, 0xa, 0x40, 0x0, 0x0, 0x0, 0x54, + 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9808 "須" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0x45, 0x56, 0x55, 0xb3, 0x0, 0x8, + 0x70, 0x0, 0xc, 0x0, 0x0, 0x0, 0x66, 0x0, + 0x7, 0x68, 0x55, 0x90, 0x5, 0x20, 0x10, 0xb, + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x98, 0xc, 0x55, + 0x55, 0xb0, 0x0, 0x7, 0x80, 0xb, 0x0, 0x0, + 0xb0, 0x0, 0x64, 0x0, 0xc, 0x55, 0x55, 0xb0, + 0x3, 0x0, 0x7, 0xb, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x6b, 0x1d, 0x55, 0x55, 0xb0, 0x0, 0x6, + 0x80, 0x2, 0x61, 0x31, 0x10, 0x0, 0x64, 0x0, + 0x5, 0xa1, 0xa, 0x40, 0x2, 0x0, 0x0, 0x56, + 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9817 "頗" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x26, 0x55, 0x55, 0xb3, 0x0, 0x0, + 0xa0, 0x0, 0xc, 0x10, 0x0, 0x2, 0xa4, 0xc5, + 0xa5, 0x5a, 0x55, 0x91, 0x1, 0x90, 0xa5, 0x2b, + 0x0, 0x0, 0xb0, 0x1, 0x90, 0xa2, 0xb, 0x55, + 0x55, 0xc0, 0x1, 0xb5, 0x98, 0x6a, 0x0, 0x0, + 0xb0, 0x2, 0x80, 0x8, 0x1a, 0x55, 0x55, 0xc0, + 0x4, 0x65, 0x1a, 0xa, 0x0, 0x0, 0xb0, 0x5, + 0x30, 0xb6, 0xb, 0x55, 0x55, 0xc0, 0x7, 0x3, + 0x9c, 0x3, 0x63, 0x21, 0x20, 0x6, 0x27, 0x7, + 0x13, 0xb1, 0x9, 0x50, 0x12, 0x30, 0x0, 0x37, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x10, + + /* U+9818 "領" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x10, 0x56, 0x56, 0x55, 0xb3, 0x0, 0x2c, + 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, 0x83, 0x68, + 0x7, 0x68, 0x55, 0x90, 0x1, 0x92, 0xa, 0x4b, + 0x0, 0x0, 0xb0, 0x7, 0x16, 0x51, 0xc, 0x55, + 0x55, 0xb0, 0x22, 0x0, 0x70, 0xb, 0x0, 0x0, + 0xb0, 0x2, 0x65, 0x5d, 0x2b, 0x55, 0x55, 0xb0, + 0x0, 0x0, 0x47, 0xb, 0x0, 0x0, 0xb0, 0x1, + 0x20, 0x80, 0xc, 0x55, 0x55, 0xb0, 0x0, 0x6a, + 0x20, 0x2, 0x82, 0x22, 0x10, 0x0, 0x9, 0x80, + 0x6, 0x80, 0x8, 0x60, 0x0, 0x0, 0x60, 0x54, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+982D "頭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x36, 0x55, 0x55, 0xb1, 0x16, 0x55, + 0x55, 0x20, 0xc, 0x0, 0x0, 0x2, 0x0, 0x4, + 0x6, 0x57, 0x44, 0x80, 0xa, 0x65, 0x5d, 0xc, + 0x0, 0x0, 0xb0, 0xa, 0x10, 0xb, 0xc, 0x55, + 0x55, 0xb0, 0xa, 0x55, 0x5b, 0xb, 0x0, 0x0, + 0xb0, 0x4, 0x0, 0x12, 0xb, 0x55, 0x55, 0xb0, + 0x3, 0x20, 0x67, 0xb, 0x0, 0x0, 0xb0, 0x0, + 0xc0, 0x90, 0xc, 0x55, 0x55, 0xb0, 0x0, 0x60, + 0x73, 0x12, 0x82, 0x13, 0x10, 0x2c, 0xa8, 0x41, + 0x6, 0x90, 0x6, 0x80, 0x2, 0x0, 0x0, 0x55, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+983C "頼" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x36, 0x56, 0x55, 0xb1, 0x1, 0x1b, + 0x16, 0x10, 0xc, 0x10, 0x0, 0x5, 0x3b, 0x33, + 0x26, 0x59, 0x55, 0x90, 0x3, 0x1a, 0x14, 0xc, + 0x0, 0x0, 0xb0, 0xa, 0x4b, 0x4c, 0x1b, 0x55, + 0x55, 0xb0, 0xa, 0xa, 0xb, 0xb, 0x0, 0x0, + 0xb0, 0xa, 0x5d, 0x5c, 0xb, 0x55, 0x55, 0xb0, + 0x2, 0x5f, 0x41, 0xb, 0x0, 0x0, 0xb0, 0x0, + 0xab, 0x3b, 0xb, 0x55, 0x55, 0xb0, 0x6, 0x3a, + 0x6, 0x52, 0x83, 0x14, 0x10, 0x24, 0xa, 0x0, + 0x5, 0x90, 0x6, 0x90, 0x0, 0xa, 0x0, 0x45, + 0x0, 0x0, 0xb2, 0x0, 0x1, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+984C "題" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x75, 0x5b, 0x36, 0x55, 0x57, 0x90, 0x4, 0x50, + 0xa, 0x0, 0x9, 0x0, 0x0, 0x4, 0x85, 0x5a, + 0x7, 0x67, 0x5b, 0x0, 0x5, 0x51, 0x1a, 0xa, + 0x0, 0xa, 0x0, 0x4, 0x64, 0x46, 0xa, 0x55, + 0x5a, 0x0, 0x5, 0x55, 0x57, 0x7a, 0x55, 0x5a, + 0x0, 0x3, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, + 0x8, 0x3a, 0x3, 0x1a, 0x55, 0x58, 0x0, 0x9, + 0x1a, 0x55, 0x21, 0xc0, 0x44, 0x0, 0x9, 0x5a, + 0x0, 0x8, 0x20, 0xa, 0x40, 0x7, 0xb, 0x30, + 0x30, 0x0, 0x1, 0x20, 0x41, 0x0, 0x7b, 0xbb, + 0xcc, 0xde, 0x80, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9854 "顔" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x40, 0x36, 0x56, 0x55, 0xb1, 0x5, 0x66, + 0x79, 0x60, 0xc, 0x10, 0x0, 0x0, 0x71, 0x39, + 0x7, 0x59, 0x55, 0xa0, 0x1, 0x36, 0x60, 0x1c, + 0x0, 0x0, 0xa0, 0xa, 0x55, 0x66, 0x6b, 0x55, + 0x55, 0xa0, 0xa, 0x0, 0x2a, 0xb, 0x0, 0x0, + 0xa0, 0xa, 0x5, 0x71, 0xb, 0x55, 0x55, 0xa0, + 0xa, 0x20, 0x1b, 0x4b, 0x0, 0x0, 0xa0, 0x9, + 0x3, 0x82, 0xb, 0x55, 0x55, 0xa0, 0x8, 0x22, + 0x6, 0xb1, 0x93, 0x24, 0x0, 0x15, 0x1, 0x87, + 0x5, 0x90, 0x7, 0x80, 0x40, 0x45, 0x0, 0x45, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+9858 "願" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x55, 0x59, 0x76, 0x57, 0x55, 0xb1, 0xa, 0x0, + 0x90, 0x0, 0xc, 0x10, 0x0, 0xa, 0x23, 0x32, + 0x15, 0x48, 0x44, 0x90, 0xa, 0x58, 0x59, 0x4b, + 0x11, 0x11, 0xc0, 0xa, 0x57, 0x59, 0x2b, 0x55, + 0x55, 0xb0, 0xa, 0x54, 0x7, 0x2b, 0x0, 0x0, + 0xb0, 0xa, 0x57, 0x99, 0x2b, 0x55, 0x55, 0xb0, + 0x8, 0x10, 0xa0, 0xb, 0x0, 0x0, 0xb0, 0x7, + 0x85, 0xa6, 0x1b, 0x55, 0x55, 0xb0, 0x33, 0x70, + 0xa2, 0xa1, 0x83, 0x14, 0x10, 0x24, 0x22, 0xb0, + 0x54, 0x90, 0x6, 0x90, 0x0, 0xa, 0x70, 0x36, + 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+985E "類" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x9, 0x35, 0x26, 0x56, 0x55, 0xb1, 0x2, 0xa9, + 0x2a, 0x0, 0xc, 0x20, 0x0, 0x0, 0x39, 0x73, + 0x45, 0x49, 0x44, 0x90, 0x26, 0xaf, 0xb6, 0x4b, + 0x10, 0x0, 0xb0, 0x3, 0x89, 0x3b, 0x3b, 0x55, + 0x55, 0xb0, 0x34, 0x9, 0x32, 0x3a, 0x0, 0x0, + 0xb0, 0x0, 0x6, 0x4b, 0xa, 0x55, 0x55, 0xb0, + 0x12, 0x29, 0x55, 0x6a, 0x0, 0x0, 0xb0, 0x14, + 0x3d, 0x33, 0x3b, 0x55, 0x55, 0xb0, 0x0, 0x2a, + 0x78, 0x1, 0x84, 0x14, 0x10, 0x0, 0xa1, 0x7, + 0x54, 0xa0, 0x6, 0x90, 0x6, 0x10, 0x0, 0x36, + 0x0, 0x0, 0xb1, 0x10, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+986F "顯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x55, 0x59, 0x56, 0x57, 0x58, 0x70, 0xa, 0x0, + 0xa, 0x0, 0xc, 0x0, 0x0, 0xa, 0x55, 0x5c, + 0x6, 0x68, 0x59, 0x30, 0xa, 0x55, 0x5a, 0xb, + 0x0, 0x9, 0x10, 0x2, 0x80, 0x17, 0xa, 0x55, + 0x5b, 0x10, 0x6, 0x34, 0x74, 0x5a, 0x0, 0x9, + 0x10, 0x28, 0x91, 0x8a, 0x1a, 0x55, 0x5b, 0x10, + 0x27, 0x54, 0x64, 0x4a, 0x0, 0x9, 0x10, 0x36, + 0x39, 0x63, 0x7a, 0x55, 0x5b, 0x10, 0x3, 0x31, + 0x54, 0x21, 0x92, 0x24, 0x0, 0x19, 0x37, 0xa2, + 0xa3, 0x90, 0x8, 0x60, 0x33, 0x2, 0x10, 0x36, + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+98A8 "風" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x86, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x82, + 0x0, 0x4, 0x92, 0xb0, 0x0, 0x0, 0x84, 0x57, + 0xd5, 0x20, 0xb0, 0x0, 0x0, 0x82, 0x0, 0xb0, + 0x0, 0xb0, 0x0, 0x0, 0x82, 0xa5, 0xc5, 0xc1, + 0xb0, 0x0, 0x0, 0x82, 0xb0, 0xb0, 0xb0, 0xb0, + 0x0, 0x0, 0x82, 0xb0, 0xb0, 0xb0, 0xb0, 0x0, + 0x0, 0x91, 0xa5, 0xc5, 0x90, 0xb0, 0x0, 0x0, + 0xb0, 0x0, 0xb0, 0x60, 0xc0, 0x0, 0x0, 0xa0, + 0x0, 0xb4, 0x7a, 0x93, 0x50, 0x6, 0x49, 0xc9, + 0x63, 0xb, 0x3c, 0x90, 0x16, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+98DB "飛" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x65, 0x55, 0x55, 0xc6, 0x3, 0x0, 0x0, 0x0, + 0x73, 0x90, 0xa4, 0x88, 0x0, 0x0, 0x2b, 0x51, + 0xa0, 0x98, 0x52, 0x0, 0x3, 0x3a, 0x0, 0xa0, + 0x5a, 0xa, 0x31, 0x0, 0xa, 0x0, 0xa0, 0xb, + 0x50, 0x61, 0x15, 0x5c, 0x55, 0xb5, 0xa2, 0x78, + 0xc5, 0x1, 0xa, 0x0, 0xa0, 0xb0, 0x12, 0x11, + 0x0, 0xb, 0x0, 0xa0, 0xb6, 0x73, 0x0, 0x0, + 0xa, 0x0, 0xa0, 0xb1, 0xa6, 0x0, 0x0, 0x45, + 0x0, 0xa0, 0x76, 0x5, 0x13, 0x0, 0x80, 0x0, + 0xa0, 0xb, 0x60, 0x53, 0x15, 0x0, 0x1, 0x50, + 0x0, 0x6b, 0xd5, + + /* U+98DF "食" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x7, 0x10, 0x0, 0x0, 0x0, 0x3, 0xb1, + 0x71, 0x96, 0x0, 0x0, 0x0, 0x59, 0x0, 0x58, + 0x8, 0xd9, 0x60, 0x16, 0x39, 0x65, 0x56, 0x5d, + 0x28, 0x40, 0x0, 0x9, 0x20, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x9, 0x65, 0x55, 0x5c, 0x0, 0x0, + 0x0, 0x9, 0x65, 0x55, 0x5c, 0x0, 0x0, 0x0, + 0x9, 0x22, 0x0, 0x7, 0xb0, 0x0, 0x0, 0x9, + 0x20, 0x68, 0x66, 0x0, 0x0, 0x0, 0xa, 0x34, + 0x52, 0x8c, 0x50, 0x0, 0x0, 0xb, 0xb3, 0x0, + 0x3, 0xe2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+98EF "飯" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x60, 0x1, 0x1, 0x5b, 0x60, 0x0, 0x1b, + 0x66, 0xb, 0x54, 0x31, 0x0, 0x0, 0x84, 0x6, + 0x8b, 0x0, 0x0, 0x0, 0x4, 0x41, 0xa0, 0x2b, + 0x0, 0x0, 0x0, 0x13, 0xa5, 0x6a, 0x2b, 0x65, + 0x58, 0x90, 0x0, 0xa0, 0xa, 0xb, 0x30, 0x7, + 0x30, 0x0, 0xc5, 0x5c, 0xb, 0x4, 0xa, 0x0, + 0x0, 0xc5, 0x5c, 0xb, 0x6, 0x27, 0x0, 0x0, + 0xa0, 0x42, 0xa, 0x5, 0xb0, 0x0, 0x0, 0xa0, + 0x4a, 0x18, 0x6, 0xb0, 0x0, 0x0, 0xc9, 0x4a, + 0x51, 0x37, 0x49, 0x0, 0x0, 0xa1, 0x0, 0x52, + 0x50, 0x8, 0xb1, 0x0, 0x0, 0x2, 0x2, 0x0, + 0x0, 0x30, + + /* U+98F2 "飲" */ + 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x8, 0x70, 0x0, 0xc2, 0x0, 0x0, 0x0, 0xb, + 0x65, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x84, 0x7, + 0x85, 0x95, 0x58, 0x60, 0x3, 0x41, 0xa0, 0x29, + 0x10, 0x9, 0x30, 0x13, 0x95, 0x7a, 0x44, 0x4a, + 0x7, 0x0, 0x0, 0xa0, 0xa, 0x20, 0x59, 0x11, + 0x0, 0x0, 0xc5, 0x5c, 0x0, 0x69, 0x0, 0x0, + 0x0, 0xc5, 0x5c, 0x0, 0x97, 0x0, 0x0, 0x0, + 0xa0, 0x42, 0x0, 0xb1, 0x60, 0x0, 0x0, 0xa0, + 0x5b, 0x3, 0x80, 0xa1, 0x0, 0x1, 0xe9, 0x18, + 0x8, 0x0, 0x3c, 0x10, 0x0, 0x50, 0x0, 0x50, + 0x0, 0x5, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9928 "館" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x8, 0x70, 0x0, 0x7, 0x60, 0x0, 0x0, 0xc, + 0x74, 0x8, 0x56, 0xa5, 0x93, 0x0, 0x85, 0xa, + 0xb6, 0x0, 0x0, 0x90, 0x3, 0x53, 0x80, 0x23, + 0x11, 0x16, 0x10, 0x14, 0x85, 0x79, 0x19, 0x64, + 0x4c, 0x10, 0x0, 0xa0, 0xa, 0x9, 0x20, 0xb, + 0x0, 0x0, 0xb5, 0x5b, 0x9, 0x65, 0x59, 0x0, + 0x0, 0xa1, 0x1b, 0x9, 0x20, 0x2, 0x30, 0x0, + 0xb3, 0x65, 0x9, 0x65, 0x58, 0x80, 0x0, 0xa0, + 0x4a, 0x9, 0x20, 0x5, 0x50, 0x1, 0xd9, 0x4a, + 0x9, 0x65, 0x58, 0x60, 0x0, 0x80, 0x0, 0x9, + 0x20, 0x4, 0x30, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+9996 "首" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x84, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x81, 0x0, 0x30, 0x16, 0x55, 0x58, + 0xb5, 0x75, 0x57, 0x91, 0x0, 0x0, 0x2, 0x80, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x57, 0x65, 0x56, + 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, 0xa0, + 0x0, 0x0, 0xc, 0x55, 0x55, 0x56, 0xa0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, + 0xc, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0xc, 0x55, + 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, 0x0, 0x0, + 0x1, 0xa0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9999 "香" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x35, 0x8b, 0xc3, 0x0, 0x0, 0x4, + 0x55, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x1, 0x80, 0x4, 0x55, 0x58, 0xdd, + 0x95, 0x55, 0x51, 0x0, 0x0, 0x2b, 0x1c, 0x18, + 0x10, 0x0, 0x0, 0x5, 0x90, 0xd, 0x1, 0xb9, + 0x30, 0x1, 0x64, 0x75, 0x57, 0x55, 0xa6, 0xc4, + 0x3, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, + 0x0, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, + 0xc5, 0x55, 0x55, 0xa0, 0x0, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0xc5, 0x55, + 0x55, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+99C4 "駄" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x2, + 0xa5, 0x85, 0x80, 0xb, 0x20, 0x0, 0x1, 0xa0, + 0xa0, 0x0, 0xa, 0x0, 0x0, 0x1, 0xb5, 0xc6, + 0x60, 0xa, 0x0, 0x10, 0x1, 0xa0, 0xa0, 0x26, + 0x5c, 0x65, 0x91, 0x1, 0xb5, 0xc5, 0x40, 0xa, + 0x50, 0x0, 0x1, 0xa0, 0xa0, 0x30, 0x9, 0x60, + 0x0, 0x1, 0xb4, 0x54, 0xd1, 0x37, 0x70, 0x0, + 0x0, 0x21, 0x40, 0xb0, 0x72, 0x81, 0x0, 0x4, + 0x66, 0x85, 0xb0, 0xa0, 0x47, 0x0, 0xa, 0x82, + 0x42, 0x93, 0x82, 0xc, 0x0, 0x14, 0x1, 0x8, + 0x69, 0xa, 0x27, 0x90, 0x0, 0x0, 0x8c, 0x61, + 0x3, 0x10, 0xc4, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+99C5 "駅" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, + 0xa5, 0x95, 0x86, 0x65, 0x55, 0xc0, 0x1, 0x90, + 0xb0, 0x16, 0x40, 0x0, 0xb0, 0x1, 0xb5, 0xc6, + 0x56, 0x40, 0x0, 0xb0, 0x1, 0x90, 0xb0, 0x16, + 0x40, 0x0, 0xb0, 0x1, 0xb5, 0xc5, 0x46, 0x88, + 0x55, 0xa0, 0x1, 0x90, 0xb0, 0x26, 0x45, 0x0, + 0x0, 0x1, 0xb4, 0x54, 0xd7, 0x34, 0x30, 0x0, + 0x0, 0x11, 0x40, 0xb8, 0x10, 0x80, 0x0, 0x4, + 0x64, 0x77, 0xb9, 0x0, 0xa0, 0x0, 0xa, 0x73, + 0x53, 0x98, 0x0, 0x49, 0x0, 0x14, 0x0, 0x8, + 0x83, 0x0, 0xb, 0x80, 0x0, 0x0, 0x7c, 0x60, + 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9A12 "騒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x85, 0x76, 0x74, 0x65, 0x56, 0xb0, 0x1, 0xa0, + 0xb0, 0x0, 0x51, 0x9, 0x40, 0x1, 0xb5, 0xc7, + 0x40, 0x9, 0x3a, 0x0, 0x1, 0xa0, 0xb0, 0x0, + 0x4, 0xf2, 0x0, 0x1, 0xb5, 0xc7, 0x40, 0x58, + 0x5c, 0x83, 0x1, 0xa0, 0xb0, 0x14, 0x20, 0xc0, + 0x51, 0x2, 0xb4, 0x74, 0xd6, 0x85, 0xc5, 0xc0, + 0x0, 0x1, 0x30, 0xb5, 0x60, 0xb0, 0xb0, 0x3, + 0x66, 0x85, 0xa5, 0x95, 0xc5, 0xc0, 0xa, 0x65, + 0x43, 0x82, 0x20, 0xb2, 0x30, 0x14, 0x0, 0x6, + 0x50, 0x0, 0xb3, 0xb2, 0x0, 0x3, 0x9c, 0x1c, + 0xb8, 0x63, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9A13 "験" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, + 0x85, 0x77, 0x50, 0x1e, 0x10, 0x0, 0x1, 0x90, + 0xb0, 0x0, 0x93, 0x70, 0x0, 0x1, 0xb5, 0xc7, + 0x24, 0x70, 0x2b, 0x51, 0x1, 0x90, 0xb0, 0x37, + 0x68, 0x6a, 0x82, 0x1, 0xb5, 0xc7, 0x20, 0xa, + 0x11, 0x0, 0x1, 0x90, 0xb0, 0x1b, 0x5c, 0x5b, + 0x40, 0x2, 0xa4, 0x66, 0x9b, 0xa, 0x19, 0x10, + 0x0, 0x1, 0x43, 0x7b, 0x5c, 0x5b, 0x10, 0x7, + 0x66, 0x88, 0x66, 0xb, 0x14, 0x0, 0x2b, 0x73, + 0x36, 0x40, 0x28, 0x70, 0x0, 0x11, 0x0, 0x9, + 0x21, 0xa0, 0x59, 0x0, 0x0, 0x2, 0xaa, 0x37, + 0x0, 0x6, 0xd3, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+9A57 "驗" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, + 0x85, 0x68, 0x40, 0xd, 0x30, 0x0, 0x1, 0x90, + 0xa0, 0x0, 0x64, 0x80, 0x0, 0x1, 0xb5, 0xc8, + 0x12, 0x80, 0x2a, 0x10, 0x1, 0x90, 0xa0, 0x18, + 0x65, 0x5b, 0xc5, 0x1, 0xb5, 0xc7, 0x31, 0x1, + 0x10, 0x20, 0x1, 0x90, 0xa0, 0xc, 0x77, 0xb5, + 0xc0, 0x1, 0xb4, 0x77, 0x8a, 0x35, 0xa0, 0xa0, + 0x0, 0x20, 0x34, 0x5c, 0x76, 0xb5, 0xb0, 0x4, + 0x56, 0x4b, 0x56, 0x81, 0x46, 0x40, 0xa, 0x82, + 0x37, 0x44, 0x80, 0xc, 0x0, 0x14, 0x0, 0xa, + 0x19, 0x63, 0x48, 0x60, 0x0, 0x2, 0x9a, 0x53, + 0x8, 0x70, 0x81, 0x0, 0x0, 0x0, 0x10, 0x2, + 0x0, 0x0, + + /* U+9AD4 "體" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x20, 0x0, 0x0, + 0x85, 0x5a, 0x0, 0x46, 0xb1, 0x0, 0x0, 0xa2, + 0x1a, 0x7, 0x89, 0xc6, 0xa0, 0x0, 0xca, 0x5a, + 0xb, 0x46, 0xa2, 0x90, 0x2, 0xa7, 0x3a, 0x1b, + 0x78, 0xc6, 0x90, 0xb, 0x66, 0x57, 0x9b, 0x78, + 0xc6, 0x90, 0x25, 0x85, 0x5b, 0x5, 0x0, 0x1, + 0x60, 0x0, 0xb0, 0xa, 0x26, 0x55, 0x56, 0x51, + 0x0, 0xc5, 0x5a, 0x7, 0x75, 0x5a, 0x60, 0x0, + 0xb0, 0xa, 0x6, 0x52, 0x28, 0x40, 0x0, 0xc5, + 0x5a, 0x5, 0x73, 0x59, 0x20, 0x0, 0xb0, 0xa, + 0x0, 0x83, 0x64, 0x0, 0x0, 0xb2, 0x99, 0x45, + 0x66, 0x95, 0xb2, 0x0, 0x20, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+9AD8 "高" */ + 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x20, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x69, 0x0, 0x3, 0x65, 0x55, 0x59, + 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0xb0, 0x0, + 0x0, 0x4, 0x95, 0x55, 0x5c, 0x0, 0x0, 0x0, + 0x32, 0x0, 0x0, 0x50, 0x10, 0x0, 0xc5, 0x55, + 0x55, 0x55, 0x5d, 0x30, 0xb, 0x6, 0x55, 0x59, + 0x30, 0xc0, 0x0, 0xb0, 0x91, 0x0, 0x91, 0xc, + 0x0, 0xb, 0x9, 0x65, 0x5b, 0x20, 0xc0, 0x0, + 0xb0, 0x70, 0x0, 0x61, 0xc, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x39, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+9AEA "髪" */ + 0x0, 0x20, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, + 0xa5, 0x55, 0x50, 0x5, 0xb3, 0x0, 0x0, 0xa5, + 0x56, 0x44, 0x73, 0x4, 0x0, 0x0, 0xa5, 0x56, + 0x50, 0x3, 0xa6, 0x0, 0x6, 0xa8, 0x55, 0x86, + 0x53, 0x3, 0x40, 0x0, 0x58, 0x16, 0x20, 0x3, + 0x98, 0x30, 0x6, 0xc7, 0x55, 0x84, 0x64, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x7, 0x20, + 0x16, 0x55, 0x8b, 0x55, 0x55, 0x55, 0x30, 0x0, + 0x1, 0xb8, 0x55, 0x5d, 0x40, 0x0, 0x0, 0x1a, + 0x23, 0x42, 0xb4, 0x0, 0x0, 0x3, 0x70, 0x1, + 0xad, 0x50, 0x0, 0x0, 0x22, 0x4, 0x66, 0x10, + 0x5b, 0xa8, 0x60, 0x1, 0x30, 0x0, 0x0, 0x0, + 0x3, 0x0, + + /* U+9B5A "魚" */ + 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xd5, 0x0, 0x10, 0x0, 0x0, 0x0, 0xa7, + 0x55, 0xab, 0x0, 0x0, 0x0, 0x83, 0x0, 0x19, + 0x0, 0x0, 0x0, 0x7b, 0x55, 0x5a, 0x55, 0x6d, + 0x1, 0x50, 0xb0, 0x0, 0xc0, 0x2, 0xa0, 0x0, + 0xb, 0x55, 0x5d, 0x55, 0x7a, 0x0, 0x0, 0xb0, + 0x0, 0xc0, 0x2, 0xa0, 0x0, 0xb, 0x0, 0xc, + 0x0, 0x2a, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x56, + 0x70, 0x0, 0x12, 0x22, 0x4, 0x20, 0x53, 0x0, + 0xb, 0x0, 0xc0, 0xd, 0x10, 0xc6, 0x9, 0x80, + 0xb, 0x10, 0x82, 0x2, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9CE5 "鳥" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x58, 0x55, 0x5b, 0x20, 0x0, 0x0, 0xb, 0x0, + 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, + 0x5c, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x5c, + 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x55, 0x56, + 0xa0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0xb, 0x55, 0x55, 0x55, 0x5b, 0x50, 0x0, + 0x11, 0x2, 0x30, 0x73, 0xb, 0x10, 0x0, 0x60, + 0xa0, 0xa4, 0x1d, 0xc, 0x0, 0x5, 0x80, 0xa1, + 0x24, 0x13, 0x1c, 0x0, 0x6, 0x10, 0x10, 0x0, + 0x29, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x30, 0x0, + + /* U+9E97 "麗" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x4, + 0x65, 0x56, 0x64, 0x65, 0x56, 0x40, 0x0, 0xb5, + 0x5c, 0x10, 0xb5, 0x5b, 0x0, 0x0, 0xb2, 0x5b, + 0x0, 0xb8, 0x1a, 0x0, 0x0, 0x90, 0x28, 0x56, + 0x92, 0xa, 0x0, 0x0, 0x96, 0x59, 0x56, 0x95, + 0x57, 0x50, 0x0, 0x96, 0x5b, 0x65, 0xb5, 0x58, + 0x10, 0x0, 0x92, 0x9, 0x10, 0x90, 0xa, 0x0, + 0x0, 0xa6, 0x86, 0x55, 0xa7, 0x59, 0x0, 0x0, + 0xc0, 0xa1, 0x2, 0x90, 0x18, 0x0, 0x0, 0xa0, + 0xa5, 0x55, 0x96, 0x74, 0x30, 0x2, 0x60, 0xa1, + 0x43, 0x90, 0x0, 0x60, 0x7, 0x0, 0xb9, 0x20, + 0x6b, 0xaa, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9EBC "麼" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x1, 0xc0, 0x0, 0x21, 0x0, 0xc5, 0x56, + 0x57, 0x56, 0x58, 0x60, 0xb, 0x0, 0xa1, 0x0, + 0xa2, 0x0, 0x0, 0xb5, 0x6d, 0x74, 0x6d, 0x67, + 0x40, 0xb, 0x4, 0xf6, 0x14, 0xf6, 0x10, 0x0, + 0xa2, 0x7a, 0x16, 0x7a, 0x1b, 0x60, 0xa, 0x40, + 0x81, 0x50, 0x60, 0x12, 0x0, 0x90, 0x3, 0x95, + 0x5, 0x20, 0x0, 0x27, 0x1b, 0x96, 0x49, 0xa3, + 0x0, 0x4, 0x30, 0x41, 0x37, 0x20, 0x50, 0x0, + 0x70, 0x5, 0x75, 0x34, 0x59, 0x70, 0x4, 0x0, + 0xc9, 0x64, 0x20, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9EC4 "黄" */ + 0x0, 0x0, 0x21, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x56, 0x0, 0xb2, 0x1, 0x0, 0x0, 0x65, + 0x98, 0x55, 0xc5, 0x5a, 0x20, 0x0, 0x0, 0x54, + 0x0, 0xb0, 0x0, 0x20, 0x26, 0x55, 0x77, 0x75, + 0x95, 0x56, 0xa1, 0x0, 0x2, 0x0, 0x91, 0x0, + 0x30, 0x0, 0x0, 0xd, 0x55, 0xb6, 0x55, 0xc2, + 0x0, 0x0, 0xc, 0x0, 0x91, 0x0, 0xb0, 0x0, + 0x0, 0xd, 0x55, 0xb6, 0x55, 0xc0, 0x0, 0x0, + 0xc, 0x0, 0x91, 0x0, 0xb0, 0x0, 0x0, 0xb, + 0x88, 0x55, 0x96, 0x90, 0x0, 0x0, 0x4, 0xd5, + 0x0, 0x7, 0xa3, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x0, 0x3e, 0x20, 0x4, 0x10, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+9ED2 "黒" */ + 0x1, 0x95, 0x55, 0x65, 0x55, 0xa0, 0x0, 0x1a, + 0x0, 0xb, 0x0, 0xb, 0x0, 0x1, 0xc5, 0x55, + 0xc5, 0x55, 0xb0, 0x0, 0x1a, 0x0, 0xb, 0x0, + 0xb, 0x0, 0x1, 0xc5, 0x55, 0xc5, 0x55, 0xb0, + 0x0, 0x3, 0x0, 0xb, 0x0, 0x2, 0x0, 0x5, + 0x65, 0x55, 0xc5, 0x55, 0xb2, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x1, 0x40, 0x46, 0x55, 0x55, 0x85, + 0x55, 0x79, 0x10, 0x4, 0x6, 0x0, 0x70, 0x8, + 0x0, 0x4, 0x60, 0x74, 0x8, 0x40, 0x86, 0x0, + 0xc1, 0x4, 0x30, 0x33, 0x3, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9EDE "點" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7, + 0x57, 0x59, 0x30, 0xd, 0x0, 0x0, 0x9, 0x1a, + 0x3a, 0x0, 0xb, 0x0, 0x0, 0x9, 0x8a, 0x6a, + 0x0, 0xc, 0x44, 0x80, 0x9, 0x6c, 0x5b, 0x10, + 0xb, 0x0, 0x0, 0x6, 0xa, 0x4, 0x0, 0xb, + 0x0, 0x0, 0x2, 0x3b, 0x38, 0x10, 0xb, 0x0, + 0x0, 0x2, 0x3b, 0x22, 0x19, 0x5a, 0x5b, 0x20, + 0x0, 0xa, 0x54, 0x1a, 0x0, 0xb, 0x0, 0xb, + 0xa5, 0x1, 0xa, 0x0, 0xb, 0x0, 0x2, 0x20, + 0x62, 0x7a, 0x0, 0xb, 0x0, 0x7, 0x27, 0x71, + 0x8b, 0x55, 0x5c, 0x0, 0x19, 0x2, 0x0, 0xb, + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+9EE8 "黨" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x10, 0x0, 0x0, + 0x6, 0x70, 0xb, 0x6, 0x80, 0x0, 0x0, 0x53, + 0xa3, 0x3b, 0x38, 0x33, 0x70, 0x3, 0x82, 0x52, + 0x22, 0x25, 0x26, 0x91, 0x8, 0x10, 0x96, 0x55, + 0x5c, 0x12, 0x0, 0x0, 0x0, 0x96, 0x55, 0x5a, + 0x0, 0x0, 0x0, 0x29, 0x65, 0x58, 0x55, 0x6a, + 0x0, 0x0, 0x29, 0x37, 0xa, 0x19, 0x18, 0x0, + 0x0, 0x2b, 0x56, 0x5b, 0x65, 0x68, 0x0, 0x0, + 0x47, 0x55, 0x5b, 0x55, 0x5a, 0x10, 0x4, 0x55, + 0x55, 0x5b, 0x55, 0x55, 0xb1, 0x1, 0x30, 0x4, + 0x0, 0x40, 0x4, 0x10, 0x2, 0xa0, 0x2, 0x70, + 0x35, 0x1, 0x80, 0x2, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9F13 "鼓" */ + 0x0, 0x0, 0x40, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x9, 0x40, 0x0, 0x6, 0x55, + 0xd5, 0x75, 0x9, 0x20, 0x0, 0x0, 0x0, 0xb0, + 0x5, 0x5b, 0x65, 0xa0, 0x1, 0x75, 0xb5, 0x91, + 0x9, 0x20, 0x0, 0x0, 0x10, 0x0, 0x20, 0x9, + 0x21, 0x10, 0x0, 0xd5, 0x55, 0xd3, 0x86, 0x5b, + 0x70, 0x0, 0xd0, 0x0, 0xb0, 0x50, 0xc, 0x0, + 0x0, 0xd5, 0x55, 0xa0, 0x43, 0x66, 0x0, 0x0, + 0x40, 0x9, 0x10, 0xa, 0xb0, 0x0, 0x0, 0x19, + 0x9, 0x0, 0xb, 0x90, 0x0, 0x0, 0x15, 0x78, + 0x53, 0x82, 0x7a, 0x10, 0xc, 0x95, 0x20, 0x36, + 0x0, 0x6, 0xc1, 0x0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, + + /* U+9F3B "鼻" */ + 0x0, 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x5a, 0x65, 0x58, 0x10, 0x0, 0x0, 0xa, + 0x22, 0x22, 0x2a, 0x0, 0x0, 0x0, 0xa, 0x33, + 0x33, 0x3a, 0x0, 0x0, 0x0, 0xa, 0x55, 0x55, + 0x5b, 0x0, 0x0, 0x0, 0x9, 0x55, 0x55, 0x5a, + 0x0, 0x0, 0x0, 0xa5, 0x55, 0x95, 0x55, 0xc2, + 0x0, 0x0, 0xa5, 0x55, 0xc5, 0x55, 0xc0, 0x0, + 0x0, 0xb5, 0x55, 0xc5, 0x55, 0xc0, 0x0, 0x0, + 0x40, 0x0, 0x0, 0x0, 0x42, 0x40, 0x17, 0x55, + 0xc6, 0x55, 0xd5, 0x55, 0x40, 0x0, 0x1, 0xa0, + 0x0, 0xb0, 0x0, 0x0, 0x0, 0x29, 0x10, 0x0, + 0xb0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x30, + 0x0, 0x0, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x7b, 0xfb, 0x0, + 0x0, 0x0, 0x4, 0x9d, 0xff, 0xff, 0xd0, 0x0, + 0x3, 0xaf, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0xaf, 0xff, 0xff, 0xff, 0xdf, 0xd0, 0x0, 0xa, + 0xff, 0xff, 0xb6, 0x10, 0xed, 0x0, 0x0, 0xaf, + 0x94, 0x0, 0x0, 0xe, 0xd0, 0x0, 0xa, 0xf1, + 0x0, 0x0, 0x0, 0xed, 0x0, 0x0, 0xaf, 0x10, + 0x0, 0x0, 0xe, 0xd0, 0x0, 0xa, 0xf1, 0x0, + 0x0, 0x45, 0xfd, 0x0, 0x0, 0xaf, 0x10, 0x1, + 0xef, 0xff, 0xd0, 0x17, 0x9d, 0xf1, 0x0, 0x5f, + 0xff, 0xfc, 0xe, 0xff, 0xff, 0x10, 0x0, 0xaf, + 0xfd, 0x31, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x1, + 0x0, 0x3, 0xbd, 0xa3, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F008 "" */ + 0x50, 0x18, 0x88, 0x88, 0x88, 0x84, 0x5, 0xfa, + 0xbf, 0xdd, 0xdd, 0xdd, 0xfd, 0xaf, 0xe4, 0x7f, + 0x10, 0x0, 0x0, 0xca, 0x4e, 0xe0, 0x4f, 0x10, + 0x0, 0x0, 0xc8, 0xe, 0xfe, 0xef, 0x10, 0x0, + 0x0, 0xcf, 0xef, 0xe0, 0x3f, 0xee, 0xee, 0xee, + 0xf8, 0xe, 0xf6, 0x8f, 0x76, 0x66, 0x66, 0xeb, + 0x6f, 0xf8, 0xaf, 0x10, 0x0, 0x0, 0xcc, 0x8f, + 0xe0, 0x3f, 0x10, 0x0, 0x0, 0xc8, 0xe, 0xfc, + 0xdf, 0x65, 0x55, 0x55, 0xee, 0xcf, 0xc2, 0x5f, + 0xff, 0xff, 0xff, 0xf9, 0x2c, + + /* U+F00B "" */ + 0x57, 0x75, 0x5, 0x77, 0x77, 0x77, 0x75, 0xff, + 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xe, + 0xff, 0xff, 0xff, 0xfe, 0x1, 0x10, 0x0, 0x11, + 0x11, 0x11, 0x10, 0xef, 0xfe, 0xe, 0xff, 0xff, + 0xff, 0xfe, 0xff, 0xff, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0x68, 0x87, 0x7, 0x88, 0x88, 0x88, 0x86, 0x68, + 0x87, 0x7, 0x88, 0x88, 0x88, 0x86, 0xff, 0xff, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xfd, 0xd, 0xff, + 0xff, 0xff, 0xfd, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xff, 0xe2, 0x2d, 0x60, 0x0, 0x1, + 0xdf, 0xfe, 0x20, 0xdf, 0xf7, 0x0, 0x1d, 0xff, + 0xe2, 0x0, 0x8f, 0xff, 0x71, 0xdf, 0xfe, 0x20, + 0x0, 0x8, 0xff, 0xfe, 0xff, 0xe2, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xfe, 0x20, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7d, 0x20, 0x0, 0x0, 0x0, + + /* U+F00D "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0x60, 0x0, + 0xb, 0xe2, 0xef, 0xf6, 0x0, 0xbf, 0xf8, 0x4f, + 0xff, 0x6b, 0xff, 0xd1, 0x4, 0xff, 0xff, 0xfd, + 0x10, 0x0, 0x5f, 0xff, 0xe1, 0x0, 0x0, 0xbf, + 0xff, 0xf6, 0x0, 0xb, 0xff, 0xdf, 0xff, 0x60, + 0xbf, 0xfd, 0x14, 0xff, 0xf5, 0xcf, 0xd1, 0x0, + 0x4f, 0xf6, 0x17, 0x10, 0x0, 0x3, 0x60, + + /* U+F011 "" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x6f, + 0x21, 0xff, 0x12, 0xf7, 0x0, 0x6, 0xff, 0x61, + 0xff, 0x16, 0xff, 0x60, 0x1f, 0xf9, 0x1, 0xff, + 0x10, 0x9f, 0xf1, 0x6f, 0xe0, 0x1, 0xff, 0x10, + 0xe, 0xf6, 0xaf, 0x80, 0x1, 0xff, 0x10, 0x8, + 0xfa, 0xcf, 0x60, 0x1, 0xff, 0x10, 0x6, 0xfc, + 0xaf, 0x80, 0x0, 0xaa, 0x0, 0x8, 0xfb, 0x7f, + 0xd0, 0x0, 0x0, 0x0, 0xd, 0xf7, 0x1f, 0xf8, + 0x0, 0x0, 0x0, 0x8f, 0xf1, 0x7, 0xff, 0x91, + 0x0, 0x2a, 0xff, 0x70, 0x0, 0x9f, 0xff, 0xee, + 0xff, 0xf9, 0x0, 0x0, 0x5, 0xcf, 0xff, 0xfd, + 0x50, 0x0, 0x0, 0x0, 0x2, 0x44, 0x20, 0x0, + 0x0, + + /* U+F013 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xff, 0xc0, 0x0, 0x0, 0x3, 0xd6, 0xdf, + 0xff, 0xfd, 0x6d, 0x30, 0xe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe0, 0x5f, 0xff, 0xff, 0xaa, 0xff, + 0xff, 0xf5, 0x1a, 0xff, 0xf4, 0x0, 0x4f, 0xff, + 0xa1, 0x3, 0xff, 0xd0, 0x0, 0xd, 0xff, 0x30, + 0x4, 0xff, 0xf0, 0x0, 0xf, 0xff, 0x40, 0x4f, + 0xff, 0xfb, 0x22, 0xbf, 0xff, 0xf4, 0x2f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0x9, 0xfe, 0xff, + 0xff, 0xff, 0xef, 0x90, 0x0, 0x50, 0x5e, 0xff, + 0xe5, 0x5, 0x0, 0x0, 0x0, 0xc, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x77, 0x40, 0x0, + 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x0, 0x3, 0x10, 0x3, 0x41, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xf5, 0xd, 0xf5, 0x0, + 0x0, 0x0, 0x1b, 0xfd, 0xff, 0x8d, 0xf5, 0x0, + 0x0, 0x2, 0xdf, 0xb1, 0x2d, 0xff, 0xf5, 0x0, + 0x0, 0x4f, 0xf8, 0x3e, 0xc2, 0xbf, 0xf5, 0x0, + 0x7, 0xff, 0x55, 0xff, 0xfe, 0x39, 0xfe, 0x40, + 0x9f, 0xe3, 0x8f, 0xff, 0xff, 0xf5, 0x6f, 0xf6, + 0xac, 0x2a, 0xff, 0xff, 0xff, 0xff, 0x73, 0xe6, + 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, + 0x0, 0x6f, 0xff, 0xd7, 0x7f, 0xff, 0xf2, 0x0, + 0x0, 0x6f, 0xff, 0x90, 0xd, 0xff, 0xf2, 0x0, + 0x0, 0x6f, 0xff, 0x90, 0xd, 0xff, 0xf2, 0x0, + 0x0, 0x4f, 0xff, 0x70, 0xb, 0xff, 0xe1, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x2e, 0xff, 0xff, 0xff, 0xe2, 0x0, + 0x0, 0x2, 0xef, 0xff, 0xfe, 0x20, 0x0, 0x0, + 0x0, 0x2d, 0xff, 0xe2, 0x0, 0x0, 0x79, 0x99, + 0x82, 0xde, 0x28, 0x99, 0x97, 0xff, 0xff, 0xfb, + 0x22, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, + 0xb3, 0xcf, 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xca, + + /* U+F01C "" */ + 0x0, 0x6, 0xbb, 0xbb, 0xbb, 0xba, 0x30, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xe1, 0x0, + 0x0, 0xef, 0x30, 0x0, 0x0, 0x6, 0xfb, 0x0, + 0x9, 0xf8, 0x0, 0x0, 0x0, 0x0, 0xcf, 0x50, + 0x4f, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xe1, + 0xdf, 0x84, 0x42, 0x0, 0x0, 0x34, 0x4b, 0xf9, + 0xff, 0xff, 0xfd, 0x0, 0x1, 0xff, 0xff, 0xfb, + 0xff, 0xff, 0xff, 0x98, 0x8b, 0xff, 0xff, 0xfc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, + + /* U+F021 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, + 0x1, 0x8d, 0xff, 0xc6, 0x0, 0xef, 0x0, 0x4e, + 0xff, 0xff, 0xff, 0xe4, 0xdf, 0x4, 0xff, 0xb3, + 0x0, 0x4c, 0xff, 0xff, 0xe, 0xf9, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0x6f, 0xc0, 0x0, 0x1, 0xff, + 0xff, 0xff, 0x8e, 0x50, 0x0, 0x1, 0xde, 0xee, + 0xed, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x21, 0xff, + 0xff, 0xff, 0x10, 0x0, 0x8, 0xf8, 0xff, 0xfb, + 0xbc, 0x10, 0x0, 0x1e, 0xf4, 0xff, 0xfc, 0x10, + 0x0, 0x1, 0xdf, 0xc0, 0xfe, 0xef, 0xe8, 0x44, + 0x8e, 0xfe, 0x10, 0xfe, 0x1a, 0xff, 0xff, 0xff, + 0xc1, 0x0, 0xfd, 0x0, 0x28, 0xbb, 0x94, 0x0, + 0x0, + + /* U+F026 "" */ + 0x0, 0x0, 0x2, 0x70, 0x0, 0x2, 0xef, 0x0, + 0x2, 0xef, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x34, 0x47, 0xff, 0xf0, + 0x0, 0x5, 0xff, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x0, + + /* U+F027 "" */ + 0x0, 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x2, + 0xef, 0x0, 0x0, 0x0, 0x2, 0xef, 0xf0, 0x0, + 0xd, 0xff, 0xff, 0xff, 0x2, 0x20, 0xff, 0xff, + 0xff, 0xf0, 0x8e, 0x1f, 0xff, 0xff, 0xff, 0x0, + 0xe7, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x5f, 0xff, + 0xff, 0xff, 0x8, 0x90, 0x34, 0x47, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x5, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, + 0x0, 0x0, 0x2, 0x70, 0x0, 0x5, 0xfa, 0x0, + 0x0, 0x0, 0x2e, 0xf0, 0x0, 0x81, 0x4f, 0x60, + 0x0, 0x2, 0xef, 0xf0, 0x1, 0xdd, 0x7, 0xf0, + 0xdf, 0xff, 0xff, 0xf0, 0x32, 0x1e, 0x80, 0xf6, + 0xff, 0xff, 0xff, 0xf0, 0x8e, 0x27, 0xe0, 0xb9, + 0xff, 0xff, 0xff, 0xf0, 0xe, 0x73, 0xf1, 0x9b, + 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x54, 0xf0, 0x9a, + 0xff, 0xff, 0xff, 0xf0, 0x89, 0xa, 0xc0, 0xd8, + 0x34, 0x47, 0xff, 0xf0, 0x0, 0x7f, 0x43, 0xf3, + 0x0, 0x0, 0x5f, 0xf0, 0x2, 0xf6, 0xc, 0xb0, + 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0xbf, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xe3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, + + /* U+F03E "" */ + 0x37, 0x88, 0x88, 0x88, 0x88, 0x88, 0x73, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0x32, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, 0x7f, + 0xff, 0xfd, 0xff, 0xff, 0xfd, 0x10, 0xcf, 0xff, + 0xa0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x7, 0xff, 0xff, 0xf3, 0x5f, 0xa0, 0x0, 0x0, + 0xcf, 0xff, 0x30, 0x3, 0x0, 0x0, 0x0, 0xcf, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xff, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, + + /* U+F043 "" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, 0xfa, + 0x0, 0x0, 0x0, 0x6, 0xff, 0x10, 0x0, 0x0, + 0xd, 0xff, 0x70, 0x0, 0x0, 0x6f, 0xff, 0xf1, + 0x0, 0x1, 0xef, 0xff, 0xfa, 0x0, 0xb, 0xff, + 0xff, 0xff, 0x60, 0x5f, 0xff, 0xff, 0xff, 0xe0, + 0xcf, 0xff, 0xff, 0xff, 0xf6, 0xfe, 0xbf, 0xff, + 0xff, 0xf9, 0xfd, 0x4f, 0xff, 0xff, 0xf9, 0xbf, + 0x49, 0xff, 0xff, 0xf5, 0x3f, 0xe5, 0x2e, 0xff, + 0xd0, 0x6, 0xff, 0xff, 0xfd, 0x20, 0x0, 0x28, + 0xba, 0x60, 0x0, + + /* U+F048 "" */ + 0x4, 0x30, 0x0, 0x0, 0x31, 0x1f, 0xe0, 0x0, + 0x6, 0xf9, 0x1f, 0xe0, 0x0, 0x7f, 0xfa, 0x1f, + 0xe0, 0x9, 0xff, 0xfa, 0x1f, 0xe0, 0xaf, 0xff, + 0xfa, 0x1f, 0xeb, 0xff, 0xff, 0xfa, 0x1f, 0xff, + 0xff, 0xff, 0xfa, 0x1f, 0xff, 0xff, 0xff, 0xfa, + 0x1f, 0xe6, 0xff, 0xff, 0xfa, 0x1f, 0xe0, 0x5f, + 0xff, 0xfa, 0x1f, 0xe0, 0x4, 0xff, 0xfa, 0x1f, + 0xe0, 0x0, 0x3e, 0xfa, 0xf, 0xd0, 0x0, 0x2, + 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04B "" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xfb, + 0x20, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xe6, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xfc, 0x30, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0x91, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe6, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xb2, 0x0, 0xf, + 0xff, 0xff, 0xfd, 0x40, 0x0, 0x0, 0xff, 0xff, + 0xf7, 0x0, 0x0, 0x0, 0xf, 0xff, 0xa1, 0x0, + 0x0, 0x0, 0x0, 0x6a, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F04C "" */ + 0x14, 0x44, 0x20, 0x1, 0x44, 0x42, 0xd, 0xff, + 0xff, 0x10, 0xdf, 0xff, 0xf1, 0xff, 0xff, 0xf3, + 0xf, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x40, 0xff, + 0xff, 0xf4, 0xff, 0xff, 0xf4, 0xf, 0xff, 0xff, + 0x4f, 0xff, 0xff, 0x40, 0xff, 0xff, 0xf4, 0xff, + 0xff, 0xf4, 0xf, 0xff, 0xff, 0x4f, 0xff, 0xff, + 0x40, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xf4, 0xf, + 0xff, 0xff, 0x4f, 0xff, 0xff, 0x40, 0xff, 0xff, + 0xf4, 0xff, 0xff, 0xf4, 0xf, 0xff, 0xff, 0x4f, + 0xff, 0xff, 0x30, 0xff, 0xff, 0xf3, 0x9f, 0xff, + 0xc0, 0x9, 0xff, 0xfc, 0x0, + + /* U+F04D "" */ + 0x14, 0x44, 0x44, 0x44, 0x44, 0x42, 0xd, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x4f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9f, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x0, + + /* U+F051 "" */ + 0x2, 0x10, 0x0, 0x0, 0x42, 0xf, 0xe2, 0x0, + 0x3, 0xfb, 0xf, 0xfe, 0x30, 0x4, 0xfb, 0xf, + 0xff, 0xf4, 0x4, 0xfb, 0xf, 0xff, 0xff, 0x54, + 0xfb, 0xf, 0xff, 0xff, 0xfa, 0xfb, 0xf, 0xff, + 0xff, 0xff, 0xfb, 0xf, 0xff, 0xff, 0xff, 0xfb, + 0xf, 0xff, 0xff, 0xd6, 0xfb, 0xf, 0xff, 0xfd, + 0x14, 0xfb, 0xf, 0xff, 0xc1, 0x4, 0xfb, 0xf, + 0xfb, 0x0, 0x4, 0xfb, 0xc, 0xa0, 0x0, 0x3, + 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F052 "" */ + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x1, 0xef, + 0xff, 0xff, 0x40, 0x0, 0x0, 0x1d, 0xff, 0xff, + 0xff, 0xf3, 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, + 0xfe, 0x20, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x50, 0x5, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0xf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf4, 0xb, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd1, + + /* U+F053 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0x90, 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x3f, + 0xfd, 0x10, 0x0, 0x3f, 0xfd, 0x10, 0x0, 0x3f, + 0xfd, 0x10, 0x0, 0x1f, 0xfd, 0x10, 0x0, 0x0, + 0xcf, 0xf4, 0x0, 0x0, 0x0, 0xcf, 0xf4, 0x0, + 0x0, 0x0, 0xcf, 0xf4, 0x0, 0x0, 0x0, 0xcf, + 0xf4, 0x0, 0x0, 0x0, 0xcf, 0xe0, 0x0, 0x0, + 0x0, 0xa4, 0x0, + + /* U+F054 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, 0x10, 0x0, + 0x0, 0x1f, 0xfd, 0x10, 0x0, 0x0, 0x3f, 0xfd, + 0x10, 0x0, 0x0, 0x3f, 0xfd, 0x10, 0x0, 0x0, + 0x3f, 0xfd, 0x10, 0x0, 0x0, 0x3f, 0xfd, 0x0, + 0x0, 0x8, 0xff, 0x90, 0x0, 0x8, 0xff, 0x90, + 0x0, 0x8, 0xff, 0x90, 0x0, 0x8, 0xff, 0x90, + 0x0, 0x2, 0xff, 0x90, 0x0, 0x0, 0x7, 0x80, + 0x0, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf7, 0x0, 0x0, + 0x6, 0x99, 0x9a, 0xff, 0xc9, 0x99, 0x80, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x1, 0x11, 0x3f, 0xf7, + 0x11, 0x10, 0x0, 0x0, 0x3, 0xff, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xd3, 0x0, 0x0, 0x0, + + /* U+F068 "" */ + 0x69, 0x99, 0x99, 0x99, 0x99, 0x98, 0xf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F06E "" */ + 0x0, 0x0, 0x1, 0x56, 0x64, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xbf, 0xfe, 0xef, 0xf9, 0x10, 0x0, + 0x0, 0x7f, 0xfa, 0x10, 0x3, 0xdf, 0xe4, 0x0, + 0x8, 0xff, 0xa0, 0x9, 0xb4, 0x1e, 0xff, 0x50, + 0x4f, 0xff, 0x20, 0xb, 0xff, 0x26, 0xff, 0xe1, + 0xef, 0xff, 0x9, 0xcf, 0xff, 0x63, 0xff, 0xfa, + 0xbf, 0xff, 0x9, 0xff, 0xff, 0x54, 0xff, 0xf6, + 0x1e, 0xff, 0x51, 0xdf, 0xfb, 0x9, 0xff, 0xb0, + 0x3, 0xef, 0xe2, 0x4, 0x30, 0x5f, 0xfc, 0x10, + 0x0, 0x2c, 0xff, 0x95, 0x6a, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x49, 0xdf, 0xfd, 0x92, 0x0, 0x0, + + /* U+F070 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0xf5, 0x0, 0x14, 0x66, 0x40, + 0x0, 0x0, 0x0, 0x4, 0xef, 0xac, 0xff, 0xef, + 0xff, 0x91, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xa1, + 0x0, 0x4d, 0xfe, 0x30, 0x0, 0x0, 0x0, 0x9f, + 0xf5, 0xab, 0x31, 0xef, 0xf4, 0x0, 0x7, 0xb1, + 0x5, 0xff, 0xff, 0xe1, 0x7f, 0xfe, 0x10, 0xf, + 0xfe, 0x30, 0x2d, 0xff, 0xf5, 0x4f, 0xff, 0x90, + 0xc, 0xff, 0xe0, 0x0, 0xaf, 0xf6, 0x5f, 0xff, + 0x60, 0x2, 0xff, 0xf4, 0x0, 0x6, 0xff, 0xef, + 0xfb, 0x0, 0x0, 0x4f, 0xfd, 0x10, 0x0, 0x3e, + 0xff, 0xc0, 0x0, 0x0, 0x2, 0xdf, 0xe8, 0x54, + 0x1, 0xbf, 0xe3, 0x0, 0x0, 0x0, 0x5, 0xae, + 0xff, 0x60, 0x7, 0xff, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4e, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa1, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xff, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xfc, 0xcf, + 0xf4, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xfb, 0x0, + 0xff, 0xd0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xc0, + 0xf, 0xff, 0x70, 0x0, 0x0, 0x4, 0xff, 0xfd, + 0x1, 0xff, 0xff, 0x10, 0x0, 0x0, 0xdf, 0xff, + 0xe0, 0x2f, 0xff, 0xfa, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0x9b, 0xff, 0xff, 0xf3, 0x0, 0x1f, 0xff, + 0xff, 0xb0, 0xe, 0xff, 0xff, 0xc0, 0xa, 0xff, + 0xff, 0xfe, 0x24, 0xff, 0xff, 0xff, 0x60, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x6, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0x30, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0x80, 0xdd, 0xdb, + 0x0, 0x0, 0x8d, 0xef, 0xf8, 0xff, 0xff, 0xb0, + 0x7, 0xff, 0xff, 0xfd, 0x55, 0x6f, 0xf4, 0x6f, + 0xf8, 0xaf, 0xe2, 0x0, 0x5, 0x74, 0xff, 0x90, + 0x7e, 0x20, 0x0, 0x0, 0x3f, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xef, 0xb2, 0x50, 0x4a, 0x0, + 0x1, 0x2e, 0xfd, 0x1d, 0xf4, 0x8f, 0xb0, 0xff, + 0xff, 0xd1, 0xb, 0xff, 0xff, 0xfb, 0xff, 0xfe, + 0x20, 0x0, 0xcf, 0xff, 0xfb, 0x12, 0x21, 0x0, + 0x0, 0x2, 0x9f, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0x0, + + /* U+F077 "" */ + 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x8, 0xff, + 0xff, 0xb0, 0x0, 0x0, 0x8, 0xff, 0x95, 0xff, + 0xb0, 0x0, 0x8, 0xff, 0x90, 0x5, 0xff, 0xb0, + 0x7, 0xff, 0x90, 0x0, 0x5, 0xff, 0xb0, 0x9f, + 0x90, 0x0, 0x0, 0x5, 0xfd, 0x0, 0x40, 0x0, + 0x0, 0x0, 0x3, 0x10, + + /* U+F078 "" */ + 0x4c, 0x20, 0x0, 0x0, 0x0, 0xb6, 0xb, 0xfe, + 0x20, 0x0, 0x0, 0xcf, 0xf0, 0x2e, 0xfe, 0x20, + 0x0, 0xcf, 0xf4, 0x0, 0x2e, 0xfe, 0x20, 0xcf, + 0xf4, 0x0, 0x0, 0x2e, 0xfe, 0xcf, 0xf4, 0x0, + 0x0, 0x0, 0x2e, 0xff, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x13, 0x0, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x8, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xf3, 0x8, 0xbb, 0xbb, 0xbb, + 0x90, 0x0, 0xb, 0xff, 0xff, 0x39, 0xff, 0xff, + 0xff, 0xf1, 0x0, 0x8f, 0xcf, 0xcf, 0xf0, 0x0, + 0x0, 0xa, 0xf1, 0x0, 0x38, 0x2f, 0x94, 0x80, + 0x0, 0x0, 0xa, 0xf1, 0x0, 0x0, 0x2f, 0x90, + 0x0, 0x0, 0x0, 0xa, 0xf1, 0x0, 0x0, 0x2f, + 0x90, 0x0, 0x0, 0x3, 0xa, 0xf1, 0x30, 0x0, + 0x2f, 0x90, 0x0, 0x0, 0x1f, 0xcb, 0xf8, 0xf8, + 0x0, 0x2f, 0xeb, 0xbb, 0xbb, 0x39, 0xff, 0xff, + 0xe2, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xb0, 0x9f, + 0xfd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xd1, 0x0, + + /* U+F07B "" */ + 0x37, 0x88, 0x87, 0x0, 0x0, 0x0, 0x0, 0xef, + 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xfd, 0xcc, 0xcc, 0xb6, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x1, 0xdf, + 0xff, 0xfd, 0x10, 0x0, 0x0, 0x1d, 0xff, 0xff, + 0xff, 0xd1, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, + 0xf9, 0x0, 0x0, 0x1, 0x1c, 0xff, 0xc1, 0x10, + 0x0, 0x0, 0x0, 0xc, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xff, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xc0, 0x0, 0x0, 0x79, 0x99, + 0x3b, 0xff, 0xb3, 0x99, 0x97, 0xff, 0xff, 0xb2, + 0x44, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xdd, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, + 0xb3, 0xcf, 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xca, + + /* U+F095 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0xc7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xff, 0xfd, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xff, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xff, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xff, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xef, 0xf3, 0x0, 0x0, 0x4a, 0x30, 0x2, + 0xdf, 0xf8, 0x0, 0x5, 0xdf, 0xfe, 0x15, 0xef, + 0xfb, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, 0xfa, + 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x0, 0x0, 0x7f, 0xff, 0xff, 0xa2, 0x0, 0x0, + 0x0, 0x2, 0xba, 0x85, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F0C4 "" */ + 0x4, 0x86, 0x0, 0x0, 0x0, 0x10, 0x6, 0xff, + 0xfa, 0x0, 0x2, 0xdf, 0xd1, 0xef, 0x3c, 0xf1, + 0x1, 0xdf, 0xfa, 0xe, 0xe0, 0xaf, 0x21, 0xdf, + 0xfa, 0x0, 0x9f, 0xef, 0xf6, 0xdf, 0xfa, 0x0, + 0x0, 0x8d, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, + 0x6, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x48, 0xef, + 0xff, 0xf6, 0x0, 0x0, 0x6f, 0xff, 0xfb, 0xff, + 0xf6, 0x0, 0xe, 0xf3, 0xcf, 0x23, 0xff, 0xf6, + 0x0, 0xee, 0xa, 0xf2, 0x4, 0xff, 0xf6, 0x9, + 0xfe, 0xfc, 0x0, 0x4, 0xff, 0xf1, 0x8, 0xda, + 0x10, 0x0, 0x2, 0x62, 0x0, + + /* U+F0C5 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xf9, 0x87, 0x0, 0x0, 0x8, 0xff, + 0xff, 0x98, 0xf7, 0x8, 0xa6, 0x8f, 0xff, 0xf9, + 0x59, 0x90, 0xff, 0xa8, 0xff, 0xff, 0xfc, 0xcc, + 0xf, 0xfa, 0x8f, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfa, 0x8f, + 0xff, 0xff, 0xff, 0xf1, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xff, 0x1f, 0xfa, 0x8f, 0xff, 0xff, 0xff, + 0xf1, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfa, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xe3, + 0x12, 0x22, 0x22, 0x21, 0xf, 0xff, 0xff, 0xff, + 0xf9, 0x0, 0x0, 0xac, 0xcc, 0xcc, 0xcb, 0x50, + 0x0, 0x0, + + /* U+F0C7 "" */ + 0x49, 0x99, 0x99, 0x99, 0x95, 0x0, 0xe, 0xff, + 0xff, 0xff, 0xff, 0xf6, 0x0, 0xfd, 0x22, 0x22, + 0x22, 0x4f, 0xf6, 0xf, 0xc0, 0x0, 0x0, 0x1, + 0xff, 0xf3, 0xfc, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0x6f, 0xc0, 0x0, 0x0, 0x2, 0xff, 0xf6, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, + 0xdc, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xb0, 0x5, + 0xff, 0xff, 0x6f, 0xff, 0xf6, 0x0, 0xf, 0xff, + 0xf6, 0xff, 0xff, 0xc0, 0x6, 0xff, 0xff, 0x6f, + 0xff, 0xff, 0xed, 0xff, 0xff, 0xf6, 0x9f, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x10, + + /* U+F0C9 "" */ + 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x2f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0x12, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xde, + 0xee, 0xee, 0xee, 0xee, 0xee, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0E0 "" */ + 0x37, 0x88, 0x88, 0x88, 0x88, 0x88, 0x73, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1c, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc1, 0xd2, 0x8f, 0xff, 0xff, + 0xff, 0xf8, 0x2d, 0xff, 0x64, 0xef, 0xff, 0xfe, + 0x45, 0xff, 0xff, 0xfa, 0x2b, 0xff, 0xb2, 0xaf, + 0xff, 0xff, 0xff, 0xd3, 0x55, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, + + /* U+F0E7 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, + 0xf0, 0x0, 0x4, 0xff, 0xff, 0xd0, 0x0, 0x6, + 0xff, 0xff, 0x80, 0x0, 0x8, 0xff, 0xff, 0x30, + 0x0, 0xa, 0xff, 0xff, 0xaa, 0xa6, 0xc, 0xff, + 0xff, 0xff, 0xf8, 0xe, 0xff, 0xff, 0xff, 0xe1, + 0xb, 0xdd, 0xdf, 0xff, 0x60, 0x0, 0x0, 0x4f, + 0xfd, 0x0, 0x0, 0x0, 0x7f, 0xf3, 0x0, 0x0, + 0x0, 0xbf, 0xa0, 0x0, 0x0, 0x0, 0xff, 0x10, + 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x0, 0x3, + 0xc0, 0x0, 0x0, + + /* U+F0EA "" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x4, 0x55, + 0xef, 0xb5, 0x52, 0x0, 0x0, 0xff, 0xfd, 0x1f, + 0xff, 0xb0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xfc, + 0x0, 0x0, 0xff, 0xff, 0x53, 0x33, 0x20, 0x0, + 0xf, 0xff, 0x97, 0xff, 0xfb, 0x57, 0x0, 0xff, + 0xf8, 0xaf, 0xff, 0xc6, 0xf8, 0xf, 0xff, 0x8a, + 0xff, 0xfc, 0x4a, 0xa1, 0xff, 0xf8, 0xaf, 0xff, + 0xe3, 0x22, 0xf, 0xff, 0x8a, 0xff, 0xff, 0xff, + 0xf4, 0xff, 0xf8, 0xaf, 0xff, 0xff, 0xff, 0x4f, + 0xff, 0x8a, 0xff, 0xff, 0xff, 0xf4, 0x35, 0x52, + 0xaf, 0xff, 0xff, 0xff, 0x40, 0x0, 0xa, 0xff, + 0xff, 0xff, 0xf4, 0x0, 0x0, 0x7f, 0xff, 0xff, + 0xfe, 0x20, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8f, + 0xfa, 0x30, 0x0, 0x0, 0x2, 0xef, 0xff, 0xff, + 0x50, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xff, 0x10, + 0x0, 0x1f, 0xff, 0xff, 0xff, 0xf5, 0x0, 0x3, + 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, 0x5f, 0xff, + 0xff, 0xff, 0xf9, 0x0, 0x8, 0xff, 0xff, 0xff, + 0xff, 0xc0, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0x20, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x2, 0x22, + 0x22, 0x22, 0x22, 0x21, 0x0, 0x0, 0x8, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xa2, 0x0, + 0x0, 0x0, + + /* U+F11C "" */ + 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xa3, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0xfc, 0xc, 0x30, 0xe1, 0x1d, 0xd, 0x11, 0xfc, + 0xfc, 0xb, 0x30, 0xe0, 0x1d, 0xd, 0x10, 0xfc, + 0xff, 0xfe, 0xff, 0xef, 0xfe, 0xfe, 0xef, 0xfc, + 0xff, 0xf1, 0x5a, 0x8, 0x70, 0xa0, 0x5f, 0xfc, + 0xff, 0xf3, 0x7b, 0x29, 0x92, 0xc2, 0x7f, 0xfc, + 0xff, 0xbf, 0xcb, 0xbb, 0xbb, 0xbf, 0xcb, 0xfc, + 0xfc, 0xb, 0x20, 0x0, 0x0, 0xd, 0x0, 0xfc, + 0xff, 0xcf, 0xcc, 0xcc, 0xcc, 0xcf, 0xcc, 0xfb, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xdf, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xef, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0x18, 0xff, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x29, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x0, + 0x4, 0x9a, 0xaa, 0xaf, 0xff, 0xff, 0x20, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xff, 0xfb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xff, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xff, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0xfd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xb3, 0x0, 0x0, 0x0, + + /* U+F15B "" */ + 0x35, 0x55, 0x55, 0x2, 0x0, 0xf, 0xff, 0xff, + 0xf2, 0xf4, 0x0, 0xff, 0xff, 0xff, 0x2f, 0xf4, + 0xf, 0xff, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xff, + 0xff, 0x32, 0x22, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x8a, 0xaa, 0xaa, + 0xaa, 0xaa, 0x30, + + /* U+F1EB "" */ + 0x0, 0x0, 0x0, 0x24, 0x55, 0x31, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xaf, 0xff, 0xff, 0xff, 0xc7, + 0x0, 0x0, 0x2, 0xbf, 0xff, 0xfe, 0xde, 0xff, + 0xff, 0xf6, 0x0, 0x5f, 0xff, 0xb5, 0x10, 0x0, + 0x3, 0x8e, 0xff, 0xb0, 0xdf, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0xf5, 0x18, 0x0, 0x5, + 0xae, 0xfe, 0xc8, 0x10, 0x4, 0x60, 0x0, 0x2, + 0xdf, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, + 0xc, 0xff, 0x95, 0x34, 0x7d, 0xff, 0x40, 0x0, + 0x0, 0x2, 0xa2, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x96, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xda, 0x0, 0x0, 0x0, 0x0, + + /* U+F240 "" */ + 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, + 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0xfc, 0x12, 0x22, 0x22, 0x22, 0x22, + 0x22, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x2c, 0xfa, 0xfc, 0x5f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x21, 0xfa, 0xfc, 0x5f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x27, 0xfa, 0xfc, 0x26, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x1f, 0xfa, 0xfe, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F241 "" */ + 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, + 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0xfc, 0x12, 0x22, 0x22, 0x22, 0x21, + 0x0, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0xff, 0xff, + 0xf8, 0x0, 0xc, 0xfa, 0xfc, 0x5f, 0xff, 0xff, + 0xff, 0xf8, 0x0, 0x1, 0xfa, 0xfc, 0x5f, 0xff, + 0xff, 0xff, 0xf8, 0x0, 0x7, 0xfa, 0xfc, 0x26, + 0x66, 0x66, 0x66, 0x63, 0x0, 0xf, 0xfa, 0xfe, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F242 "" */ + 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, + 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0xfc, 0x12, 0x22, 0x22, 0x10, 0x0, + 0x0, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0xc, 0xfa, 0xfc, 0x5f, 0xff, 0xff, + 0xd0, 0x0, 0x0, 0x1, 0xfa, 0xfc, 0x5f, 0xff, + 0xff, 0xd0, 0x0, 0x0, 0x7, 0xfa, 0xfc, 0x26, + 0x66, 0x66, 0x50, 0x0, 0x0, 0xf, 0xfa, 0xfe, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F243 "" */ + 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, + 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0xfc, 0x12, 0x22, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0x30, 0x0, + 0x0, 0x0, 0xc, 0xfa, 0xfc, 0x5f, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x1, 0xfa, 0xfc, 0x5f, 0xff, + 0x30, 0x0, 0x0, 0x0, 0x7, 0xfa, 0xfc, 0x26, + 0x66, 0x10, 0x0, 0x0, 0x0, 0xf, 0xfa, 0xfe, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F244 "" */ + 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, + 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xf7, 0xfc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xfa, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xfa, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xfa, 0xfc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfa, 0xfe, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F287 "" */ + 0x0, 0x0, 0x0, 0x0, 0x7, 0xb2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9, 0x3d, 0xf5, + 0x0, 0x0, 0x0, 0x4, 0x40, 0x2, 0xe0, 0x0, + 0x10, 0x0, 0x0, 0x0, 0xaf, 0xf8, 0xb, 0x60, + 0x0, 0x0, 0x0, 0x6c, 0x30, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xaf, 0xf9, + 0x0, 0xc, 0x50, 0x0, 0x0, 0x6d, 0x40, 0x5, + 0x50, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc4, 0x3e, 0xe8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xef, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F293 "" */ + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x7, + 0xef, 0xff, 0xb3, 0x0, 0x0, 0xaf, 0xfd, 0x8f, + 0xff, 0x20, 0x4, 0xff, 0xfd, 0x9, 0xff, 0xb0, + 0xa, 0xfe, 0xfd, 0x12, 0xaf, 0xf0, 0xe, 0xf5, + 0x5d, 0x2c, 0xe, 0xf3, 0xf, 0xff, 0x33, 0x12, + 0x9f, 0xf5, 0xf, 0xff, 0xf3, 0x7, 0xff, 0xf6, + 0xf, 0xff, 0xe2, 0x6, 0xff, 0xf6, 0xf, 0xfe, + 0x24, 0x13, 0x7f, 0xf5, 0xd, 0xf5, 0x7d, 0x2c, + 0xd, 0xf3, 0xa, 0xff, 0xfd, 0x11, 0xbf, 0xf0, + 0x3, 0xff, 0xfe, 0xb, 0xff, 0xa0, 0x0, 0x7f, + 0xfe, 0xbf, 0xfe, 0x10, 0x0, 0x3, 0xac, 0xdc, + 0x81, 0x0, + + /* U+F2ED "" */ + 0x0, 0x0, 0x34, 0x43, 0x0, 0x0, 0x5, 0x66, + 0x7f, 0xff, 0xf9, 0x66, 0x50, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x35, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x50, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc4, + 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x2f, + 0xf3, 0xfb, 0x7f, 0x6d, 0xf6, 0x2, 0xff, 0x2f, + 0xb7, 0xf5, 0xdf, 0x60, 0x2f, 0xf2, 0xfb, 0x7f, + 0x5d, 0xf6, 0x2, 0xff, 0x2f, 0xb7, 0xf5, 0xdf, + 0x60, 0x2f, 0xf2, 0xfb, 0x7f, 0x5d, 0xf6, 0x2, + 0xff, 0x2f, 0xb7, 0xf5, 0xdf, 0x60, 0x2f, 0xf3, + 0xfb, 0x7f, 0x6d, 0xf6, 0x1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x50, 0x7, 0xbc, 0xcc, 0xcc, 0xcc, + 0x90, 0x0, + + /* U+F304 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xff, 0xff, 0x50, 0x0, + 0x0, 0x0, 0x4, 0x39, 0xff, 0xfe, 0x0, 0x0, + 0x0, 0x4, 0xff, 0x39, 0xff, 0xa0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0x39, 0xb0, 0x0, 0x0, 0x4, + 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x4, 0xff, + 0xff, 0xff, 0xb0, 0x0, 0x0, 0x4, 0xff, 0xff, + 0xff, 0xb0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, + 0xb0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0xd, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xa8, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F55A "" */ + 0x0, 0x0, 0x17, 0x88, 0x88, 0x88, 0x88, 0x87, + 0x40, 0x0, 0x2, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0x0, 0x3e, 0xff, 0xff, 0xcf, 0xff, + 0xcf, 0xff, 0xf7, 0x3, 0xef, 0xff, 0xf9, 0x8, + 0xf8, 0x9, 0xff, 0xf8, 0x3e, 0xff, 0xff, 0xfe, + 0x20, 0x40, 0x2e, 0xff, 0xf8, 0xdf, 0xff, 0xff, + 0xff, 0xe1, 0x1, 0xef, 0xff, 0xf8, 0x9f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x8f, 0xff, 0xf8, 0x9, + 0xff, 0xff, 0xf9, 0x2, 0xc2, 0x9, 0xff, 0xf8, + 0x0, 0x9f, 0xff, 0xfe, 0x4e, 0xfe, 0x4e, 0xff, + 0xf8, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf7, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc1, + + /* U+F7C2 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xef, + 0xff, 0xff, 0xe2, 0x3, 0xfb, 0xfb, 0xce, 0xbf, + 0xa4, 0xff, 0x1d, 0x3, 0xa1, 0xfa, 0xff, 0xf1, + 0xd0, 0x3a, 0x1f, 0xaf, 0xff, 0xff, 0xff, 0xff, + 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, + 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x29, 0xaa, 0xaa, + 0xaa, 0xa8, 0x0, + + /* U+F8A2 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xf1, 0x0, + 0x8, 0x20, 0x0, 0x0, 0x1, 0xff, 0x10, 0xb, + 0xf7, 0x0, 0x0, 0x0, 0x2f, 0xf1, 0xc, 0xff, + 0x94, 0x44, 0x44, 0x45, 0xff, 0x1b, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x0, 0x7f, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+FF08 "(" */ + 0x0, 0x0, 0x20, 0x0, 0x61, 0x0, 0x81, 0x0, + 0x46, 0x0, 0xb, 0x10, 0x0, 0xc0, 0x0, 0xc, + 0x0, 0x0, 0xb0, 0x0, 0x4, 0x60, 0x0, 0x8, + 0x20, 0x0, 0x6, 0x20, 0x0, 0x1, + + /* U+FF09 ")" */ + 0x30, 0x0, 0x1, 0x70, 0x0, 0x1, 0x90, 0x0, + 0x6, 0x60, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, + 0xd, 0x0, 0x0, 0xc0, 0x0, 0x66, 0x0, 0x2a, + 0x0, 0x27, 0x0, 0x2, 0x0, 0x0, + + /* U+FF0C "," */ + 0x1, 0x0, 0xfc, 0x7, 0xb0, 0x63, 0x3, 0x0, + + /* U+FF11 "1" */ + 0x0, 0x23, 0x0, 0x5, 0xd6, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x86, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x86, 0x0, 0x0, 0x86, 0x0, + 0x0, 0x96, 0x0, 0x14, 0x66, 0x40, + + /* U+FF12 "2" */ + 0x0, 0x0, 0x0, 0x7, 0x67, 0x91, 0x87, 0x0, + 0x99, 0x69, 0x0, 0x8b, 0x0, 0x0, 0xd5, 0x0, + 0x6, 0x80, 0x0, 0x39, 0x0, 0x2, 0x90, 0x0, + 0x19, 0x0, 0x3, 0xab, 0xaa, 0xb4, 0x12, 0x22, + 0x20 +}; + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 112, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 112, .box_w = 3, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 15, .adv_w = 112, .box_w = 6, .box_h = 4, .ofs_x = 0, .ofs_y = 8}, + {.bitmap_index = 27, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 62, .adv_w = 112, .box_w = 6, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 143, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 178, .adv_w = 112, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 8}, + {.bitmap_index = 184, .adv_w = 112, .box_w = 4, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 214, .adv_w = 112, .box_w = 4, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 244, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 272, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 304, .adv_w = 112, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 310, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 314, .adv_w = 112, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 317, .adv_w = 112, .box_w = 7, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 366, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 401, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 426, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 461, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 496, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 531, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 566, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 601, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 636, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 671, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 706, .adv_w = 112, .box_w = 3, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 717, .adv_w = 112, .box_w = 3, .box_h = 9, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 731, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 770, .adv_w = 112, .box_w = 7, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 784, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 823, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 858, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 893, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 928, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 963, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 998, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1033, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1068, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1103, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1138, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1173, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1198, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1240, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1275, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1310, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1345, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1380, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1415, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1450, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1489, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1524, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1559, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1594, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1629, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1664, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1699, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1734, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1769, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1804, .adv_w = 112, .box_w = 5, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 1839, .adv_w = 112, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1878, .adv_w = 112, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1913, .adv_w = 112, .box_w = 5, .box_h = 2, .ofs_x = 1, .ofs_y = 10}, + {.bitmap_index = 1918, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1922, .adv_w = 112, .box_w = 3, .box_h = 2, .ofs_x = 1, .ofs_y = 10}, + {.bitmap_index = 1925, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1950, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1989, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2014, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2053, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2078, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2113, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2145, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2184, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2209, .adv_w = 112, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 2239, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2278, .adv_w = 112, .box_w = 5, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2306, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2331, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2356, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2381, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2413, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2445, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2470, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2488, .adv_w = 112, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2515, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2540, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2565, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2590, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2615, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2647, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2672, .adv_w = 112, .box_w = 4, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 2700, .adv_w = 112, .box_w = 1, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 2708, .adv_w = 112, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 2736, .adv_w = 112, .box_w = 7, .box_h = 3, .ofs_x = 0, .ofs_y = 10}, + {.bitmap_index = 2747, .adv_w = 112, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2747, .adv_w = 224, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2757, .adv_w = 224, .box_w = 4, .box_h = 5, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2767, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 2811, .adv_w = 224, .box_w = 4, .box_h = 12, .ofs_x = 8, .ofs_y = -1}, + {.bitmap_index = 2835, .adv_w = 224, .box_w = 4, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2859, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 2895, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2955, .adv_w = 224, .box_w = 8, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 2983, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3028, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 3076, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 3112, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3172, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3238, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3304, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3370, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 3418, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3484, .adv_w = 224, .box_w = 6, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 3520, .adv_w = 224, .box_w = 9, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 3574, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3646, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3731, .adv_w = 224, .box_w = 9, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3776, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3837, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 3881, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3953, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 4001, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 4049, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4121, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4205, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4260, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4332, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4392, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4464, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4524, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4590, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 4645, .adv_w = 224, .box_w = 9, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 4677, .adv_w = 224, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4727, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 4787, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 4837, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4903, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 4951, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5012, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5078, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5123, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5183, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5255, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5316, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5382, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5454, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5526, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5592, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5664, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5736, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5786, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5846, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5901, .adv_w = 224, .box_w = 12, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 5949, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 6003, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 6057, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 6112, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6184, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6250, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6298, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6359, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6420, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6481, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6529, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 6574, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6640, .adv_w = 224, .box_w = 8, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6672, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 6733, .adv_w = 224, .box_w = 7, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6761, .adv_w = 224, .box_w = 8, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 6801, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6849, .adv_w = 224, .box_w = 7, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 6891, .adv_w = 224, .box_w = 9, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6941, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7013, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7068, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7140, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7200, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7261, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 7297, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7357, .adv_w = 224, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7397, .adv_w = 224, .box_w = 9, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7451, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7511, .adv_w = 224, .box_w = 9, .box_h = 6, .ofs_x = 2, .ofs_y = 1}, + {.bitmap_index = 7538, .adv_w = 224, .box_w = 11, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 7582, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7648, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7703, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7775, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7835, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7901, .adv_w = 224, .box_w = 9, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7955, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8021, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 8076, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8142, .adv_w = 224, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 1}, + {.bitmap_index = 8178, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 8238, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8304, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8382, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 8437, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 8498, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 8553, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 8619, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 8674, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 8746, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 8790, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 8850, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8935, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9001, .adv_w = 224, .box_w = 8, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 9033, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 9088, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 9143, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9215, .adv_w = 224, .box_w = 6, .box_h = 11, .ofs_x = 5, .ofs_y = -1}, + {.bitmap_index = 9248, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 5, .ofs_y = -1}, + {.bitmap_index = 9292, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 9347, .adv_w = 224, .box_w = 12, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 9389, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 9449, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 9499, .adv_w = 224, .box_w = 12, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 9541, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 9601, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 9661, .adv_w = 224, .box_w = 8, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 9701, .adv_w = 224, .box_w = 9, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 9746, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 9796, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 9846, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 9924, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10002, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 10056, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 10116, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10166, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10232, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10287, .adv_w = 224, .box_w = 10, .box_h = 8, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10327, .adv_w = 224, .box_w = 6, .box_h = 11, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 10360, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10410, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10465, .adv_w = 224, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 10515, .adv_w = 224, .box_w = 10, .box_h = 8, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10555, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10616, .adv_w = 224, .box_w = 10, .box_h = 6, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10646, .adv_w = 224, .box_w = 8, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 10674, .adv_w = 224, .box_w = 9, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10719, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10774, .adv_w = 224, .box_w = 7, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 10813, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 10867, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 10903, .adv_w = 224, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 10939, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10994, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 11039, .adv_w = 224, .box_w = 8, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 11071, .adv_w = 224, .box_w = 14, .box_h = 3, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 11092, .adv_w = 224, .box_w = 14, .box_h = 2, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 11106, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11197, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 11282, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 11380, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11464, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11555, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 11640, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 11738, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 11836, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11920, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12018, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12116, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12207, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 12284, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12375, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12473, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12564, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12662, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12845, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12943, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13034, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 13111, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 13196, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 13294, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 13392, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 13462, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13546, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13630, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13721, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 13819, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 13910, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14008, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14106, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14204, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14302, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14596, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14694, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14890, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14988, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 15072, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15170, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15268, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15366, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15464, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15555, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15653, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15751, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15849, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15947, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16045, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16143, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16241, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16339, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16430, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16528, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16626, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16724, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16822, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16920, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17018, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17116, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17214, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17305, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17403, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17501, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17599, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17697, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17795, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17893, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17991, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18089, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18180, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18278, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18376, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18474, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18572, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18670, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18866, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18964, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19062, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19160, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19258, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19356, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19454, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19552, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19650, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19748, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19846, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19944, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 20029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20120, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 20211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20309, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20407, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20505, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20603, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20701, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 20792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20890, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20974, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 21051, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21149, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 21240, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21338, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21436, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21534, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21632, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21730, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21828, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 21905, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 21977, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22068, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22166, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22257, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22348, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22446, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22544, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22642, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22740, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22838, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 22922, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23020, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23118, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23216, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23314, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23412, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23510, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23608, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23699, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23797, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23888, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23986, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24084, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24182, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 24273, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24371, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 24462, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24560, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24658, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24756, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24847, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24938, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25036, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25134, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25232, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25330, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 25421, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25519, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25617, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25715, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25813, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25911, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26009, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 26100, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26198, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26296, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26394, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 26478, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26576, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26674, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26772, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26870, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26968, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27066, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27164, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27262, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27360, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 27444, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27542, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27640, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27731, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27822, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27913, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28011, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28109, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28200, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28291, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28389, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28487, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28585, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28683, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 28744, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28842, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28940, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29031, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29115, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29199, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29290, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29374, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29465, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29550, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29641, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29719, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 29804, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29902, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30000, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30084, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 30169, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 30246, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30337, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 30415, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30500, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30591, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30669, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30760, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30851, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30942, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31040, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31138, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31229, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31313, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31397, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31482, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31580, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31665, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31756, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 31847, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31938, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 32029, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32120, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 32211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32309, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32400, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 32491, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32569, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 32660, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32758, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 32835, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 32907, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 32998, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33082, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33166, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 33243, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33327, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33418, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33502, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33586, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33677, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33866, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33957, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34055, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34153, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 34244, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34335, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34433, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34531, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34629, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34727, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34825, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34923, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35021, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35119, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35217, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35315, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35413, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35504, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 35595, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 35686, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35777, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35973, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36064, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36155, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36239, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36533, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36631, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36729, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36827, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36925, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37023, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37121, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37219, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37317, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37415, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37513, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37611, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37709, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37807, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37905, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38003, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38101, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38192, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38290, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38388, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38486, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38584, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38682, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38780, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38878, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38976, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39074, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39172, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39270, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39368, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39466, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39564, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39655, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39753, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39851, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39949, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40040, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40131, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40222, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40411, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40509, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40600, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40691, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40782, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40880, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40971, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41069, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41167, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41265, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41356, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41454, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41552, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41650, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41741, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41839, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41923, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42021, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42112, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42210, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42308, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42399, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42497, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42595, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42693, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42791, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42882, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42980, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43078, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 43162, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43253, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 43337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43533, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43624, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43715, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43806, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43897, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43995, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44093, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44191, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44282, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 44360, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44549, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44640, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44731, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44815, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44900, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44998, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45076, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45148, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 45239, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45337, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45428, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45526, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 45617, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45715, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45813, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45911, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46009, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46107, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 46198, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 46289, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46387, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46485, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46583, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46681, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46772, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46870, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46968, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47066, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47164, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47262, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47360, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47549, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47647, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47745, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47843, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47941, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48039, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 48116, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 48207, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48298, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48396, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48487, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 48571, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48669, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48767, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48865, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48963, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49061, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49159, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49257, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49355, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49453, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49551, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49649, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49845, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49943, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50041, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50125, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50210, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50301, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50399, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50497, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50595, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50693, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50784, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50973, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51064, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51162, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51247, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51332, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51423, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51521, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51612, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51703, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 51788, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51879, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 51957, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 52041, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52139, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 52224, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52322, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 52407, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52505, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52603, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52694, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52890, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52988, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53086, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53184, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53282, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53380, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53478, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53576, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53674, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53772, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53863, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53961, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54059, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54157, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54255, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54549, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54640, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54738, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54836, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54934, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55032, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55130, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55221, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55319, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55417, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55515, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55613, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55711, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55809, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55907, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56005, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56103, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56201, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56299, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56397, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56495, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56593, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56691, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56789, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56887, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56985, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57083, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57181, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57279, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57377, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57468, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57566, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57664, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57762, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57860, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57958, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58056, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58154, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58252, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58350, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58448, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58546, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58644, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58742, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58840, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58938, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59036, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59134, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59232, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59330, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59428, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 59519, .adv_w = 224, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 59578, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59656, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59747, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 59838, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59936, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 60013, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60097, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60195, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60286, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60377, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60475, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60566, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60664, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60748, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60839, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60930, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61021, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61119, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61210, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61294, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61379, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61477, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61568, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61659, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61750, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61841, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 61918, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62016, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 62107, .adv_w = 224, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 62177, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 62261, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62359, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62457, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 62534, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62632, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62717, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62808, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62906, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63004, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63102, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63200, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63298, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63396, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63494, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63592, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63690, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63788, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63886, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63984, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64082, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64180, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64271, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64369, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64467, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64565, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64663, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64761, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64852, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64950, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65048, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65146, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65244, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65342, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65440, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65538, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65636, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65734, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65832, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65930, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66028, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66126, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66224, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66322, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66420, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66518, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66616, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66714, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66812, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66910, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67008, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67106, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67204, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67302, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67596, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67694, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67890, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67988, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68086, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68184, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68282, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68373, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68464, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68555, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68653, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 68744, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68842, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68940, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69038, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69136, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69234, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69332, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69430, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69528, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69626, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69724, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69822, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 69900, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69984, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 70068, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 70159, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70257, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70355, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70453, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70551, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70649, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70845, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70936, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71034, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71132, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71230, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71321, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71419, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71517, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 71608, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71706, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71804, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 71895, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71993, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72091, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72189, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72287, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72385, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72483, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72581, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72679, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72777, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72973, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73064, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73162, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73253, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73344, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73442, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73540, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73638, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73736, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73834, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73932, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74023, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74114, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74212, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74310, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74408, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74506, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74604, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74702, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74800, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74898, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74996, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75094, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75192, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75290, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75381, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75479, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75570, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75668, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75766, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75864, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75955, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 76046, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76137, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 76228, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76319, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 76410, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76508, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76606, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76704, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76802, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76893, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76991, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77089, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77187, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77285, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77383, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77481, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77579, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77677, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77866, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77950, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78041, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78139, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78237, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 78328, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78419, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78510, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78601, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 78661, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 78738, .adv_w = 224, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 78808, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 78886, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 78970, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79055, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 79140, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79238, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79329, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79420, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79518, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79609, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79700, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79798, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79889, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79987, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80085, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 80176, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 80253, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 80344, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 80435, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 80519, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 80589, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 80680, .adv_w = 224, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 80739, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80830, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80921, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81019, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81117, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 81208, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 81292, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81390, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81488, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81586, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81677, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81775, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81873, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81971, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82069, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82167, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82265, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82363, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82461, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82559, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82657, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82755, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82853, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82951, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83049, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83147, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83245, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83343, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83441, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83539, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83637, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83735, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83833, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83931, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84120, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84309, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84394, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84492, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84590, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84688, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84786, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84884, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84982, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85080, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85178, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85276, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85374, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85472, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85570, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85661, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85759, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85857, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85955, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86046, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86137, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86333, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86431, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86529, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86627, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86725, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86823, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86914, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87012, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87110, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87208, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87306, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87404, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87502, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87600, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87698, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87796, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87894, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87992, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88090, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88188, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88286, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88384, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88475, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88573, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88671, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88769, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88867, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88965, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 89056, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89154, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89252, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89350, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89448, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 89532, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89630, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89728, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89826, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89924, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90022, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 90106, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90204, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90302, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90498, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 90575, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90666, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90764, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90855, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90946, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91037, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 91128, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91226, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91324, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91422, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91520, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91618, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91716, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91814, .adv_w = 224, .box_w = 9, .box_h = 14, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 91877, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91968, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92066, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92164, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92255, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92549, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92647, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 92724, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 92815, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92913, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93011, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93109, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93207, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93305, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93403, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93501, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93599, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93697, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93795, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93893, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93984, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94082, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94180, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94278, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94376, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94474, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94572, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94670, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94866, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94964, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95062, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95160, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95258, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95356, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95454, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95539, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95630, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95728, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95826, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95924, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96015, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96113, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96309, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96596, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96687, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96785, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96883, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96981, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97079, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97177, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97275, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97373, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97471, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97569, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97667, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97765, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97863, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97961, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98059, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98157, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98255, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98549, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98647, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98745, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98843, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98941, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99039, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99137, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99333, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99431, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99529, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99620, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99718, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99816, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99914, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100012, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100110, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100201, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100299, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100397, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100495, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100593, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100691, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 100782, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 100866, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100964, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101055, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101153, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101244, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101328, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101419, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101503, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101587, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101671, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101755, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101846, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101944, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102035, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102133, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102231, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102329, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102427, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102525, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102623, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102721, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 102805, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102903, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102994, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103099, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103197, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103295, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103393, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103491, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103589, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103687, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103785, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103883, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103974, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104072, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104170, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104261, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104359, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104457, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104548, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104646, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104744, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104835, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104933, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105017, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105115, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105213, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105311, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105402, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105500, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105598, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105696, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105794, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105885, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105983, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106081, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106179, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106277, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106375, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106466, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106564, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106655, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106753, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106851, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106949, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107047, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107145, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107243, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107341, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107439, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107530, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107615, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107713, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107811, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107909, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108000, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108091, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108189, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108287, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108385, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108476, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108567, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108665, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108763, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108861, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108959, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109057, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109148, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109239, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109533, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 109617, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 109701, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 109785, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 109876, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 109967, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110058, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110136, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110227, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110318, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110403, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110487, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110578, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110669, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110760, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110851, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110942, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111033, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111124, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111215, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111411, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111509, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111600, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111698, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111796, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111894, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111972, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112070, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 112161, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 112246, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112344, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112442, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112533, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112631, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112729, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112827, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112925, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113023, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113121, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113212, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 113303, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113401, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113499, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113597, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113695, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113793, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113891, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113989, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114087, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114185, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114283, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114381, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114479, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114570, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114668, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114766, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114864, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114962, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115060, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115158, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115256, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115354, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115452, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115550, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115648, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115746, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 115837, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115935, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116026, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116124, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116222, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116411, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 116496, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116594, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116692, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116790, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116888, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 117001, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 117078, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 117169, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 117246, .adv_w = 154, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 117301, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117406, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117511, .adv_w = 252, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 117615, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117720, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 117808, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117913, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 117955, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118021, .adv_w = 252, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118133, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 118210, .adv_w = 154, .box_w = 10, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118285, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 118355, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118453, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118538, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118623, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 118693, .adv_w = 196, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 118784, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118843, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118902, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118987, .adv_w = 196, .box_w = 13, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 119013, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 119101, .adv_w = 280, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119236, .adv_w = 252, .box_w = 17, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 119364, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119455, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 119507, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 119559, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 119658, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 119735, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119840, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 119953, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120038, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120136, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120221, .adv_w = 196, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120299, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 120376, .adv_w = 140, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 120451, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120549, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120647, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 120735, .adv_w = 224, .box_w = 16, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 120855, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120938, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121055, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121145, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121235, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121325, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121415, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121505, .adv_w = 280, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121613, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121703, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121801, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 121914, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122013, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122096, .adv_w = 225, .box_w = 15, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122171, .adv_w = 224, .box_w = 5, .box_h = 12, .ofs_x = 7, .ofs_y = -1}, + {.bitmap_index = 122201, .adv_w = 224, .box_w = 5, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 122231, .adv_w = 224, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 122239, .adv_w = 224, .box_w = 6, .box_h = 10, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 122269, .adv_w = 224, .box_w = 6, .box_h = 11, .ofs_x = 4, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1, 0x4, 0xb, 0xc, 0x40, 0x41, 0x42, + 0x43, 0x45, 0x46, 0x47 +}; + +static const uint8_t glyph_id_ofs_list_4[] = { + 0, 0, 0, 1, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 4, 5, 6, 0, 7, + 8, 9, 0, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 0, + 30, 31, 32, 0, 33, 34, 0, 35, + 36, 37, 38, 39, 40, 0, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 0, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 0, + 65, 66, 67, 68, 69, 70, 71 +}; + +static const uint16_t unicode_list_5[] = { + 0x0, 0x4, 0x7, 0xd, 0x1d11, 0x1d14, 0x1d18, 0x1d19, + 0x1d1a, 0x1d1b, 0x1d1c, 0x1d1e, 0x1d24, 0x1d25, 0x1d27, 0x1d32, + 0x1d37, 0x1d3e, 0x1d4c, 0x1d56, 0x1d5c, 0x1d5f, 0x1d60, 0x1d68, + 0x1d6e, 0x1d70, 0x1d97, 0x1d99, 0x1d9a, 0x1d9c, 0x1d9d, 0x1da5, + 0x1dac, 0x1db2, 0x1db5, 0x1db7, 0x1dbd, 0x1dcb, 0x1dd1, 0x1ddb, + 0x1ddc, 0x1dde, 0x1de6, 0x1de7, 0x1de9, 0x1df4, 0x1df5, 0x1df6, + 0x1dff, 0x1e07, 0x1e0c, 0x1e0e, 0x1e12, 0x1e1b, 0x1e22, 0x1e2b, + 0x1e2e, 0x1e49, 0x1e4d, 0x1e57, 0x1e5e, 0x1e5f, 0x1e60, 0x1e64, + 0x1e66, 0x1e6a, 0x1e6d, 0x1e71, 0x1e90, 0x1e97, 0x1e9c, 0x1eac, + 0x1eae, 0x1eb2, 0x1ed0, 0x1ed3, 0x1eee, 0x1ef2, 0x1eff, 0x1f1c, + 0x1f22, 0x1f2a, 0x1f30, 0x1f35, 0x1f4d, 0x1f6b, 0x1f6d, 0x1f76, + 0x1f85, 0x1faa, 0x1fc4, 0x1fd6, 0x1fde, 0x1fe0, 0x1fe6, 0x200a, + 0x2015, 0x203b, 0x2050, 0x2054, 0x2055, 0x2056, 0x2059, 0x205a, + 0x205c, 0x205e, 0x2063, 0x206b, 0x2076, 0x2078, 0x2079, 0x207a, + 0x207c, 0x207d, 0x207e, 0x2082, 0x2087, 0x2088, 0x2096, 0x2097, + 0x209b, 0x209e, 0x20aa, 0x20ac, 0x20bd, 0x20c8, 0x20de, 0x20ee, + 0x20f7, 0x210b, 0x2117, 0x2118, 0x211b, 0x2128, 0x212e, 0x2135, + 0x2136, 0x213a, 0x2141, 0x2147, 0x2149, 0x214c, 0x2158, 0x215b, + 0x215e, 0x216c, 0x2183, 0x2186, 0x2194, 0x21ac, 0x21b0, 0x21b1, + 0x21b9, 0x21ba, 0x21bb, 0x21c4, 0x21da, 0x21e6, 0x21ea, 0x21ee, + 0x21f5, 0x2206, 0x2216, 0x2227, 0x2228, 0x224c, 0x2251, 0x2252, + 0x2254, 0x2259, 0x225b, 0x2263, 0x2265, 0x2268, 0x2269, 0x2282, + 0x2284, 0x228c, 0x22ab, 0x22b0, 0x22c4, 0x22cc, 0x22d3, 0x22d4, + 0x22d9, 0x22db, 0x22dc, 0x22de, 0x22e7, 0x22e8, 0x22f4, 0x22f5, + 0x22f6, 0x22f7, 0x22fb, 0x22fc, 0x2300, 0x2301, 0x2303, 0x2304, + 0x2308, 0x2309, 0x2314, 0x2315, 0x2319, 0x231d, 0x231e, 0x2322, + 0x2337, 0x2338, 0x2351, 0x235b, 0x2373, 0x2379, 0x2384, 0x238d, + 0x238e, 0x239d, 0x23c3, 0x23d2, 0x23f2, 0x23fb, 0x2457, 0x245b, + 0x2460, 0x2477, 0x2495, 0x249a, 0x24ad, 0x24ae, 0x24bf, 0x24c7, + 0x24df, 0x2500, 0x252c, 0x25c5, 0x25ec, 0x25ef, 0x25f1, 0x2601, + 0x2604, 0x260e, 0x261c, 0x261e, 0x2623, 0x2629, 0x2630, 0x2634, + 0x2639, 0x2641, 0x2658, 0x265b, 0x2661, 0x269c, 0x26f0, 0x2708, + 0x270b, 0x2742, 0x2745, 0x275b, 0x277a, 0x2794, 0x27a8, 0x27af, + 0x27db, 0x27e4, 0x27fc, 0x2801, 0x2803, 0x281a, 0x2820, 0x2826, + 0x2827, 0x282b, 0x282d, 0x2831, 0x2838, 0x283a, 0x283b, 0x283c, + 0x283f, 0x2842, 0x2858, 0x2862, 0x2868, 0x2884, 0x288a, 0x288e, + 0x2893, 0x2898, 0x28c4, 0x28ca, 0x28cc, 0x28da, 0x28dc, 0x28e1, + 0x28e5, 0x2929, 0x296b, 0x2977, 0x29a3, 0x29ce, 0x29dd, 0x2a1a, + 0x2a61, 0x2a68, 0x2a69, 0x2a74, 0x2a77, 0x2a7a, 0x2a7c, 0x2a89, + 0x2a94, 0x2a96, 0x2a98, 0x2a99, 0x2a9a, 0x2a9d, 0x2aa9, 0x2aaa, + 0x2aab, 0x2aaf, 0x2ab0, 0x2ab3, 0x2ab5, 0x2ac4, 0x2ac6, 0x2ac7, + 0x2aca, 0x2ad0, 0x2ad5, 0x2ad7, 0x2add, 0x2ae3, 0x2aee, 0x2af0, + 0x2af7, 0x2afc, 0x2b0b, 0x2b0f, 0x2b15, 0x2b18, 0x2b19, 0x2b1e, + 0x2b1f, 0x2b20, 0x2b22, 0x2b2b, 0x2b35, 0x2b42, 0x2b4b, 0x2b51, + 0x2b56, 0x2b5b, 0x2b5c, 0x2b66, 0x2b76, 0x2b7d, 0x2b82, 0x2c07, + 0x2c5d, 0x2cee, 0x2cef, 0x2cf6, 0x2cf7, 0x2cff, 0x2d02, 0x2d03, + 0x2d13, 0x2d14, 0x2d19, 0x2d1d, 0x2d3c, 0x2d3e, 0x2d40, 0x2d41, + 0x2d44, 0x2d47, 0x2d49, 0x2d56, 0x2d84, 0x2d85, 0x2d89, 0x2d8f, + 0x2d94, 0x2d97, 0x2da6, 0x2da8, 0x2dad, 0x2db7, 0x2db8, 0x2dbc, + 0x2dbe, 0x2dc8, 0x2df1, 0x2e0b, 0x2e10, 0x2e20, 0x2e26, 0x2e30, + 0x2e42, 0x2e46, 0x2e48, 0x2e64, 0x2e73, 0x2e82, 0x2e8a, 0x2e8d, + 0x2e91, 0x2e96, 0x2e99, 0x2e9c, 0x2e9d, 0x2ea3, 0x2ea4, 0x2ea8, + 0x2eaf, 0x2eb2, 0x2eba, 0x2ed4, 0x2ed6, 0x2ee9, 0x2eea, 0x2efc, + 0x2f06, 0x2f1f, 0x2f23, 0x2f26, 0x2f2e, 0x2f36, 0x2f38, 0x2f80, + 0x2fb9, 0x2fbb, 0x2fc3, 0x2fd6, 0x3004, 0x3019, 0x3020, 0x302b, + 0x302c, 0x3030, 0x305c, 0x3074, 0x3078, 0x307f, 0x30da, 0x3109, + 0x3121, 0x3122, 0x3127, 0x3137, 0x3141, 0x314c, 0x3150, 0x3151, + 0x315c, 0x315e, 0x3164, 0x3166, 0x318f, 0x3191, 0x319b, 0x31a6, + 0x31cd, 0x31d6, 0x31da, 0x31ec, 0x31f2, 0x31fd, 0x31fe, 0x3210, + 0x3212, 0x3218, 0x322a, 0x3266, 0x3279, 0x3299, 0x32a3, 0x32ac, + 0x32b2, 0x32b3, 0x32b6, 0x32b8, 0x32b9, 0x32e0, 0x32e1, 0x32ec, + 0x32ff, 0x330b, 0x334b, 0x33d2, 0x33d8, 0x33e5, 0x33eb, 0x3440, + 0x344a, 0x344f, 0x3450, 0x3456, 0x3459, 0x3468, 0x346a, 0x3473, + 0x3481, 0x3485, 0x3498, 0x34aa, 0x34be, 0x34c1, 0x34c8, 0x34ca, + 0x34cd, 0x34ce, 0x34d2, 0x34d6, 0x34e0, 0x34f3, 0x34f6, 0x34f7, + 0x34fa, 0x3507, 0x3518, 0x351f, 0x3524, 0x3525, 0x3530, 0x3531, + 0x3536, 0x3539, 0x3540, 0x354d, 0x3553, 0x357a, 0x357f, 0x3580, + 0x3585, 0x358b, 0x3598, 0x35a2, 0x35a7, 0x35a8, 0x35d8, 0x35ed, + 0x3603, 0x3605, 0x3609, 0x360f, 0x3610, 0x3611, 0x3614, 0x3619, + 0x361a, 0x361c, 0x361e, 0x362c, 0x362e, 0x3630, 0x3639, 0x363b, + 0x363c, 0x363d, 0x363e, 0x364b, 0x3661, 0x3662, 0x3670, 0x3672, + 0x3676, 0x3680, 0x3682, 0x36a1, 0x36a8, 0x36ad, 0x36e1, 0x36f6, + 0x3702, 0x370c, 0x3710, 0x3722, 0x3732, 0x373b, 0x374a, 0x374d, + 0x3754, 0x3759, 0x37ae, 0x37c1, 0x37ff, 0x381e, 0x382d, 0x386b, + 0x387e, 0x3886, 0x388e, 0x3893, 0x38dc, 0x38e9, 0x3913, 0x392a, + 0x3932, 0x3934, 0x393b, 0x394a, 0x395c, 0x3970, 0x3a32, 0x3a43, + 0x3a5d, 0x3a61, 0x3a72, 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a7a, + 0x3a80, 0x3a83, 0x3a84, 0x3a88, 0x3a8c, 0x3a9b, 0x3a9c, 0x3ac6, + 0x3ade, 0x3adf, 0x3ae0, 0x3ae5, 0x3aec, 0x3b20, 0x3b22, 0x3b25, + 0x3b28, 0x3b45, 0x3b48, 0x3b49, 0x3b53, 0x3b6b, 0x3b71, 0x3b8b, + 0x3b99, 0x3ba3, 0x3bca, 0x3bcc, 0x3bd2, 0x3bdb, 0x3be6, 0x3bf3, + 0x3bf4, 0x3bf9, 0x3c04, 0x3c1c, 0x3c28, 0x3c43, 0x3c4c, 0x3c4f, + 0x3c52, 0x3c56, 0x3c85, 0x3c88, 0x3c99, 0x3ccd, 0x3d02, 0x3d08, + 0x3d16, 0x3d18, 0x3d19, 0x3d1a, 0x3d2c, 0x3d32, 0x3d3a, 0x3d40, + 0x3d67, 0x3da1, 0x3da7, 0x3dae, 0x3e10, 0x3e33, 0x3e49, 0x3ed4, + 0x3ef0, 0x3f74, 0x3f7c, 0x3f8e, 0x3fca, 0x3fcb, 0x4032, 0x4047, + 0x406a, 0x40c2, 0x40f0, 0x413e, 0x4147, 0x4149, 0x4158, 0x416c, + 0x4171, 0x417a, 0x418a, 0x41bd, 0x41c0, 0x41c7, 0x41d1, 0x41fd, + 0x41fe, 0x423c, 0x4250, 0x4283, 0x42ba, 0x430f, 0x4314, 0x4317, + 0x43c1, 0x4429, 0x442b, 0x4430, 0x4433, 0x4434, 0x4439, 0x4441, + 0x4442, 0x4444, 0x4446, 0x4448, 0x444b, 0x444c, 0x445d, 0x446a, + 0x447b, 0x447c, 0x4481, 0x4487, 0x44c3, 0x44d6, 0x44ec, 0x458b, + 0x458d, 0x458e, 0x458f, 0x4595, 0x4597, 0x45d0, 0x45e8, 0x45ff, + 0x4605, 0x4609, 0x461c, 0x4630, 0x4631, 0x464f, 0x4651, 0x46f6, + 0x46fe, 0x4704, 0x4713, 0x4725, 0x4745, 0x47cb, 0x484b, 0x484d, + 0x484f, 0x4867, 0x486e, 0x486f, 0x487e, 0x4892, 0x48d1, 0x48d2, + 0x48dc, 0x48de, 0x48e2, 0x48e9, 0x490c, 0x491c, 0x493f, 0x495e, + 0x4987, 0x498b, 0x49a4, 0x49dc, 0x49ea, 0x49f6, 0x4a00, 0x4a22, + 0x4a37, 0x4a3d, 0x4a57, 0x4a5a, 0x4a65, 0x4a67, 0x4aa8, 0x4ab2, + 0x4ad1, 0x4ad5, 0x4b32, 0x4b84, 0x4bcf, 0x4be7, 0x4c0c, 0x4c11, + 0x4c15, 0x4c2a, 0x4c31, 0x4c41, 0x4c4a, 0x4c53, 0x4c55, 0x4c5d, + 0x4c61, 0x4c72, 0x4c77, 0x4c82, 0x4c86, 0x4ca4, 0x4cab, 0x4cbe, + 0x4cc3, 0x4ce2, 0x4ce3, 0x4ceb, 0x4cf1, 0x4cfa, 0x4d05, 0x4d4e, + 0x4d4f, 0x4d65, 0x4d81, 0x4d8d, 0x4d9d, 0x4df0, 0x4e4b, 0x4e7f, + 0x4e9f, 0x4eba, 0x4ee3, 0x4f12, 0x4f14, 0x4f16, 0x4f1d, 0x4f44, + 0x4f6f, 0x4f80, 0x4f83, 0x4f88, 0x4f8e, 0x4f9a, 0x4fba, 0x4fc0, + 0x4fc3, 0x4fdd, 0x5009, 0x500e, 0x5042, 0x505b, 0x5066, 0x5077, + 0x5081, 0x50ae, 0x50da, 0x50fb, 0x5104, 0x510b, 0x5118, 0x5119, + 0x511a, 0x513b, 0x513d, 0x514a, 0x5180, 0x5183, 0x5193, 0x51c2, + 0x51f6, 0x51f7, 0x5202, 0x5247, 0x5288, 0x52e4, 0x52ed, 0x534e, + 0x535a, 0x5368, 0x5446, 0x5495, 0x54bd, 0x54ee, 0x5518, 0x5566, + 0x575d, 0x5764, 0x5779, 0x57bc, 0x57e0, 0x57ed, 0x57f2, 0x580e, + 0x5818, 0x5890, 0x5892, 0x589c, 0x58a0, 0x58a7, 0x58ab, 0x58bb, + 0x58cb, 0x58d1, 0x58e3, 0x58f4, 0x58f7, 0x5911, 0x5919, 0x591b, + 0x591f, 0x5924, 0x5929, 0x593b, 0x593e, 0x5942, 0x5944, 0x5945, + 0x5966, 0x5977, 0x5982, 0x5983, 0x5984, 0x599d, 0x599e, 0x59a6, + 0x59a9, 0x59af, 0x59bb, 0x59bd, 0x59be, 0x59c1, 0x59c3, 0x59d0, + 0x59d8, 0x59dc, 0x59e7, 0x5a09, 0x5a13, 0x5a2c, 0x5a2e, 0x5a69, + 0x5a81, 0x5a88, 0x5a9b, 0x5aa4, 0x5ab2, 0x5aef, 0x5b61, 0x5b72, + 0x5bb1, 0x5bb2, 0x5bb8, 0x5bba, 0x5bbd, 0x5bc8, 0x5bc9, 0x5bcc, + 0x5bd0, 0x5bd4, 0x5bd8, 0x5bfb, 0x5c0e, 0x5c4a, 0x5c75, 0x5c81, + 0x5c88, 0x5c96, 0x5c9b, 0x5cb4, 0x5cc4, 0x5cf0, 0x5d00, 0x5dbc, + 0x5ddb, 0x5df0, 0x5df3, 0x5e0e, 0x5e14, 0x5e1a, 0x5e26, 0x5e3b, + 0x5e49, 0x5eac, 0x5eaf, 0x5eb7, 0x5ec3, 0x5ecb, 0x5ecd, 0x5edf, + 0x5ee2, 0x5ee5, 0x5efc, 0x5f0e, 0x5f11, 0x5f12, 0x5f14, 0x5f20, + 0x5f21, 0x5f2a, 0x5f2b, 0x5f30, 0x5f31, 0x5f34, 0x5f3f, 0x5f42, + 0x5f43, 0x5f56, 0x5f5b, 0x5f5c, 0x5f5f, 0x5f64, 0x5f65, 0x5f66, + 0x5f71, 0x5f7a, 0x5f89, 0x5f90, 0x5f95, 0x5f9b, 0x5fb4, 0x5fbb, + 0x5ff9, 0x6006, 0x600e, 0x605e, 0x6063, 0x6065, 0x6089, 0x60bc, + 0x60de, 0x60df, 0x60e0, 0x60e2, 0x60ee, 0x6155, 0x616c, 0x6191, + 0x6233, 0x6240, 0x6243, 0x6488, 0x649a, 0x649c, 0x64a4, 0x64b3, + 0x64ed, 0x6501, 0x6544, 0x6555, 0x655e, 0x6561, 0x6573, 0x6575, + 0x6589, 0x658e, 0x659f, 0x65ac, 0x65ad, 0x65b4, 0x65b9, 0x65cc, + 0x65d7, 0x65e2, 0x65e7, 0x65ea, 0x65f3, 0x65f4, 0x65f9, 0x65fb, + 0x6603, 0x660c, 0x6611, 0x6618, 0x6663, 0x666a, 0x666f, 0x6673, + 0x667a, 0x6685, 0x6704, 0x6710, 0x6714, 0x6716, 0x6719, 0x6728, + 0x6729, 0x673e, 0x674d, 0x675d, 0x6765, 0x6769, 0x676f, 0x6780, + 0x67b9, 0x67ec, 0x67f0, 0x6800, 0x6803, 0x6839, 0x68a7, 0x68aa, + 0x68d5, 0x68d6, 0x6923, 0x6924, 0x6968, 0x69e5, 0x69e9, 0x69fb, + 0x6a6b, 0x6bf6, 0x6da8, 0x6dcd, 0x6dd5, 0x6de3, 0x6def, 0x6df9, + 0x6e24, 0x6e4c, 0xbf12, 0xbf19, 0xbf1c, 0xbf1d, 0xbf1e, 0xbf22, + 0xbf24, 0xbf26, 0xbf2a, 0xbf2d, 0xbf32, 0xbf37, 0xbf38, 0xbf39, + 0xbf4f, 0xbf54, 0xbf59, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf62, 0xbf63, + 0xbf64, 0xbf65, 0xbf78, 0xbf79, 0xbf7f, 0xbf81, 0xbf82, 0xbf85, + 0xbf88, 0xbf89, 0xbf8a, 0xbf8c, 0xbfa4, 0xbfa6, 0xbfd5, 0xbfd6, + 0xbfd8, 0xbfda, 0xbff1, 0xbff8, 0xbffb, 0xc004, 0xc02d, 0xc035, + 0xc06c, 0xc0fc, 0xc151, 0xc152, 0xc153, 0xc154, 0xc155, 0xc198, + 0xc1a4, 0xc1fe, 0xc215, 0xc46b, 0xc6d3, 0xc7b3, 0xce19, 0xce1a, + 0xce1d, 0xce22, 0xce23 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = { + { + .range_start = 32, .range_length = 96, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 12289, .range_length = 72, .glyph_id_start = 97, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 12, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + }, + { + .range_start = 12362, .range_length = 24, .glyph_id_start = 109, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 12387, .range_length = 43, .glyph_id_start = 133, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 12431, .range_length = 95, .glyph_id_start = 176, + .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_4, .list_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL + }, + { + .range_start = 12527, .range_length = 52772, .glyph_id_start = 248, + .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1187, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR >= 8 +/*Store all the custom data of the font*/ + +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 6, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 0, + +}; + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_simsun_14_cjk = { +#else +lv_font_t lv_font_simsun_14_cjk = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 15, /*The maximum line height required by the font*/ + .base_line = 2, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -2, + .underline_thickness = 1, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if LV_FONT_SIMSUN_14_CJK*/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_16_cjk.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_16_cjk.c index d79105891..e8b2f28ae 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_16_cjk.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_simsun_16_cjk.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 16 px * Bpp: 4 - * Opts: --no-compress --no-prefilter --bpp 4 --size 16 --font SimSun.woff -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可 --font FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl -o lv_font_simsun_16_cjk.c --force-fast-kern-format + * Opts: --no-compress --no-prefilter --bpp 4 --size 16 --font SimSun.woff -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可廿节宵植树端阳旦腊妇费愚劳动儿军师庆圣诞闰 --font FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl -o lv_font_simsun_16_cjk.c --force-fast-kern-format ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -3971,6 +3971,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x2c, 0x0, 0x38, 0x81, 0x3a, 0xda, 0x60, 0x0, 0x13, 0x15, 0x30, 0x0, 0x0, 0x15, 0x10, + /* U+513F "儿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x30, 0xb, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x20, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x20, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x10, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x10, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x0, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0x0, 0xc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0xc, 0x10, 0x0, 0x20, + 0x0, 0x0, 0xb2, 0x0, 0xc, 0x10, 0x0, 0x60, + 0x0, 0x3, 0xa0, 0x0, 0xc, 0x10, 0x0, 0x80, + 0x0, 0x1b, 0x10, 0x0, 0xc, 0x20, 0x1, 0xe1, + 0x2, 0x81, 0x0, 0x0, 0x6, 0xed, 0xde, 0xc1, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+5143 "元" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x5, 0x76, 0x66, 0x66, 0x69, 0xb1, 0x0, @@ -4374,6 +4391,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, + /* U+519B "军" */ + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x91, 0x0, + 0xb6, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x60, 0x5c, + 0x0, 0x6, 0xb0, 0x0, 0x4, 0x10, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x0, 0x40, 0x0, 0x1, 0x66, + 0x9b, 0x66, 0x66, 0x67, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x80, 0x0, 0x0, 0x0, 0x0, 0x7, 0x60, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, + 0xd0, 0x3, 0x50, 0x0, 0x0, 0x56, 0x66, 0x6e, + 0x66, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0x67, 0x66, 0x66, 0x6e, 0x66, + 0x66, 0xa9, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x0, + /* U+51AC "冬" */ 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x3, 0x0, 0x0, 0x0, @@ -4852,6 +4886,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xa3, 0x6, 0x0, 0x6, 0x30, 0xb, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+52A8 "动" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x0, 0xd, 0x0, 0x0, 0x4, + 0x76, 0x66, 0x92, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x21, 0x0, 0x0, + 0x0, 0x2, 0x66, 0xe6, 0x6b, 0x70, 0x66, 0x67, + 0x67, 0xb1, 0xc, 0x0, 0x84, 0x0, 0x6, 0xd0, + 0x0, 0x0, 0xc0, 0x9, 0x40, 0x0, 0xc3, 0x0, + 0x0, 0x29, 0x0, 0x93, 0x0, 0x47, 0x5, 0x40, + 0x6, 0x60, 0xa, 0x30, 0x9, 0x0, 0xc, 0x30, + 0xa1, 0x0, 0xb2, 0x9, 0x56, 0x76, 0x8b, 0x2a, + 0x0, 0xb, 0x20, 0xc9, 0x40, 0x0, 0x7a, 0x10, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x6, 0x30, 0x31, + 0x2e, 0x0, 0x0, 0x0, 0x6, 0x30, 0x1, 0xaf, + 0x70, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x30, + 0x0, + /* U+52A9 "助" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0xa6, 0x66, 0xc2, 0x0, 0xd1, 0x0, 0x0, @@ -4887,6 +4938,24 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x16, 0x92, 0x0, 0x7, 0xef, 0x20, 0x0, 0x3, 0x41, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, + /* U+52B3 "劳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x50, 0x1, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x20, 0x1, 0xc0, 0x4, 0x10, + 0x7, 0x66, 0x6c, 0x76, 0x66, 0xd6, 0x6a, 0x80, + 0x0, 0x0, 0xa, 0x20, 0x1, 0xc0, 0x0, 0x0, + 0x0, 0x30, 0x5, 0x10, 0x0, 0x30, 0x2, 0x0, + 0x0, 0xa6, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x70, + 0x5, 0xb0, 0x0, 0x4b, 0x0, 0x0, 0x26, 0x0, + 0x2, 0x10, 0x0, 0x5b, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x67, 0x66, 0x9b, 0x66, 0x6a, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x95, 0x0, 0x8, 0x60, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0xa, 0x50, 0x0, + 0x0, 0x0, 0x8, 0x90, 0x0, 0xc, 0x20, 0x0, + 0x0, 0x0, 0x7a, 0x0, 0x32, 0x2e, 0x0, 0x0, + 0x0, 0x39, 0x50, 0x0, 0x19, 0xf7, 0x0, 0x0, + 0x5, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, + /* U+52C9 "勉" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, @@ -6399,6 +6468,22 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x27, 0x66, 0x66, 0x6c, 0x76, 0x66, 0x6d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+5723 "圣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, + 0x0, 0x6, 0x78, 0x66, 0x66, 0x8f, 0x70, 0x0, + 0x0, 0x0, 0x5, 0x20, 0x0, 0xc7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0xa, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xca, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0x9c, 0x83, 0x0, 0x0, + 0x0, 0x0, 0x29, 0x92, 0x60, 0x6d, 0xfc, 0xa2, + 0x2, 0x57, 0x50, 0x1, 0xf1, 0x0, 0x16, 0x40, + 0x2, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x10, 0x0, + 0x0, 0x6, 0x66, 0x66, 0xf6, 0x66, 0xd8, 0x0, + 0x0, 0x1, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x4, 0x70, + 0x5, 0x76, 0x66, 0x66, 0x76, 0x66, 0x67, 0x71, + /* U+5728 "在" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5c, 0x10, 0x0, 0x0, 0x0, @@ -7106,6 +7191,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x20, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+5987 "妇" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, + 0xd0, 0x0, 0x76, 0x66, 0x66, 0xe3, 0x16, 0x8c, + 0x66, 0xb0, 0x0, 0x0, 0xe, 0x0, 0x6, 0x70, + 0x4a, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xa3, 0x6, + 0x70, 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, 0x94, + 0x26, 0x66, 0x66, 0xe0, 0x1, 0xb0, 0xc, 0x0, + 0x20, 0x0, 0xe, 0x0, 0x48, 0x1, 0xc0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x49, 0x97, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0xd, 0xc3, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x6, 0x63, 0xd3, 0x66, 0x66, + 0x6e, 0x0, 0x3, 0x80, 0x3, 0x1, 0x0, 0x0, + 0xe0, 0x3, 0x60, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+59B3 "妳" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x8, 0x30, 0x0, 0x0, @@ -7731,6 +7833,22 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xa2, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0xc2, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x51, 0x0, + /* U+5BB5 "宵" */ + 0x0, 0x0, 0x4, 0x91, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x10, 0x6, 0x76, + 0x66, 0x66, 0x66, 0x66, 0xc7, 0xd, 0x34, 0x0, + 0x18, 0x0, 0x51, 0x80, 0x15, 0x7, 0xc0, 0x1d, + 0x8, 0x92, 0x0, 0x0, 0x0, 0xb2, 0x1d, 0x46, + 0x0, 0x0, 0x0, 0x28, 0x66, 0x6d, 0x76, 0xa4, + 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xb2, 0x0, + 0x0, 0x2c, 0x66, 0x66, 0x66, 0xc2, 0x0, 0x0, + 0x2a, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x2c, + 0x66, 0x66, 0x66, 0xc2, 0x0, 0x0, 0x2a, 0x0, + 0x0, 0x0, 0xb2, 0x0, 0x0, 0x2a, 0x0, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x6c, + 0xe0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x2, 0x20, + 0x0, + /* U+5BB6 "家" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x40, 0x0, 0x0, 0x0, @@ -8451,6 +8569,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, + /* U+5E08 "师" */ + 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x5, 0x0, + 0x0, 0xc2, 0x47, 0x66, 0xb6, 0x66, 0x93, 0x9, + 0xc, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, + 0xb1, 0x0, 0x0, 0xd0, 0x0, 0x10, 0xd, 0xb, + 0x10, 0xd6, 0x6e, 0x66, 0x7d, 0x0, 0xd0, 0xb1, + 0xd, 0x0, 0xd0, 0x2, 0xb0, 0xd, 0xc, 0x0, + 0xd0, 0xd, 0x0, 0x2b, 0x0, 0xd0, 0xc0, 0xd, + 0x0, 0xd0, 0x2, 0xb0, 0xd, 0xc, 0x0, 0xd0, + 0xd, 0x0, 0x2b, 0x0, 0xb2, 0xa0, 0xd, 0x0, + 0xd0, 0x2, 0xb0, 0x0, 0x74, 0x0, 0xd0, 0xd, + 0x5, 0x8a, 0x0, 0xb, 0x0, 0x5, 0x0, 0xd0, + 0xa, 0x30, 0x7, 0x30, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0x20, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, + 0x0, + /* U+5E0C "希" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0xba, 0x0, 0x0, @@ -8692,6 +8827,24 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x44, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+5E86 "庆" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0xf1, 0x0, 0x5, 0x0, + 0x0, 0x98, 0x66, 0x66, 0x96, 0x66, 0x7b, 0x40, + 0x0, 0x95, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0x95, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x95, 0x0, 0x0, 0xe0, 0x0, 0x1, 0x0, + 0x0, 0xa5, 0x76, 0x66, 0xe6, 0x66, 0x6c, 0x50, + 0x0, 0xa3, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x0, 0x3, 0xa7, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x8, 0x63, 0x60, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0xd, 0x10, 0xa2, 0x0, 0x0, + 0x4, 0x80, 0x0, 0x77, 0x0, 0x2d, 0x30, 0x0, + 0x9, 0x10, 0x7, 0x80, 0x0, 0x4, 0xe8, 0x10, + 0x26, 0x3, 0x73, 0x0, 0x0, 0x0, 0x3d, 0x70, + 0x20, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+5E95 "底" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, @@ -8868,6 +9021,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x5, 0x40, 0x1, 0x7b, 0xde, 0xee, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+5EFF "廿" */ + 0x0, 0x0, 0x9, 0x10, 0x0, 0x81, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x6, 0x30, + 0x6, 0x66, 0x6e, 0x66, 0x66, 0xe6, 0x67, 0x70, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + /* U+5F0F "式" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x23, 0x0, 0x0, 0x0, @@ -9582,6 +9752,21 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xb6, 0x9, 0x40, 0x4d, 0xbb, 0xbb, 0xd4, 0x1, 0x10, + /* U+611A "愚" */ + 0x0, 0x86, 0x66, 0x66, 0x66, 0xb4, 0x0, 0x0, + 0xc0, 0x0, 0xd0, 0x0, 0xd2, 0x0, 0x0, 0xb6, + 0x66, 0xe6, 0x66, 0xe2, 0x0, 0x0, 0xc0, 0x0, + 0xd0, 0x0, 0xd2, 0x0, 0x0, 0xc6, 0x66, 0xe6, + 0x66, 0xe3, 0x0, 0x3, 0x30, 0x0, 0xd0, 0x0, + 0x20, 0x50, 0xd, 0x66, 0x66, 0xe6, 0x76, 0x67, + 0xc0, 0xc, 0x10, 0x0, 0xd0, 0x3b, 0x22, 0xa0, + 0xc, 0x1b, 0xc9, 0x86, 0x46, 0x92, 0xa0, 0xd, + 0x12, 0x5, 0x20, 0x0, 0x69, 0x90, 0x6, 0x6, + 0x21, 0xd4, 0x0, 0x9, 0x20, 0x6, 0xa, 0x40, + 0x44, 0x3, 0x8, 0x50, 0x2d, 0xa, 0x30, 0x0, + 0x6, 0x30, 0xd4, 0x65, 0x6, 0xdb, 0xbb, 0xbd, + 0x90, 0x41, + /* U+611B "愛" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x47, 0xbc, 0x0, 0x1, 0x45, @@ -10950,6 +11135,21 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xc3, 0xc0, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+65E6 "旦" */ + 0x0, 0x0, 0x96, 0x66, 0x66, 0x6b, 0x20, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0xf6, 0x66, 0x66, 0x6e, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, + 0x7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, + /* U+65E9 "早" */ 0x0, 0x0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, 0x60, 0x0, @@ -11950,6 +12150,24 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0xd, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, + /* U+6811 "树" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0xb3, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xc, 0x12, 0x66, 0x6d, 0x10, 0xe0, 0x0, + 0x0, 0xc, 0x16, 0x0, 0x3b, 0x22, 0xe4, 0x70, + 0x16, 0x6e, 0x66, 0x20, 0x76, 0x44, 0xe4, 0x40, + 0x0, 0x1f, 0x10, 0x51, 0xb2, 0x0, 0xe0, 0x0, + 0x0, 0x5f, 0x94, 0x9, 0xc2, 0x40, 0xe0, 0x0, + 0x0, 0xae, 0x2e, 0x9, 0x80, 0xc1, 0xe0, 0x0, + 0x1, 0x9c, 0x13, 0xc, 0xd0, 0x85, 0xe0, 0x0, + 0x7, 0x1c, 0x10, 0x74, 0xa5, 0x21, 0xe0, 0x0, + 0x14, 0xc, 0x12, 0x70, 0x56, 0x0, 0xe0, 0x0, + 0x0, 0xd, 0x27, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x1, 0x10, 0xe0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x1, 0x7f, 0xd0, 0x0, + 0x0, 0x6, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, + /* U+6821 "校" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0xa, 0x10, 0x0, 0x0, @@ -12111,6 +12329,24 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x10, 0x0, 0xe0, 0x20, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, + /* U+690D "植" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x9, 0x40, 0x0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0xb, 0x20, 0x1, 0x0, + 0x0, 0xd, 0x10, 0x76, 0x6d, 0x76, 0x7d, 0x30, + 0x4, 0x4d, 0x69, 0x0, 0xb, 0x10, 0x0, 0x0, + 0x3, 0x2e, 0x22, 0xa, 0x6c, 0x66, 0xb2, 0x0, + 0x0, 0x1f, 0x40, 0xd, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x6f, 0x7a, 0xe, 0x66, 0x66, 0xe0, 0x0, + 0x0, 0xad, 0x1a, 0xd, 0x0, 0x0, 0xd0, 0x0, + 0x2, 0x7d, 0x10, 0xd, 0x66, 0x66, 0xe0, 0x0, + 0x7, 0xd, 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, + 0x14, 0xd, 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0xd, 0x10, 0xd, 0x66, 0x66, 0xe0, 0x0, + 0x0, 0xd, 0x10, 0xd, 0x0, 0x0, 0xd3, 0x30, + 0x0, 0xd, 0x27, 0x67, 0x66, 0x66, 0x77, 0x70, + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+691C "検" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x9, 0x90, 0x0, 0x0, @@ -15400,6 +15636,24 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x40, 0x6, 0x76, 0x66, 0x66, 0xa6, 0x66, 0x66, 0xa5, + /* U+7AEF "端" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x41, 0x0, 0x2, 0x0, 0xb1, 0x0, 0x0, + 0x0, 0x1c, 0x0, 0xd, 0x10, 0xb0, 0xc, 0x20, + 0x0, 0x9, 0x0, 0xc, 0x0, 0xb0, 0xc, 0x0, + 0x5, 0x66, 0x6c, 0x2d, 0x66, 0xd6, 0x6d, 0x0, + 0x0, 0x0, 0x33, 0x4, 0x0, 0x0, 0x5, 0x0, + 0x1, 0x40, 0x78, 0x56, 0x66, 0x66, 0x66, 0xb1, + 0x0, 0x90, 0x92, 0x11, 0x6, 0x60, 0x0, 0x0, + 0x0, 0xb1, 0xa0, 0x12, 0x7, 0x0, 0x1, 0x40, + 0x0, 0xa1, 0x80, 0x2d, 0x6d, 0x6d, 0x6a, 0x90, + 0x0, 0x12, 0x41, 0x4b, 0xc, 0xc, 0x7, 0x60, + 0x0, 0x3a, 0x84, 0x1b, 0xc, 0xc, 0x7, 0x60, + 0xc, 0xa2, 0x0, 0x1b, 0xc, 0xc, 0x7, 0x60, + 0x0, 0x0, 0x0, 0x1b, 0xc, 0xb, 0x7, 0x60, + 0x0, 0x0, 0x0, 0x2b, 0x5, 0x2, 0x7d, 0x50, + 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x6, 0x0, + /* U+7B11 "笑" */ 0x0, 0x2, 0xa0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x8, 0x80, 0x4, 0x5, 0xc0, 0x3, 0x10, @@ -16607,6 +16861,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x6, 0x0, 0x89, 0x38, 0x10, 0xb, 0xbb, 0xb0, 0x10, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + /* U+814A "腊" */ + 0x0, 0x30, 0x4, 0x0, 0x76, 0xa, 0x30, 0x0, + 0x0, 0xd6, 0x6e, 0x10, 0x84, 0xc, 0x0, 0x0, + 0x0, 0xd0, 0xd, 0x26, 0xb8, 0x6d, 0x7c, 0x10, + 0x0, 0xd0, 0xd, 0x1, 0x84, 0xc, 0x0, 0x0, + 0x0, 0xd6, 0x6d, 0x0, 0x84, 0xc, 0x0, 0x0, + 0x0, 0xd0, 0xd, 0x46, 0xb8, 0x6d, 0x6b, 0x90, + 0x0, 0xd0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x3d, 0x4, 0x0, 0x0, 0x33, 0x0, + 0x0, 0xd3, 0x3d, 0xc, 0x66, 0x66, 0xa9, 0x0, + 0x0, 0xc0, 0xd, 0xc, 0x0, 0x0, 0x66, 0x0, + 0x0, 0xb0, 0xd, 0xc, 0x66, 0x66, 0xa6, 0x0, + 0x3, 0x80, 0xd, 0xc, 0x0, 0x0, 0x66, 0x0, + 0x7, 0x22, 0x1d, 0xc, 0x66, 0x66, 0xa6, 0x0, + 0x6, 0x3, 0xca, 0xd, 0x0, 0x0, 0x66, 0x0, + 0x10, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, + /* U+8155 "腕" */ 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0xb6, 0x6d, 0x1, 0x0, 0x96, 0x0, 0x0, @@ -16879,6 +17150,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc1, 0x0, 0xa, 0xdc, 0xcc, 0xcc, 0xcc, 0xcd, 0xa0, + /* U+8282 "节" */ + 0x0, 0x0, 0x7, 0x20, 0x1, 0x80, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x30, 0x1, 0xd0, 0x2, 0x0, + 0x26, 0x66, 0x6d, 0x76, 0x66, 0xe6, 0x6e, 0x90, + 0x1, 0x0, 0xb, 0x20, 0x1, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x10, 0x0, 0x90, 0x0, 0x0, + 0x0, 0x56, 0x66, 0x66, 0x66, 0x66, 0xc1, 0x0, + 0x0, 0x10, 0x0, 0x77, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x4, 0x44, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x5e, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + /* U+82B1 "花" */ 0x0, 0x0, 0x7, 0x50, 0x4, 0x60, 0x0, 0x0, 0x0, 0x0, 0x8, 0x60, 0x5, 0x80, 0x2, 0x10, @@ -18237,6 +18525,23 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + /* U+8BDE "诞" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, + 0x3b, 0x4, 0x69, 0x70, 0x3, 0x9d, 0x90, 0x0, + 0xb2, 0x0, 0xb2, 0x36, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x7, 0x50, 0x7, 0xd, 0x0, 0x3, 0x7b, 0x61, + 0xd0, 0x40, 0xd0, 0xd6, 0xc3, 0x0, 0xa2, 0x29, + 0x7d, 0xc, 0xd, 0x0, 0x0, 0xa, 0x21, 0x3, + 0x90, 0xc0, 0xd0, 0x0, 0x0, 0xa2, 0x5, 0x66, + 0xc, 0xd, 0x0, 0x0, 0xa, 0x20, 0x8b, 0x20, + 0xc0, 0xd0, 0x71, 0x0, 0xa2, 0x64, 0xd0, 0x4b, + 0x66, 0x66, 0x30, 0xb, 0xb1, 0x9b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0xa4, 0x66, 0x6, 0xc9, 0x64, + 0x22, 0x10, 0x0, 0x64, 0x0, 0x0, 0x59, 0xce, + 0xe3, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + /* U+8C50 "豐" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0xb0, 0xc2, 0xa, 0x3, 0x0, 0x0, @@ -18488,6 +18793,22 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x3, 0x96, 0x0, 0x0, 0x3d, 0x70, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, + /* U+8D39 "费" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x10, 0xc1, 0x0, 0x0, 0x3, 0x66, + 0x6e, 0x66, 0xe6, 0x6a, 0x30, 0x0, 0x10, 0xd, + 0x0, 0xd0, 0xb, 0x20, 0x2, 0xb6, 0x6e, 0x66, + 0xe6, 0x6d, 0x10, 0x6, 0x80, 0xd, 0x0, 0xd0, + 0x4, 0x22, 0x6, 0x76, 0xaa, 0x66, 0xe6, 0x66, + 0xc7, 0x0, 0x7, 0x70, 0x0, 0xd0, 0x18, 0xc0, + 0x15, 0x69, 0x66, 0x66, 0x86, 0x95, 0x10, 0x0, + 0xd, 0x0, 0x63, 0x0, 0xd1, 0x0, 0x0, 0xd, + 0x0, 0xc5, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, + 0xf1, 0x0, 0xd0, 0x0, 0x0, 0x7, 0x7, 0xa2, + 0x63, 0x40, 0x0, 0x0, 0x0, 0x6c, 0x10, 0x17, + 0xe8, 0x0, 0x1, 0x58, 0x60, 0x0, 0x0, 0x2e, + 0x40, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+8D64 "赤" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, @@ -19913,6 +20234,37 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x10, 0x6c, 0xc0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, + /* U+95F0 "闰" */ + 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x2f, 0x2, 0x86, 0x66, 0x66, 0xe2, 0xa, 0x16, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0xe, 0x0, 0x0, + 0x0, 0x1, 0x50, 0xe0, 0xd, 0x6, 0x76, 0x7c, + 0x66, 0x60, 0xe0, 0xd, 0x0, 0x0, 0x2b, 0x0, + 0x0, 0xe0, 0xd, 0x0, 0x0, 0x2b, 0x3, 0x0, + 0xe0, 0xd, 0x0, 0x76, 0x7d, 0x68, 0x40, 0xe0, + 0xd, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe0, 0xd, + 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe0, 0xd, 0x26, + 0x66, 0x7d, 0x66, 0xe3, 0xe0, 0xd, 0x2, 0x0, + 0x0, 0x0, 0x0, 0xe0, 0xd, 0x0, 0x0, 0x0, + 0x0, 0x22, 0xe0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0x5d, 0xc0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, + + /* U+9633 "阳" */ + 0x40, 0x1, 0x40, 0x0, 0x0, 0x0, 0xe, 0x66, + 0xad, 0x19, 0x66, 0x66, 0xb2, 0xd0, 0xb, 0x20, + 0xc0, 0x0, 0xd, 0xd, 0x1, 0x90, 0xc, 0x0, + 0x0, 0xd0, 0xd0, 0x51, 0x0, 0xc0, 0x0, 0xd, + 0xd, 0x5, 0x10, 0xc, 0x0, 0x0, 0xd0, 0xd0, + 0x8, 0x10, 0xd6, 0x66, 0x6d, 0xd, 0x0, 0x18, + 0xc, 0x0, 0x0, 0xd0, 0xd0, 0x0, 0xb0, 0xc0, + 0x0, 0xd, 0xd, 0x24, 0x98, 0xc, 0x0, 0x0, + 0xd0, 0xd0, 0x8a, 0x0, 0xc0, 0x0, 0xd, 0xd, + 0x0, 0x0, 0xd, 0x66, 0x66, 0xd0, 0xd0, 0x0, + 0x0, 0xc0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x6, + 0x0, 0x0, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + /* U+9644 "附" */ 0x20, 0x3, 0x0, 0x73, 0x0, 0x82, 0x0, 0xe6, 0x6e, 0x10, 0xd1, 0x0, 0xd0, 0x0, 0xd0, 0x56, @@ -22452,1073 +22804,1094 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 25018, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 25131, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 25251, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25371, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 25476, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 25596, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25716, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25836, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 25956, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26084, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 26204, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26317, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26437, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 26541, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26669, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 26782, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26902, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 27015, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25371, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25491, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 25596, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 25716, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25836, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25956, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 26076, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26204, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 26324, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26437, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26557, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 26661, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26789, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 26902, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27022, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, {.bitmap_index = 27135, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27255, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27383, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27503, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 27607, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 27705, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27825, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27938, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28050, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28163, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28291, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28404, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28524, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28644, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28742, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28855, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28968, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29081, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29194, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29322, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29442, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27255, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27375, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27503, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27623, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 27727, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 27825, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27945, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28058, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 28170, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 28283, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 28396, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28524, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 28637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28757, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28877, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 28975, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29088, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29201, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29314, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29427, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 29555, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29675, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 29675, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 29788, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29908, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30036, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30164, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30277, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30389, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30509, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30614, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30734, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30862, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30990, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31110, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31230, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31350, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31470, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31598, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31718, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31838, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31958, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32086, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32214, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32334, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 32446, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32559, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32672, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32785, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32890, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33010, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33130, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33250, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33378, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33498, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33618, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33738, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33851, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33971, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34076, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34196, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34309, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34414, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34527, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34647, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 34783, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 34919, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35039, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35159, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35287, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35407, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35527, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35647, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 35719, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 35839, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35959, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36064, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36162, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36267, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36387, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 36491, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36619, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36739, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36844, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36942, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 37047, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37175, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37303, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 37401, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37513, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 37617, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 37722, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 37820, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 37933, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38038, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38143, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38256, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38376, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38489, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29908, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30021, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30141, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30269, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30397, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30510, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30622, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30742, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 30847, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30967, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31095, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31223, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31343, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31463, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31583, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31816, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31944, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32072, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32192, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32312, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32432, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32560, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32688, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32808, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32920, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33033, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33146, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33259, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33364, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33484, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33604, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33724, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33852, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33972, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34092, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34212, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34325, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34445, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34550, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34670, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34783, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34888, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35001, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35121, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 35257, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 35393, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35513, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35761, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35881, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36001, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36121, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 36193, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36313, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36433, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36538, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36636, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36741, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36861, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 36965, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37093, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37213, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 37318, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 37416, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 37521, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37649, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37777, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 37875, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37987, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 38091, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 38196, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 38294, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 38407, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 38512, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, {.bitmap_index = 38617, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 38730, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38850, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38955, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39059, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39172, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39292, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39405, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39510, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39623, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39751, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39864, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39992, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40097, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40217, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40330, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40443, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 40548, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40668, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40788, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 40886, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 40984, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41089, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 41187, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41307, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 41405, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41525, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41637, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41749, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41861, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 41973, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42101, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 42213, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42326, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42439, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 42551, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 42663, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42791, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42919, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43047, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43167, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43295, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43423, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43551, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43679, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43799, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43919, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44047, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44175, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 44280, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44400, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44513, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44626, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44746, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 44851, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44964, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 45076, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45204, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45324, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45452, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45572, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45700, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45820, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45940, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46060, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46188, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46308, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46436, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 46549, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46677, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46797, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46910, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47038, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47166, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 47302, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47422, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47550, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47678, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47798, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47926, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48054, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48182, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48310, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48430, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48550, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48670, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48790, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48918, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49046, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49166, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 49279, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49399, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49519, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49647, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 49752, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 49872, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 49992, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50112, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50240, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50360, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 50480, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50593, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 50706, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 50826, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50946, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51074, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51194, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 51306, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51434, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 51554, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51674, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51794, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51914, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52026, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52146, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52274, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52394, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52514, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52634, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52762, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52882, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53010, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53130, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 53250, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53378, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53498, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 53603, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53716, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 53820, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53940, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54068, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54188, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54301, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54421, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54534, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54654, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54767, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54887, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55007, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 55098, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 55218, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 55338, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 55436, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55541, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 55639, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 55744, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 55864, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 55962, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 56060, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56180, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56300, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56428, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56548, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56668, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56796, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56916, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 57029, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57149, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 57261, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 57366, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57486, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57614, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57742, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57870, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57983, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58111, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58231, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58359, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58479, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58599, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58719, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58847, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58975, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59103, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59231, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 59351, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 59441, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 59553, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59666, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59786, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59914, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60019, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60139, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60259, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60387, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60507, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60627, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60747, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60867, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60995, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61115, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61235, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61363, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61491, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61611, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61731, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61859, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 61964, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 62069, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 62182, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62302, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62430, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62558, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 62670, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 62790, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62910, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63023, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 63136, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63264, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 63369, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 63482, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 63587, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 63707, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63835, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 63955, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 64068, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 64181, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 64293, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64421, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 64526, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64646, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 64759, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 64895, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 65023, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 65135, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65255, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65383, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65503, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 65623, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 65759, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65879, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65999, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66119, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66239, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66367, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66487, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66607, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 66743, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66871, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66999, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67119, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67239, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67359, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67479, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67592, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67712, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67840, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67968, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68088, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68208, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 68321, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68441, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68569, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68697, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68825, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68953, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69073, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69193, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69321, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69449, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69569, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69682, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69802, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69930, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70058, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70186, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70306, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70426, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70546, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70666, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70794, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70922, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71035, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 71148, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71276, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71404, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71524, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 71637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71757, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71885, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72013, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72141, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72269, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72389, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72517, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 72630, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72750, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72870, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72990, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73110, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73238, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73358, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73478, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73598, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 73711, .adv_w = 256, .box_w = 10, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 73786, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73906, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 74018, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74131, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 74229, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 74334, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74462, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 74567, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 74672, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74800, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 74920, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75033, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 75145, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 75250, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 75370, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75498, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75618, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 75730, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75850, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 75963, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76083, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76188, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76300, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76412, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76517, .adv_w = 256, .box_w = 12, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 76613, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76733, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76853, .adv_w = 256, .box_w = 12, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 76949, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77061, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77189, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77317, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77415, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77543, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77656, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77776, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77889, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78009, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78129, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78249, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78362, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78475, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78603, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78731, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78859, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78987, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79115, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79235, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79363, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79491, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79619, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79739, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79859, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79987, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80100, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80228, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80356, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80476, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80604, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80732, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80860, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80988, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81108, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81236, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81364, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81492, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81620, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81748, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81876, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82004, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 82132, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82260, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82388, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82508, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82636, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82764, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82892, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83020, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83140, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83268, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83396, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83524, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83652, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83780, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 83916, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 84036, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84156, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84284, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84412, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84540, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 84652, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 84764, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84892, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 85012, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85140, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85268, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85396, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85524, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85644, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85764, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85892, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86020, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86140, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86260, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86388, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86516, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 86614, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 86726, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 86831, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 86944, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87072, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87200, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87328, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87448, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87568, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87816, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87929, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 88049, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88169, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88289, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88409, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 88522, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88642, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 88747, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88875, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89003, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89131, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89244, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89357, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89485, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89605, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89718, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89838, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89958, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90086, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 90206, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90326, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90454, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 90566, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90686, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90799, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 90911, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91031, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91144, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 91264, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91384, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91512, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91632, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91752, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91880, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91993, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92113, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92233, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92361, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 92481, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92609, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92737, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92865, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92993, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93121, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93249, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93369, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 93481, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93609, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 93721, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93849, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93969, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94082, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94202, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 94315, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94435, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 94547, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 94659, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 94779, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94899, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95155, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95283, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95403, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95523, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95651, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95771, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95899, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96019, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96139, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96259, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96379, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96499, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96627, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 96739, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96859, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96972, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97092, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 97212, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97332, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97452, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97565, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 97656, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 97754, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 97858, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 97956, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 98061, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 98174, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 98279, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98399, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 98504, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98632, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98752, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98865, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 98977, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99105, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99225, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99353, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 99466, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99586, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 99676, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 99789, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 99893, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 99998, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 100094, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 100214, .adv_w = 256, .box_w = 11, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 100297, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 100417, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100537, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100665, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100793, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 100906, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101011, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101131, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101244, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101364, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101484, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101612, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101732, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101852, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101980, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102100, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102213, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102333, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102453, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102573, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102693, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102821, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102941, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103069, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103189, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103317, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103445, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103565, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103685, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103805, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103925, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104045, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104173, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 104293, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104406, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 104519, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 104639, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104759, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 104879, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104999, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105127, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105240, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105368, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105496, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105624, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105744, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105872, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105992, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 106112, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106232, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106352, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106480, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106608, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106736, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106856, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 106968, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107081, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107194, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 107314, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107434, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107547, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107667, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107787, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 107899, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108019, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108147, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108267, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108387, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108507, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108627, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108755, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108875, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108995, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109115, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109243, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109371, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109499, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109619, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109747, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 109852, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109980, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110108, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110236, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110356, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110484, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110604, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110732, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110852, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110972, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 111108, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 111206, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111326, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111454, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111574, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111687, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111807, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 111920, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112048, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112176, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112296, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112424, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 112528, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112640, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112760, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 112865, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112985, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113113, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 113226, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113346, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113466, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113579, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113699, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113827, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113955, .adv_w = 256, .box_w = 11, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 114038, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 114143, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114271, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114391, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114504, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114632, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114760, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114888, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115016, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 115120, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 115240, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115360, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115488, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115616, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115736, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115856, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115976, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116089, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116202, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116322, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116450, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116578, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116706, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 116826, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116954, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117082, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117210, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117338, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 117451, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117571, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117699, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117827, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 117939, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118067, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118195, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118315, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118443, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118556, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118676, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118796, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118916, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119036, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119156, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119276, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119404, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119524, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119644, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119764, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119892, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 120004, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120124, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120244, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120364, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120492, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120612, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120732, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120860, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120973, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121101, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121221, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121341, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121454, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121574, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121694, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121822, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121942, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122062, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122190, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122310, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122430, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122558, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122686, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122814, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122942, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123062, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123182, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123310, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123430, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123558, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123686, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123806, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123926, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124054, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124174, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124302, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124430, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 124566, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124694, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124807, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124927, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 125047, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 125159, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125279, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 125392, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125512, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 125632, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 125730, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125850, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 125970, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 126082, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 126202, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 126322, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 126427, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126555, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 126675, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126803, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 126939, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 127075, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127195, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127315, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127443, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127563, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127691, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127811, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127931, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128059, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128187, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128315, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128443, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128571, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128699, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128827, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128955, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129068, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129196, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129324, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129452, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129572, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129692, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 129804, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129924, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130044, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 130156, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130284, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 130396, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130516, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130636, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130756, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130876, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130996, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131116, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131236, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131356, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 131468, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131588, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131708, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131828, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131948, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132068, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132188, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132308, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 132428, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132556, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132684, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132804, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132932, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133052, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133180, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133300, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133428, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133541, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133661, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133781, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 133894, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134022, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134142, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134262, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134390, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134518, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134638, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 134743, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134863, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134983, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135111, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135239, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135359, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135479, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 135591, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135719, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135839, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135959, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136079, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136177, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136275, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136379, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136477, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136575, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136680, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 136792, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 136905, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137018, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137130, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137243, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137348, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137461, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137581, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137686, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137799, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 137919, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 138039, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138167, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138287, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 138400, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138528, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 138641, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138769, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 138874, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138987, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139099, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 139204, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139317, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 139437, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 139565, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 139693, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 139813, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 139933, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140053, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140181, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140301, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140413, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140526, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140646, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140759, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140879, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140999, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 141112, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141232, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141352, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141472, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141592, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141712, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141832, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141952, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142072, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142200, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142320, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142440, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142560, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142688, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142808, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142936, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143056, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143176, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143304, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143432, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143552, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 143672, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143800, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143920, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144040, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144160, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144280, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144400, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 144505, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144625, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144753, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144881, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 145001, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145137, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 145233, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 145345, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 145441, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 145507, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145635, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145763, .adv_w = 288, .box_w = 18, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 145889, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146017, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 146125, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146253, .adv_w = 128, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 146309, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 146393, .adv_w = 288, .box_w = 18, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146537, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 146633, .adv_w = 176, .box_w = 11, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146721, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 146801, .adv_w = 224, .box_w = 14, .box_h = 18, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 146927, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147032, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147130, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 147210, .adv_w = 224, .box_w = 16, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 147322, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147392, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147462, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147560, .adv_w = 224, .box_w = 14, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 147588, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 147696, .adv_w = 320, .box_w = 20, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 147856, .adv_w = 288, .box_w = 20, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 148016, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148144, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 148214, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 148284, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 148424, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 148520, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148648, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 148793, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 148898, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 149010, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149108, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149206, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 149302, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 149398, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 149510, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 149622, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 149730, .adv_w = 256, .box_w = 18, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 149892, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 149988, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 150138, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150238, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150338, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150438, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150538, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150638, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 150785, .adv_w = 224, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 150881, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 150993, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 151138, .adv_w = 320, .box_w = 20, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 151258, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 151354, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 151448, .adv_w = 256, .box_w = 5, .box_h = 14, .ofs_x = 9, .ofs_y = -1}, - {.bitmap_index = 151483, .adv_w = 256, .box_w = 5, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 151518, .adv_w = 256, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 151528, .adv_w = 256, .box_w = 6, .box_h = 11, .ofs_x = 5, .ofs_y = 0}, - {.bitmap_index = 151561, .adv_w = 256, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = 0} + {.bitmap_index = 38850, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 38963, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39091, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39204, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39324, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39429, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39533, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39646, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39766, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39879, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 39984, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40097, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40225, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40338, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40466, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40571, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40691, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40804, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40917, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 41022, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41142, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41262, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 41360, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 41458, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41563, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 41661, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41781, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 41879, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41999, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42111, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42223, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42335, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42447, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42559, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42687, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42799, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42912, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43025, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43137, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 43249, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43377, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43633, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43753, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43881, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44009, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44137, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44265, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44385, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44761, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44866, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44986, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45099, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45212, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45332, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 45437, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45550, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 45662, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45790, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45910, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46038, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46158, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46286, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46406, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46526, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46646, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46774, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46894, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47022, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 47135, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47263, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47383, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47496, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47616, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47744, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47872, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 48008, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48128, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48256, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48384, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48504, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48632, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48760, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48888, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49016, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49136, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49256, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49376, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49496, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49624, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49752, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49872, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 49985, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50105, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50225, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50353, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50458, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50578, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 50698, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50818, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50946, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51066, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 51186, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51299, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 51412, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 51532, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51652, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51780, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51900, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 52012, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 52117, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52245, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 52365, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52485, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52605, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52725, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 52837, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52957, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53085, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 53205, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 53325, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53445, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53573, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53693, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53821, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53941, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 54061, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54189, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54309, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 54414, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54527, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 54631, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54751, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54879, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54999, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55112, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55232, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55345, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55465, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55578, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55698, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55818, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 55909, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 56029, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 56149, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 56247, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56352, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56450, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56555, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 56675, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 56773, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 56871, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 56991, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57111, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 57224, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57352, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 57472, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57592, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57720, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57840, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 57953, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58073, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 58185, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 58290, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58410, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58666, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58794, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58907, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59035, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59163, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59283, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59411, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59531, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59651, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59771, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59899, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60155, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60283, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60403, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60523, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 60613, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60725, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60838, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60958, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61086, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61191, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61311, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61431, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61559, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61679, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61799, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61919, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62039, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62167, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62287, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62407, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62535, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62663, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62783, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62903, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63031, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63136, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63241, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63354, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63474, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63602, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63730, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 63842, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63962, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64082, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64195, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 64308, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64436, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 64541, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64654, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 64759, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 64879, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65007, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65127, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65240, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65353, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 65451, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 65563, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65691, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 65796, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65916, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 66029, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 66165, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 66293, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66405, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66525, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66653, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66773, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 66893, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 67029, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67149, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67269, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67389, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67509, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67757, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67877, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 68013, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68141, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68269, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68389, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68509, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68629, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68749, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68862, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68982, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69110, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69238, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69358, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69478, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 69591, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69711, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69839, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69967, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70095, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70223, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70343, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70463, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70591, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70719, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70839, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70952, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71072, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71200, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71328, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71456, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71576, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71816, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71936, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72064, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72192, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72305, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 72418, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72546, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72674, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72794, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 72907, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73155, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73283, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73411, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73539, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73659, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73787, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 73900, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74020, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74140, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74260, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74380, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74508, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74628, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74748, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74868, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 74981, .adv_w = 256, .box_w = 10, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 75056, .adv_w = 256, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 75160, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75280, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 75392, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75505, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 75603, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 75708, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75836, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 75941, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 76046, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76174, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 76294, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76407, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 76519, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 76624, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 76744, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76872, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76992, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77104, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77224, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77337, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77457, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77562, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77674, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77786, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77891, .adv_w = 256, .box_w = 12, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 77987, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78107, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 78227, .adv_w = 256, .box_w = 12, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 78323, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 78435, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78563, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78691, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78789, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78917, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79030, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79150, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79263, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79383, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79503, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79623, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79736, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79849, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79977, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80105, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80233, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80361, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80489, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80609, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80737, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80865, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80993, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81113, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81233, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81361, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81474, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81602, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81730, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81850, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81978, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82106, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82234, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82362, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82490, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82610, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82738, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82866, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82994, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83122, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83250, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83378, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83506, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83634, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 83762, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83890, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84018, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84138, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84266, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84394, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84522, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84650, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84770, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84898, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85026, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85154, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85282, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85410, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 85546, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 85666, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85786, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85914, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86042, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86170, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86282, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86394, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86522, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 86642, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86770, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86898, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87026, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87154, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87274, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87394, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87522, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87650, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87770, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87890, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88018, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88146, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 88244, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88356, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 88461, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 88574, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88702, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88830, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88958, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89078, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89198, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89326, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89446, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89559, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 89679, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89799, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89919, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90039, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 90152, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90272, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 90377, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90761, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90874, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90987, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91115, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91235, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91348, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91468, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91588, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91716, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 91836, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91956, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92084, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 92196, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92316, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92429, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 92541, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92661, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92774, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 92894, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93014, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93142, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93262, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93382, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93510, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93623, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93743, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93863, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93991, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 94111, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94239, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94367, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94495, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94623, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94751, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94879, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94999, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 95111, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95239, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 95351, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95479, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95599, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95712, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95832, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 95945, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96065, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96177, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 96289, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 96409, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96529, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96657, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96785, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96913, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97033, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97153, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97281, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97401, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97529, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97649, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97769, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97889, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98009, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98129, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98257, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98369, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98489, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98602, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98722, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98842, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98962, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99082, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99195, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 99286, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 99384, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 99488, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 99586, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 99691, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 99804, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 99909, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100029, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 100134, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100262, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100382, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100495, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 100607, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100735, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100855, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100983, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101096, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101216, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 101306, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101419, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 101523, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 101628, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 101724, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 101844, .adv_w = 256, .box_w = 11, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 101927, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 102047, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102167, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102295, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102423, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102536, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102641, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102761, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102874, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102994, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103114, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103242, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103362, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103482, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103610, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103730, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103843, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103963, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104083, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104203, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104323, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104451, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104571, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104699, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104819, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104947, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105075, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105195, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105315, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105435, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105555, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105675, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105803, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 105923, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106036, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 106149, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106269, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106389, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106509, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106757, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106885, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106998, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107126, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107254, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107382, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107502, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107630, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107750, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 107870, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107990, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108110, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108238, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108366, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108494, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108614, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108726, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108839, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108952, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 109072, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109192, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109305, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109425, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109545, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109657, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109777, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109905, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110025, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110145, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110265, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110385, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110513, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110633, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110753, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110873, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111001, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111129, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111257, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111377, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111505, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111610, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111738, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111866, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111994, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112114, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112242, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 112362, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112490, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112610, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112730, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 112866, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 112964, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113084, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113212, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113332, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113445, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113565, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 113678, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113806, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113934, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114054, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114182, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 114286, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114398, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114518, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 114623, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114743, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114871, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 114984, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115104, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115224, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115344, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115457, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115577, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115705, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115833, .adv_w = 256, .box_w = 11, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 115916, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116021, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116149, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116269, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116382, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116510, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116638, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116766, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116894, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 116998, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 117118, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117238, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117358, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117486, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117614, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117734, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117854, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117974, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118087, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118200, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118320, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118448, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118576, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118704, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 118824, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118952, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119080, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119208, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119336, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 119449, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119569, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119697, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119825, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 119937, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120065, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120193, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120313, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120441, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120554, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120674, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120794, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120914, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121034, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121154, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121274, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121402, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121522, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121642, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121762, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121890, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 122002, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122122, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122242, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122362, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122490, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122610, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122730, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122858, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122971, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123099, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123219, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123339, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123452, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123572, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123692, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123820, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123940, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124060, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124188, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124308, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124428, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124556, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124684, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124812, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124940, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125060, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125180, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125308, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125428, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125556, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125684, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125804, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125924, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126052, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126172, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126300, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126428, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 126564, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126692, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126805, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126918, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127038, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 127158, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 127270, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127390, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 127503, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127623, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 127743, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 127841, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127961, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128081, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128193, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128313, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128433, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 128666, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128778, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 128898, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129026, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 129162, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 129298, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129418, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129666, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129786, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129914, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130034, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130154, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130282, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130410, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130666, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130794, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130922, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131050, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131178, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131291, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131419, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131547, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131675, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131795, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131915, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 132027, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132147, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132267, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 132379, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132507, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 132619, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132739, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132859, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132979, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133099, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133219, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133339, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133459, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133579, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133691, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133811, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133931, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134051, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134171, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134291, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134411, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134531, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 134651, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134779, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134907, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135155, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135275, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135403, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135523, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135651, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135764, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135884, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136004, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 136117, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136245, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136365, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136485, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136613, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136741, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136861, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 136966, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137086, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137206, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137334, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137462, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137582, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137702, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 137814, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137942, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138062, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138182, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138302, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 138400, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 138498, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 138602, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 138700, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 138798, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 138903, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 139001, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 139106, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 139218, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 139331, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 139444, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 139556, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 139669, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 139774, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 139887, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 140007, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 140112, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 140225, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 140345, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 140465, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 140593, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 140713, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 140826, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 140954, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141067, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 141195, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141300, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 141413, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141525, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 141630, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141743, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 141863, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 141991, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 142119, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 142239, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 142359, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 142479, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 142607, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 142727, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142839, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142952, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143072, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 143185, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143305, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143425, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 143538, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143658, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143778, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143898, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144018, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144138, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144258, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144378, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144498, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144626, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144746, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144866, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144986, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145114, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145234, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145362, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145482, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145602, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145730, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145858, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145978, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 146098, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146226, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146346, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146466, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146586, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146706, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146826, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 146931, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147051, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147179, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147307, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 147427, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147563, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 147659, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 147771, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 147867, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 147933, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148061, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148189, .adv_w = 288, .box_w = 18, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 148315, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148443, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 148551, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148679, .adv_w = 128, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 148735, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 148819, .adv_w = 288, .box_w = 18, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148963, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 149059, .adv_w = 176, .box_w = 11, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149147, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 149227, .adv_w = 224, .box_w = 14, .box_h = 18, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 149353, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149458, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149556, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 149636, .adv_w = 224, .box_w = 16, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 149748, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149818, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149888, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149986, .adv_w = 224, .box_w = 14, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 150014, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 150122, .adv_w = 320, .box_w = 20, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 150282, .adv_w = 288, .box_w = 20, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 150442, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 150570, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 150640, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 150710, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 150850, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 150946, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151074, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 151219, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 151324, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151436, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 151534, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 151632, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 151728, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 151824, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151936, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 152048, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 152156, .adv_w = 256, .box_w = 18, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 152318, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 152414, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152564, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 152664, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 152764, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 152864, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 152964, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 153064, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 153211, .adv_w = 224, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 153307, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 153419, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 153564, .adv_w = 320, .box_w = 20, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 153684, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 153780, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 153874, .adv_w = 256, .box_w = 5, .box_h = 14, .ofs_x = 9, .ofs_y = -1}, + {.bitmap_index = 153909, .adv_w = 256, .box_w = 5, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 153944, .adv_w = 256, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 153954, .adv_w = 256, .box_w = 6, .box_h = 11, .ofs_x = 5, .ofs_y = 0}, + {.bitmap_index = 153987, .adv_w = 256, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = 0} }; /*--------------------- @@ -23558,140 +23931,143 @@ static const uint16_t unicode_list_5[] = { 0x1eae, 0x1eb2, 0x1ed0, 0x1ed3, 0x1eee, 0x1ef2, 0x1eff, 0x1f1c, 0x1f22, 0x1f2a, 0x1f30, 0x1f35, 0x1f4d, 0x1f6b, 0x1f6d, 0x1f76, 0x1f85, 0x1faa, 0x1fc4, 0x1fd6, 0x1fde, 0x1fe0, 0x1fe6, 0x200a, - 0x2015, 0x203b, 0x2054, 0x2055, 0x2056, 0x2059, 0x205a, 0x205c, - 0x205e, 0x2063, 0x206b, 0x2076, 0x2078, 0x2079, 0x207a, 0x207c, - 0x207d, 0x207e, 0x2082, 0x2087, 0x2088, 0x2096, 0x2097, 0x209b, - 0x209e, 0x20aa, 0x20bd, 0x20c8, 0x20de, 0x20ee, 0x20f7, 0x210b, - 0x2117, 0x2118, 0x211b, 0x2128, 0x212e, 0x2135, 0x2136, 0x213a, - 0x2141, 0x2147, 0x2149, 0x214c, 0x2158, 0x215b, 0x215e, 0x216c, - 0x2183, 0x2186, 0x2194, 0x21ac, 0x21b0, 0x21b1, 0x21ba, 0x21bb, - 0x21da, 0x21e6, 0x21ea, 0x21ee, 0x21f5, 0x2206, 0x2216, 0x2227, - 0x2228, 0x224c, 0x2251, 0x2252, 0x2254, 0x2259, 0x225b, 0x2263, - 0x2265, 0x2268, 0x2269, 0x2282, 0x2284, 0x228c, 0x22ab, 0x22b0, - 0x22c4, 0x22cc, 0x22d3, 0x22d4, 0x22d9, 0x22db, 0x22dc, 0x22de, - 0x22e7, 0x22e8, 0x22f4, 0x22f5, 0x22f6, 0x22f7, 0x22fb, 0x22fc, - 0x2300, 0x2301, 0x2303, 0x2304, 0x2308, 0x2309, 0x2314, 0x2315, - 0x2319, 0x231d, 0x231e, 0x2322, 0x2337, 0x2338, 0x2351, 0x235b, - 0x2373, 0x2379, 0x2384, 0x238d, 0x238e, 0x239d, 0x23c3, 0x23d2, - 0x23f2, 0x23fb, 0x2457, 0x245b, 0x2460, 0x2477, 0x2495, 0x249a, - 0x24ad, 0x24ae, 0x24bf, 0x24c7, 0x24df, 0x2500, 0x252c, 0x25c5, - 0x25ec, 0x25ef, 0x25f1, 0x2601, 0x2604, 0x260e, 0x261c, 0x261e, - 0x2623, 0x2629, 0x2630, 0x2639, 0x2641, 0x2658, 0x265b, 0x2661, - 0x269c, 0x26f0, 0x2708, 0x270b, 0x2742, 0x2745, 0x275b, 0x277a, - 0x2794, 0x27a8, 0x27af, 0x27db, 0x27e4, 0x27fc, 0x2801, 0x2803, - 0x281a, 0x2820, 0x2826, 0x2827, 0x282b, 0x282d, 0x2831, 0x2838, - 0x283a, 0x283b, 0x283c, 0x283f, 0x2842, 0x2858, 0x2862, 0x2868, - 0x2884, 0x288a, 0x288e, 0x2893, 0x28c4, 0x28ca, 0x28cc, 0x28da, - 0x28dc, 0x28e1, 0x28e5, 0x2929, 0x296b, 0x2977, 0x29a3, 0x29ce, - 0x29dd, 0x2a1a, 0x2a61, 0x2a68, 0x2a69, 0x2a74, 0x2a77, 0x2a7a, - 0x2a7c, 0x2a89, 0x2a94, 0x2a96, 0x2a98, 0x2a99, 0x2a9a, 0x2a9d, - 0x2aa9, 0x2aaa, 0x2aab, 0x2aaf, 0x2ab0, 0x2ab3, 0x2ab5, 0x2ac4, - 0x2ac7, 0x2aca, 0x2ad0, 0x2ad5, 0x2ad7, 0x2add, 0x2ae3, 0x2aee, - 0x2af0, 0x2af7, 0x2afc, 0x2b0b, 0x2b0f, 0x2b15, 0x2b18, 0x2b19, - 0x2b1e, 0x2b1f, 0x2b20, 0x2b22, 0x2b2b, 0x2b35, 0x2b42, 0x2b4b, - 0x2b51, 0x2b56, 0x2b5b, 0x2b5c, 0x2b66, 0x2b76, 0x2b7d, 0x2b82, - 0x2c07, 0x2c5d, 0x2cee, 0x2cef, 0x2cf6, 0x2cf7, 0x2cff, 0x2d02, - 0x2d03, 0x2d13, 0x2d14, 0x2d1d, 0x2d3c, 0x2d3e, 0x2d40, 0x2d41, + 0x2015, 0x203b, 0x2050, 0x2054, 0x2055, 0x2056, 0x2059, 0x205a, + 0x205c, 0x205e, 0x2063, 0x206b, 0x2076, 0x2078, 0x2079, 0x207a, + 0x207c, 0x207d, 0x207e, 0x2082, 0x2087, 0x2088, 0x2096, 0x2097, + 0x209b, 0x209e, 0x20aa, 0x20ac, 0x20bd, 0x20c8, 0x20de, 0x20ee, + 0x20f7, 0x210b, 0x2117, 0x2118, 0x211b, 0x2128, 0x212e, 0x2135, + 0x2136, 0x213a, 0x2141, 0x2147, 0x2149, 0x214c, 0x2158, 0x215b, + 0x215e, 0x216c, 0x2183, 0x2186, 0x2194, 0x21ac, 0x21b0, 0x21b1, + 0x21b9, 0x21ba, 0x21bb, 0x21c4, 0x21da, 0x21e6, 0x21ea, 0x21ee, + 0x21f5, 0x2206, 0x2216, 0x2227, 0x2228, 0x224c, 0x2251, 0x2252, + 0x2254, 0x2259, 0x225b, 0x2263, 0x2265, 0x2268, 0x2269, 0x2282, + 0x2284, 0x228c, 0x22ab, 0x22b0, 0x22c4, 0x22cc, 0x22d3, 0x22d4, + 0x22d9, 0x22db, 0x22dc, 0x22de, 0x22e7, 0x22e8, 0x22f4, 0x22f5, + 0x22f6, 0x22f7, 0x22fb, 0x22fc, 0x2300, 0x2301, 0x2303, 0x2304, + 0x2308, 0x2309, 0x2314, 0x2315, 0x2319, 0x231d, 0x231e, 0x2322, + 0x2337, 0x2338, 0x2351, 0x235b, 0x2373, 0x2379, 0x2384, 0x238d, + 0x238e, 0x239d, 0x23c3, 0x23d2, 0x23f2, 0x23fb, 0x2457, 0x245b, + 0x2460, 0x2477, 0x2495, 0x249a, 0x24ad, 0x24ae, 0x24bf, 0x24c7, + 0x24df, 0x2500, 0x252c, 0x25c5, 0x25ec, 0x25ef, 0x25f1, 0x2601, + 0x2604, 0x260e, 0x261c, 0x261e, 0x2623, 0x2629, 0x2630, 0x2634, + 0x2639, 0x2641, 0x2658, 0x265b, 0x2661, 0x269c, 0x26f0, 0x2708, + 0x270b, 0x2742, 0x2745, 0x275b, 0x277a, 0x2794, 0x27a8, 0x27af, + 0x27db, 0x27e4, 0x27fc, 0x2801, 0x2803, 0x281a, 0x2820, 0x2826, + 0x2827, 0x282b, 0x282d, 0x2831, 0x2838, 0x283a, 0x283b, 0x283c, + 0x283f, 0x2842, 0x2858, 0x2862, 0x2868, 0x2884, 0x288a, 0x288e, + 0x2893, 0x2898, 0x28c4, 0x28ca, 0x28cc, 0x28da, 0x28dc, 0x28e1, + 0x28e5, 0x2929, 0x296b, 0x2977, 0x29a3, 0x29ce, 0x29dd, 0x2a1a, + 0x2a61, 0x2a68, 0x2a69, 0x2a74, 0x2a77, 0x2a7a, 0x2a7c, 0x2a89, + 0x2a94, 0x2a96, 0x2a98, 0x2a99, 0x2a9a, 0x2a9d, 0x2aa9, 0x2aaa, + 0x2aab, 0x2aaf, 0x2ab0, 0x2ab3, 0x2ab5, 0x2ac4, 0x2ac6, 0x2ac7, + 0x2aca, 0x2ad0, 0x2ad5, 0x2ad7, 0x2add, 0x2ae3, 0x2aee, 0x2af0, + 0x2af7, 0x2afc, 0x2b0b, 0x2b0f, 0x2b15, 0x2b18, 0x2b19, 0x2b1e, + 0x2b1f, 0x2b20, 0x2b22, 0x2b2b, 0x2b35, 0x2b42, 0x2b4b, 0x2b51, + 0x2b56, 0x2b5b, 0x2b5c, 0x2b66, 0x2b76, 0x2b7d, 0x2b82, 0x2c07, + 0x2c5d, 0x2cee, 0x2cef, 0x2cf6, 0x2cf7, 0x2cff, 0x2d02, 0x2d03, + 0x2d13, 0x2d14, 0x2d19, 0x2d1d, 0x2d3c, 0x2d3e, 0x2d40, 0x2d41, 0x2d44, 0x2d47, 0x2d49, 0x2d56, 0x2d84, 0x2d85, 0x2d89, 0x2d8f, - 0x2d94, 0x2da6, 0x2da8, 0x2dad, 0x2db7, 0x2db8, 0x2dbc, 0x2dbe, - 0x2dc8, 0x2df1, 0x2e0b, 0x2e20, 0x2e26, 0x2e30, 0x2e42, 0x2e46, - 0x2e48, 0x2e64, 0x2e73, 0x2e82, 0x2e8a, 0x2e8d, 0x2e91, 0x2e96, - 0x2e99, 0x2e9c, 0x2e9d, 0x2ea3, 0x2ea4, 0x2ea8, 0x2eaf, 0x2eb2, - 0x2eba, 0x2ed4, 0x2ed6, 0x2ee9, 0x2eea, 0x2efc, 0x2f06, 0x2f1f, - 0x2f23, 0x2f26, 0x2f2e, 0x2f36, 0x2f38, 0x2f80, 0x2fb9, 0x2fbb, - 0x2fc3, 0x2fd6, 0x3004, 0x3019, 0x3020, 0x302c, 0x3030, 0x305c, - 0x3074, 0x3078, 0x307f, 0x30da, 0x3109, 0x3121, 0x3122, 0x3127, - 0x3137, 0x3141, 0x314c, 0x3150, 0x3151, 0x315c, 0x315e, 0x3164, - 0x3166, 0x318f, 0x3191, 0x319b, 0x31a6, 0x31cd, 0x31d6, 0x31da, - 0x31ec, 0x31f2, 0x31fd, 0x31fe, 0x3210, 0x3212, 0x3218, 0x322a, - 0x3266, 0x3279, 0x3299, 0x32a3, 0x32ac, 0x32b2, 0x32b3, 0x32b6, - 0x32b8, 0x32b9, 0x32e0, 0x32e1, 0x32ec, 0x32ff, 0x330b, 0x334b, - 0x33d2, 0x33d8, 0x33e5, 0x33eb, 0x3440, 0x344a, 0x344f, 0x3450, - 0x3456, 0x3459, 0x3468, 0x346a, 0x3473, 0x3481, 0x3485, 0x3498, - 0x34aa, 0x34be, 0x34c1, 0x34c8, 0x34ca, 0x34cd, 0x34ce, 0x34d2, - 0x34d6, 0x34e0, 0x34f3, 0x34f6, 0x34fa, 0x3507, 0x3518, 0x351f, - 0x3524, 0x3525, 0x3530, 0x3531, 0x3536, 0x3539, 0x3540, 0x354d, - 0x3553, 0x357a, 0x357f, 0x3580, 0x3585, 0x358b, 0x3598, 0x35a2, - 0x35a7, 0x35a8, 0x35d8, 0x35ed, 0x3603, 0x3605, 0x3609, 0x360f, - 0x3610, 0x3611, 0x3614, 0x3619, 0x361a, 0x361c, 0x361e, 0x362c, - 0x362e, 0x3630, 0x3639, 0x363b, 0x363c, 0x363d, 0x363e, 0x364b, - 0x3661, 0x3662, 0x3670, 0x3672, 0x3676, 0x3680, 0x3682, 0x36a1, - 0x36a8, 0x36ad, 0x36e1, 0x36f6, 0x3702, 0x370c, 0x3710, 0x3732, - 0x373b, 0x374a, 0x374d, 0x3754, 0x3759, 0x37ae, 0x37c1, 0x37ff, - 0x382d, 0x386b, 0x387e, 0x3886, 0x388e, 0x3893, 0x38dc, 0x38e9, - 0x3913, 0x392a, 0x3932, 0x3934, 0x393b, 0x394a, 0x395c, 0x3970, - 0x3a32, 0x3a43, 0x3a5d, 0x3a61, 0x3a72, 0x3a73, 0x3a74, 0x3a75, - 0x3a76, 0x3a7a, 0x3a80, 0x3a83, 0x3a84, 0x3a88, 0x3a8c, 0x3a9b, - 0x3a9c, 0x3ac6, 0x3ade, 0x3adf, 0x3ae0, 0x3ae5, 0x3aec, 0x3b20, - 0x3b22, 0x3b25, 0x3b28, 0x3b45, 0x3b48, 0x3b49, 0x3b53, 0x3b6b, - 0x3b71, 0x3b8b, 0x3b99, 0x3ba3, 0x3bca, 0x3bcc, 0x3bd2, 0x3bdb, - 0x3be6, 0x3bf3, 0x3bf4, 0x3bf9, 0x3c04, 0x3c1c, 0x3c28, 0x3c43, - 0x3c4c, 0x3c4f, 0x3c52, 0x3c56, 0x3c85, 0x3c88, 0x3c99, 0x3ccd, - 0x3d02, 0x3d08, 0x3d16, 0x3d18, 0x3d19, 0x3d1a, 0x3d2c, 0x3d32, - 0x3d3a, 0x3d40, 0x3d67, 0x3da1, 0x3da7, 0x3dae, 0x3e10, 0x3e33, - 0x3e49, 0x3ed4, 0x3ef0, 0x3f74, 0x3f7c, 0x3f8e, 0x3fca, 0x3fcb, - 0x4032, 0x4047, 0x406a, 0x40c2, 0x40f0, 0x413e, 0x4147, 0x4149, - 0x4158, 0x416c, 0x4171, 0x417a, 0x418a, 0x41bd, 0x41c0, 0x41c7, - 0x41d1, 0x41fd, 0x41fe, 0x423c, 0x4250, 0x4283, 0x42ba, 0x430f, - 0x4314, 0x4317, 0x43c1, 0x4429, 0x442b, 0x4430, 0x4433, 0x4434, - 0x4439, 0x4441, 0x4442, 0x4444, 0x4446, 0x4448, 0x444b, 0x444c, - 0x445d, 0x446a, 0x447b, 0x447c, 0x4481, 0x4487, 0x44c3, 0x44d6, - 0x44ec, 0x458b, 0x458d, 0x458e, 0x458f, 0x4595, 0x4597, 0x45d0, - 0x45e8, 0x45ff, 0x4605, 0x4609, 0x461c, 0x4630, 0x4631, 0x464f, - 0x4651, 0x46f6, 0x46fe, 0x4704, 0x4713, 0x4725, 0x4745, 0x47cb, - 0x484b, 0x484d, 0x484f, 0x4867, 0x486e, 0x486f, 0x487e, 0x4892, - 0x48d1, 0x48d2, 0x48dc, 0x48de, 0x48e2, 0x48e9, 0x490c, 0x491c, - 0x493f, 0x495e, 0x4987, 0x498b, 0x49a4, 0x49dc, 0x49ea, 0x49f6, - 0x4a22, 0x4a37, 0x4a3d, 0x4a57, 0x4a5a, 0x4a65, 0x4a67, 0x4aa8, - 0x4ab2, 0x4ad1, 0x4ad5, 0x4b32, 0x4b84, 0x4bcf, 0x4be7, 0x4c0c, - 0x4c11, 0x4c15, 0x4c2a, 0x4c31, 0x4c41, 0x4c4a, 0x4c53, 0x4c55, - 0x4c5d, 0x4c61, 0x4c72, 0x4c77, 0x4c82, 0x4c86, 0x4ca4, 0x4cab, - 0x4cbe, 0x4cc3, 0x4ce2, 0x4ce3, 0x4ceb, 0x4cf1, 0x4cfa, 0x4d05, - 0x4d4e, 0x4d4f, 0x4d65, 0x4d81, 0x4d8d, 0x4d9d, 0x4df0, 0x4e4b, - 0x4e7f, 0x4e9f, 0x4eba, 0x4ee3, 0x4f12, 0x4f14, 0x4f16, 0x4f1d, - 0x4f44, 0x4f6f, 0x4f80, 0x4f83, 0x4f88, 0x4f8e, 0x4f9a, 0x4fba, - 0x4fc0, 0x4fc3, 0x4fdd, 0x5009, 0x500e, 0x5042, 0x5066, 0x5077, + 0x2d94, 0x2d97, 0x2da6, 0x2da8, 0x2dad, 0x2db7, 0x2db8, 0x2dbc, + 0x2dbe, 0x2dc8, 0x2df1, 0x2e0b, 0x2e10, 0x2e20, 0x2e26, 0x2e30, + 0x2e42, 0x2e46, 0x2e48, 0x2e64, 0x2e73, 0x2e82, 0x2e8a, 0x2e8d, + 0x2e91, 0x2e96, 0x2e99, 0x2e9c, 0x2e9d, 0x2ea3, 0x2ea4, 0x2ea8, + 0x2eaf, 0x2eb2, 0x2eba, 0x2ed4, 0x2ed6, 0x2ee9, 0x2eea, 0x2efc, + 0x2f06, 0x2f1f, 0x2f23, 0x2f26, 0x2f2e, 0x2f36, 0x2f38, 0x2f80, + 0x2fb9, 0x2fbb, 0x2fc3, 0x2fd6, 0x3004, 0x3019, 0x3020, 0x302b, + 0x302c, 0x3030, 0x305c, 0x3074, 0x3078, 0x307f, 0x30da, 0x3109, + 0x3121, 0x3122, 0x3127, 0x3137, 0x3141, 0x314c, 0x3150, 0x3151, + 0x315c, 0x315e, 0x3164, 0x3166, 0x318f, 0x3191, 0x319b, 0x31a6, + 0x31cd, 0x31d6, 0x31da, 0x31ec, 0x31f2, 0x31fd, 0x31fe, 0x3210, + 0x3212, 0x3218, 0x322a, 0x3266, 0x3279, 0x3299, 0x32a3, 0x32ac, + 0x32b2, 0x32b3, 0x32b6, 0x32b8, 0x32b9, 0x32e0, 0x32e1, 0x32ec, + 0x32ff, 0x330b, 0x334b, 0x33d2, 0x33d8, 0x33e5, 0x33eb, 0x3440, + 0x344a, 0x344f, 0x3450, 0x3456, 0x3459, 0x3468, 0x346a, 0x3473, + 0x3481, 0x3485, 0x3498, 0x34aa, 0x34be, 0x34c1, 0x34c8, 0x34ca, + 0x34cd, 0x34ce, 0x34d2, 0x34d6, 0x34e0, 0x34f3, 0x34f6, 0x34f7, + 0x34fa, 0x3507, 0x3518, 0x351f, 0x3524, 0x3525, 0x3530, 0x3531, + 0x3536, 0x3539, 0x3540, 0x354d, 0x3553, 0x357a, 0x357f, 0x3580, + 0x3585, 0x358b, 0x3598, 0x35a2, 0x35a7, 0x35a8, 0x35d8, 0x35ed, + 0x3603, 0x3605, 0x3609, 0x360f, 0x3610, 0x3611, 0x3614, 0x3619, + 0x361a, 0x361c, 0x361e, 0x362c, 0x362e, 0x3630, 0x3639, 0x363b, + 0x363c, 0x363d, 0x363e, 0x364b, 0x3661, 0x3662, 0x3670, 0x3672, + 0x3676, 0x3680, 0x3682, 0x36a1, 0x36a8, 0x36ad, 0x36e1, 0x36f6, + 0x3702, 0x370c, 0x3710, 0x3722, 0x3732, 0x373b, 0x374a, 0x374d, + 0x3754, 0x3759, 0x37ae, 0x37c1, 0x37ff, 0x381e, 0x382d, 0x386b, + 0x387e, 0x3886, 0x388e, 0x3893, 0x38dc, 0x38e9, 0x3913, 0x392a, + 0x3932, 0x3934, 0x393b, 0x394a, 0x395c, 0x3970, 0x3a32, 0x3a43, + 0x3a5d, 0x3a61, 0x3a72, 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a7a, + 0x3a80, 0x3a83, 0x3a84, 0x3a88, 0x3a8c, 0x3a9b, 0x3a9c, 0x3ac6, + 0x3ade, 0x3adf, 0x3ae0, 0x3ae5, 0x3aec, 0x3b20, 0x3b22, 0x3b25, + 0x3b28, 0x3b45, 0x3b48, 0x3b49, 0x3b53, 0x3b6b, 0x3b71, 0x3b8b, + 0x3b99, 0x3ba3, 0x3bca, 0x3bcc, 0x3bd2, 0x3bdb, 0x3be6, 0x3bf3, + 0x3bf4, 0x3bf9, 0x3c04, 0x3c1c, 0x3c28, 0x3c43, 0x3c4c, 0x3c4f, + 0x3c52, 0x3c56, 0x3c85, 0x3c88, 0x3c99, 0x3ccd, 0x3d02, 0x3d08, + 0x3d16, 0x3d18, 0x3d19, 0x3d1a, 0x3d2c, 0x3d32, 0x3d3a, 0x3d40, + 0x3d67, 0x3da1, 0x3da7, 0x3dae, 0x3e10, 0x3e33, 0x3e49, 0x3ed4, + 0x3ef0, 0x3f74, 0x3f7c, 0x3f8e, 0x3fca, 0x3fcb, 0x4032, 0x4047, + 0x406a, 0x40c2, 0x40f0, 0x413e, 0x4147, 0x4149, 0x4158, 0x416c, + 0x4171, 0x417a, 0x418a, 0x41bd, 0x41c0, 0x41c7, 0x41d1, 0x41fd, + 0x41fe, 0x423c, 0x4250, 0x4283, 0x42ba, 0x430f, 0x4314, 0x4317, + 0x43c1, 0x4429, 0x442b, 0x4430, 0x4433, 0x4434, 0x4439, 0x4441, + 0x4442, 0x4444, 0x4446, 0x4448, 0x444b, 0x444c, 0x445d, 0x446a, + 0x447b, 0x447c, 0x4481, 0x4487, 0x44c3, 0x44d6, 0x44ec, 0x458b, + 0x458d, 0x458e, 0x458f, 0x4595, 0x4597, 0x45d0, 0x45e8, 0x45ff, + 0x4605, 0x4609, 0x461c, 0x4630, 0x4631, 0x464f, 0x4651, 0x46f6, + 0x46fe, 0x4704, 0x4713, 0x4725, 0x4745, 0x47cb, 0x484b, 0x484d, + 0x484f, 0x4867, 0x486e, 0x486f, 0x487e, 0x4892, 0x48d1, 0x48d2, + 0x48dc, 0x48de, 0x48e2, 0x48e9, 0x490c, 0x491c, 0x493f, 0x495e, + 0x4987, 0x498b, 0x49a4, 0x49dc, 0x49ea, 0x49f6, 0x4a00, 0x4a22, + 0x4a37, 0x4a3d, 0x4a57, 0x4a5a, 0x4a65, 0x4a67, 0x4aa8, 0x4ab2, + 0x4ad1, 0x4ad5, 0x4b32, 0x4b84, 0x4bcf, 0x4be7, 0x4c0c, 0x4c11, + 0x4c15, 0x4c2a, 0x4c31, 0x4c41, 0x4c4a, 0x4c53, 0x4c55, 0x4c5d, + 0x4c61, 0x4c72, 0x4c77, 0x4c82, 0x4c86, 0x4ca4, 0x4cab, 0x4cbe, + 0x4cc3, 0x4ce2, 0x4ce3, 0x4ceb, 0x4cf1, 0x4cfa, 0x4d05, 0x4d4e, + 0x4d4f, 0x4d65, 0x4d81, 0x4d8d, 0x4d9d, 0x4df0, 0x4e4b, 0x4e7f, + 0x4e9f, 0x4eba, 0x4ee3, 0x4f12, 0x4f14, 0x4f16, 0x4f1d, 0x4f44, + 0x4f6f, 0x4f80, 0x4f83, 0x4f88, 0x4f8e, 0x4f9a, 0x4fba, 0x4fc0, + 0x4fc3, 0x4fdd, 0x5009, 0x500e, 0x5042, 0x505b, 0x5066, 0x5077, 0x5081, 0x50ae, 0x50da, 0x50fb, 0x5104, 0x510b, 0x5118, 0x5119, - 0x511a, 0x513b, 0x513d, 0x514a, 0x5180, 0x5183, 0x51c2, 0x51f6, - 0x51f7, 0x5202, 0x5247, 0x5288, 0x52e4, 0x52ed, 0x534e, 0x535a, - 0x5368, 0x5446, 0x5495, 0x54bd, 0x54ee, 0x5518, 0x5566, 0x575d, - 0x5764, 0x5779, 0x57bc, 0x57e0, 0x57ed, 0x57f2, 0x580e, 0x5818, - 0x5890, 0x5892, 0x589c, 0x58a0, 0x58a7, 0x58ab, 0x58bb, 0x58cb, - 0x58d1, 0x58e3, 0x58f4, 0x58f7, 0x5911, 0x5919, 0x591b, 0x591f, - 0x5924, 0x5929, 0x593b, 0x593e, 0x5942, 0x5944, 0x5945, 0x5966, - 0x5977, 0x5982, 0x5983, 0x5984, 0x599d, 0x599e, 0x59a6, 0x59a9, - 0x59af, 0x59bb, 0x59bd, 0x59be, 0x59c1, 0x59c3, 0x59d0, 0x59d8, - 0x59dc, 0x59e7, 0x5a09, 0x5a13, 0x5a2c, 0x5a2e, 0x5a69, 0x5a81, - 0x5a88, 0x5a9b, 0x5aa4, 0x5ab2, 0x5b61, 0x5b72, 0x5bb1, 0x5bb2, - 0x5bb8, 0x5bba, 0x5bbd, 0x5bc8, 0x5bc9, 0x5bcc, 0x5bd0, 0x5bd4, - 0x5bd8, 0x5bfb, 0x5c0e, 0x5c75, 0x5c81, 0x5c88, 0x5c96, 0x5c9b, - 0x5cb4, 0x5cc4, 0x5cf0, 0x5d00, 0x5dbc, 0x5ddb, 0x5df0, 0x5df3, - 0x5e0e, 0x5e14, 0x5e1a, 0x5e26, 0x5e3b, 0x5e49, 0x5eac, 0x5eaf, - 0x5eb7, 0x5ec3, 0x5ecb, 0x5ecd, 0x5edf, 0x5ee2, 0x5ee5, 0x5efc, - 0x5f0e, 0x5f11, 0x5f12, 0x5f14, 0x5f20, 0x5f21, 0x5f2a, 0x5f2b, - 0x5f30, 0x5f31, 0x5f34, 0x5f3f, 0x5f42, 0x5f43, 0x5f56, 0x5f5b, - 0x5f5c, 0x5f5f, 0x5f64, 0x5f65, 0x5f66, 0x5f71, 0x5f7a, 0x5f89, - 0x5f90, 0x5f95, 0x5f9b, 0x5fb4, 0x5fbb, 0x5ff9, 0x6006, 0x600e, - 0x605e, 0x6063, 0x6065, 0x6089, 0x60bc, 0x60de, 0x60df, 0x60e0, - 0x60e2, 0x60ee, 0x6155, 0x616c, 0x6191, 0x6233, 0x6240, 0x6243, - 0x6488, 0x649a, 0x649c, 0x64a4, 0x64b3, 0x64ed, 0x6555, 0x655e, - 0x6561, 0x6573, 0x6575, 0x6589, 0x658e, 0x659f, 0x65ac, 0x65ad, - 0x65b4, 0x65b9, 0x65cc, 0x65d7, 0x65e2, 0x65e7, 0x65ea, 0x65f3, - 0x65f4, 0x65f9, 0x65fb, 0x6603, 0x660c, 0x6611, 0x6618, 0x6663, - 0x666a, 0x666f, 0x6673, 0x667a, 0x6685, 0x6704, 0x6710, 0x6714, - 0x6716, 0x6719, 0x6728, 0x6729, 0x673e, 0x674d, 0x675d, 0x6765, - 0x6769, 0x676f, 0x6780, 0x67b9, 0x67ec, 0x67f0, 0x6800, 0x6803, - 0x6839, 0x68a7, 0x68aa, 0x68d5, 0x68d6, 0x6923, 0x6924, 0x6968, - 0x69e5, 0x69e9, 0x69fb, 0x6a6b, 0x6bf6, 0x6da8, 0x6dcd, 0x6dd5, - 0x6de3, 0x6def, 0x6df9, 0x6e24, 0x6e4c, 0xbf12, 0xbf19, 0xbf1c, - 0xbf1d, 0xbf1e, 0xbf22, 0xbf24, 0xbf26, 0xbf2a, 0xbf2d, 0xbf32, - 0xbf37, 0xbf38, 0xbf39, 0xbf4f, 0xbf54, 0xbf59, 0xbf5c, 0xbf5d, - 0xbf5e, 0xbf62, 0xbf63, 0xbf64, 0xbf65, 0xbf78, 0xbf79, 0xbf7f, - 0xbf81, 0xbf82, 0xbf85, 0xbf88, 0xbf89, 0xbf8a, 0xbf8c, 0xbfa4, - 0xbfa6, 0xbfd5, 0xbfd6, 0xbfd8, 0xbfda, 0xbff1, 0xbff8, 0xbffb, - 0xc004, 0xc02d, 0xc035, 0xc06c, 0xc0fc, 0xc151, 0xc152, 0xc153, - 0xc154, 0xc155, 0xc198, 0xc1a4, 0xc1fe, 0xc215, 0xc46b, 0xc6d3, - 0xc7b3, 0xce19, 0xce1a, 0xce1d, 0xce22, 0xce23 + 0x511a, 0x513b, 0x513d, 0x514a, 0x5180, 0x5183, 0x5193, 0x51c2, + 0x51f6, 0x51f7, 0x5202, 0x5247, 0x5288, 0x52e4, 0x52ed, 0x534e, + 0x535a, 0x5368, 0x5446, 0x5495, 0x54bd, 0x54ee, 0x5518, 0x5566, + 0x575d, 0x5764, 0x5779, 0x57bc, 0x57e0, 0x57ed, 0x57f2, 0x580e, + 0x5818, 0x5890, 0x5892, 0x589c, 0x58a0, 0x58a7, 0x58ab, 0x58bb, + 0x58cb, 0x58d1, 0x58e3, 0x58f4, 0x58f7, 0x5911, 0x5919, 0x591b, + 0x591f, 0x5924, 0x5929, 0x593b, 0x593e, 0x5942, 0x5944, 0x5945, + 0x5966, 0x5977, 0x5982, 0x5983, 0x5984, 0x599d, 0x599e, 0x59a6, + 0x59a9, 0x59af, 0x59bb, 0x59bd, 0x59be, 0x59c1, 0x59c3, 0x59d0, + 0x59d8, 0x59dc, 0x59e7, 0x5a09, 0x5a13, 0x5a2c, 0x5a2e, 0x5a69, + 0x5a81, 0x5a88, 0x5a9b, 0x5aa4, 0x5ab2, 0x5aef, 0x5b61, 0x5b72, + 0x5bb1, 0x5bb2, 0x5bb8, 0x5bba, 0x5bbd, 0x5bc8, 0x5bc9, 0x5bcc, + 0x5bd0, 0x5bd4, 0x5bd8, 0x5bfb, 0x5c0e, 0x5c4a, 0x5c75, 0x5c81, + 0x5c88, 0x5c96, 0x5c9b, 0x5cb4, 0x5cc4, 0x5cf0, 0x5d00, 0x5dbc, + 0x5ddb, 0x5df0, 0x5df3, 0x5e0e, 0x5e14, 0x5e1a, 0x5e26, 0x5e3b, + 0x5e49, 0x5eac, 0x5eaf, 0x5eb7, 0x5ec3, 0x5ecb, 0x5ecd, 0x5edf, + 0x5ee2, 0x5ee5, 0x5efc, 0x5f0e, 0x5f11, 0x5f12, 0x5f14, 0x5f20, + 0x5f21, 0x5f2a, 0x5f2b, 0x5f30, 0x5f31, 0x5f34, 0x5f3f, 0x5f42, + 0x5f43, 0x5f56, 0x5f5b, 0x5f5c, 0x5f5f, 0x5f64, 0x5f65, 0x5f66, + 0x5f71, 0x5f7a, 0x5f89, 0x5f90, 0x5f95, 0x5f9b, 0x5fb4, 0x5fbb, + 0x5ff9, 0x6006, 0x600e, 0x605e, 0x6063, 0x6065, 0x6089, 0x60bc, + 0x60de, 0x60df, 0x60e0, 0x60e2, 0x60ee, 0x6155, 0x616c, 0x6191, + 0x6233, 0x6240, 0x6243, 0x6488, 0x649a, 0x649c, 0x64a4, 0x64b3, + 0x64ed, 0x6501, 0x6544, 0x6555, 0x655e, 0x6561, 0x6573, 0x6575, + 0x6589, 0x658e, 0x659f, 0x65ac, 0x65ad, 0x65b4, 0x65b9, 0x65cc, + 0x65d7, 0x65e2, 0x65e7, 0x65ea, 0x65f3, 0x65f4, 0x65f9, 0x65fb, + 0x6603, 0x660c, 0x6611, 0x6618, 0x6663, 0x666a, 0x666f, 0x6673, + 0x667a, 0x6685, 0x6704, 0x6710, 0x6714, 0x6716, 0x6719, 0x6728, + 0x6729, 0x673e, 0x674d, 0x675d, 0x6765, 0x6769, 0x676f, 0x6780, + 0x67b9, 0x67ec, 0x67f0, 0x6800, 0x6803, 0x6839, 0x68a7, 0x68aa, + 0x68d5, 0x68d6, 0x6923, 0x6924, 0x6968, 0x69e5, 0x69e9, 0x69fb, + 0x6a6b, 0x6bf6, 0x6da8, 0x6dcd, 0x6dd5, 0x6de3, 0x6def, 0x6df9, + 0x6e24, 0x6e4c, 0xbf12, 0xbf19, 0xbf1c, 0xbf1d, 0xbf1e, 0xbf22, + 0xbf24, 0xbf26, 0xbf2a, 0xbf2d, 0xbf32, 0xbf37, 0xbf38, 0xbf39, + 0xbf4f, 0xbf54, 0xbf59, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf62, 0xbf63, + 0xbf64, 0xbf65, 0xbf78, 0xbf79, 0xbf7f, 0xbf81, 0xbf82, 0xbf85, + 0xbf88, 0xbf89, 0xbf8a, 0xbf8c, 0xbfa4, 0xbfa6, 0xbfd5, 0xbfd6, + 0xbfd8, 0xbfda, 0xbff1, 0xbff8, 0xbffb, 0xc004, 0xc02d, 0xc035, + 0xc06c, 0xc0fc, 0xc151, 0xc152, 0xc153, 0xc154, 0xc155, 0xc198, + 0xc1a4, 0xc1fe, 0xc215, 0xc46b, 0xc6d3, 0xc7b3, 0xce19, 0xce1a, + 0xce1d, 0xce22, 0xce23 }; /*Collect the unicode lists and glyph_id offsets*/ @@ -23718,7 +24094,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = { }, { .range_start = 12527, .range_length = 52772, .glyph_id_start = 248, - .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1166, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1187, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_symbol_def.h b/lib/libesp32_lvgl/lvgl/src/font/lv_symbol_def.h index 7c2365869..d78f3892d 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_symbol_def.h +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_symbol_def.h @@ -1,3 +1,8 @@ +/** + * @file lv_symbol_def.h + * + */ + #ifndef LV_SYMBOL_DEF_H #define LV_SYMBOL_DEF_H @@ -27,7 +32,7 @@ extern "C" { 62018, 62019, 62020, 62087, 62099, 62189, 62212, 62810, 63426, 63650 */ -/* These symbols can be prefined in the lv_conf.h file. +/* These symbols can be predefined in the lv_conf.h file. * If they are not predefined, they will use the following values */ @@ -278,71 +283,71 @@ extern "C" { /* * The following list is generated using - * cat src/font/lv_symbol_def.h | sed -E -n 's/^#define\s+LV_(SYMBOL_\w+).*".*$/ _LV_STR_\1,/p' + * cat src/font/lv_symbol_def.h | sed -E -n 's/^#define\s+LV_(SYMBOL_\w+).*".*$/ LV_STR_\1,/p' */ enum { - _LV_STR_SYMBOL_BULLET, - _LV_STR_SYMBOL_AUDIO, - _LV_STR_SYMBOL_VIDEO, - _LV_STR_SYMBOL_LIST, - _LV_STR_SYMBOL_OK, - _LV_STR_SYMBOL_CLOSE, - _LV_STR_SYMBOL_POWER, - _LV_STR_SYMBOL_SETTINGS, - _LV_STR_SYMBOL_HOME, - _LV_STR_SYMBOL_DOWNLOAD, - _LV_STR_SYMBOL_DRIVE, - _LV_STR_SYMBOL_REFRESH, - _LV_STR_SYMBOL_MUTE, - _LV_STR_SYMBOL_VOLUME_MID, - _LV_STR_SYMBOL_VOLUME_MAX, - _LV_STR_SYMBOL_IMAGE, - _LV_STR_SYMBOL_TINT, - _LV_STR_SYMBOL_PREV, - _LV_STR_SYMBOL_PLAY, - _LV_STR_SYMBOL_PAUSE, - _LV_STR_SYMBOL_STOP, - _LV_STR_SYMBOL_NEXT, - _LV_STR_SYMBOL_EJECT, - _LV_STR_SYMBOL_LEFT, - _LV_STR_SYMBOL_RIGHT, - _LV_STR_SYMBOL_PLUS, - _LV_STR_SYMBOL_MINUS, - _LV_STR_SYMBOL_EYE_OPEN, - _LV_STR_SYMBOL_EYE_CLOSE, - _LV_STR_SYMBOL_WARNING, - _LV_STR_SYMBOL_SHUFFLE, - _LV_STR_SYMBOL_UP, - _LV_STR_SYMBOL_DOWN, - _LV_STR_SYMBOL_LOOP, - _LV_STR_SYMBOL_DIRECTORY, - _LV_STR_SYMBOL_UPLOAD, - _LV_STR_SYMBOL_CALL, - _LV_STR_SYMBOL_CUT, - _LV_STR_SYMBOL_COPY, - _LV_STR_SYMBOL_SAVE, - _LV_STR_SYMBOL_BARS, - _LV_STR_SYMBOL_ENVELOPE, - _LV_STR_SYMBOL_CHARGE, - _LV_STR_SYMBOL_PASTE, - _LV_STR_SYMBOL_BELL, - _LV_STR_SYMBOL_KEYBOARD, - _LV_STR_SYMBOL_GPS, - _LV_STR_SYMBOL_FILE, - _LV_STR_SYMBOL_WIFI, - _LV_STR_SYMBOL_BATTERY_FULL, - _LV_STR_SYMBOL_BATTERY_3, - _LV_STR_SYMBOL_BATTERY_2, - _LV_STR_SYMBOL_BATTERY_1, - _LV_STR_SYMBOL_BATTERY_EMPTY, - _LV_STR_SYMBOL_USB, - _LV_STR_SYMBOL_BLUETOOTH, - _LV_STR_SYMBOL_TRASH, - _LV_STR_SYMBOL_EDIT, - _LV_STR_SYMBOL_BACKSPACE, - _LV_STR_SYMBOL_SD_CARD, - _LV_STR_SYMBOL_NEW_LINE, - _LV_STR_SYMBOL_DUMMY, + LV_STR_SYMBOL_BULLET, + LV_STR_SYMBOL_AUDIO, + LV_STR_SYMBOL_VIDEO, + LV_STR_SYMBOL_LIST, + LV_STR_SYMBOL_OK, + LV_STR_SYMBOL_CLOSE, + LV_STR_SYMBOL_POWER, + LV_STR_SYMBOL_SETTINGS, + LV_STR_SYMBOL_HOME, + LV_STR_SYMBOL_DOWNLOAD, + LV_STR_SYMBOL_DRIVE, + LV_STR_SYMBOL_REFRESH, + LV_STR_SYMBOL_MUTE, + LV_STR_SYMBOL_VOLUME_MID, + LV_STR_SYMBOL_VOLUME_MAX, + LV_STR_SYMBOL_IMAGE, + LV_STR_SYMBOL_TINT, + LV_STR_SYMBOL_PREV, + LV_STR_SYMBOL_PLAY, + LV_STR_SYMBOL_PAUSE, + LV_STR_SYMBOL_STOP, + LV_STR_SYMBOL_NEXT, + LV_STR_SYMBOL_EJECT, + LV_STR_SYMBOL_LEFT, + LV_STR_SYMBOL_RIGHT, + LV_STR_SYMBOL_PLUS, + LV_STR_SYMBOL_MINUS, + LV_STR_SYMBOL_EYE_OPEN, + LV_STR_SYMBOL_EYE_CLOSE, + LV_STR_SYMBOL_WARNING, + LV_STR_SYMBOL_SHUFFLE, + LV_STR_SYMBOL_UP, + LV_STR_SYMBOL_DOWN, + LV_STR_SYMBOL_LOOP, + LV_STR_SYMBOL_DIRECTORY, + LV_STR_SYMBOL_UPLOAD, + LV_STR_SYMBOL_CALL, + LV_STR_SYMBOL_CUT, + LV_STR_SYMBOL_COPY, + LV_STR_SYMBOL_SAVE, + LV_STR_SYMBOL_BARS, + LV_STR_SYMBOL_ENVELOPE, + LV_STR_SYMBOL_CHARGE, + LV_STR_SYMBOL_PASTE, + LV_STR_SYMBOL_BELL, + LV_STR_SYMBOL_KEYBOARD, + LV_STR_SYMBOL_GPS, + LV_STR_SYMBOL_FILE, + LV_STR_SYMBOL_WIFI, + LV_STR_SYMBOL_BATTERY_FULL, + LV_STR_SYMBOL_BATTERY_3, + LV_STR_SYMBOL_BATTERY_2, + LV_STR_SYMBOL_BATTERY_1, + LV_STR_SYMBOL_BATTERY_EMPTY, + LV_STR_SYMBOL_USB, + LV_STR_SYMBOL_BLUETOOTH, + LV_STR_SYMBOL_TRASH, + LV_STR_SYMBOL_EDIT, + LV_STR_SYMBOL_BACKSPACE, + LV_STR_SYMBOL_SD_CARD, + LV_STR_SYMBOL_NEW_LINE, + LV_STR_SYMBOL_DUMMY, }; #ifdef __cplusplus diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c index 66624922c..5d0810747 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c @@ -1,3 +1,8 @@ +#include "lv_indev_private.h" +#include "../misc/lv_event_private.h" +#include "../misc/lv_area_private.h" +#include "../misc/lv_anim_private.h" +#include "../core/lv_obj_draw_private.h" /** * @file lv_indev.c * @@ -6,16 +11,15 @@ /********************* * INCLUDES ********************/ -#include "lv_indev_private.h" #include "lv_indev_scroll.h" #include "../display/lv_display_private.h" #include "../core/lv_global.h" -#include "../core/lv_obj.h" +#include "../core/lv_obj_private.h" #include "../core/lv_group.h" #include "../core/lv_refr.h" #include "../tick/lv_tick.h" -#include "../misc/lv_timer.h" +#include "../misc/lv_timer_private.h" #include "../misc/lv_math.h" #include "../misc/lv_profiler.h" #include "../stdlib/lv_string.h" @@ -30,7 +34,7 @@ #define LV_INDEV_DEF_SCROLL_THROW 10 /*Long press time in milliseconds. - *Time to send `LV_EVENT_LONG_PRESSSED`)*/ + *Time to send `LV_EVENT_LONG_PRESSED`)*/ #define LV_INDEV_DEF_LONG_PRESS_TIME 400 /*Repeated trigger period in long press [ms] @@ -113,7 +117,7 @@ lv_indev_t * lv_indev_create(void) LV_LOG_WARN("no display was created so far"); } - lv_indev_t * indev = _lv_ll_ins_head(indev_ll_head); + lv_indev_t * indev = lv_ll_ins_head(indev_ll_head); LV_ASSERT_MALLOC(indev); if(indev == NULL) { return NULL; @@ -134,7 +138,7 @@ lv_indev_t * lv_indev_create(void) indev->long_press_repeat_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME; indev->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT; indev->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY; - indev->rotary_sensitvity = LV_INDEV_DEF_ROTARY_SENSITIVITY; + indev->rotary_sensitivity = LV_INDEV_DEF_ROTARY_SENSITIVITY; return indev; } @@ -149,7 +153,7 @@ void lv_indev_delete(lv_indev_t * indev) if(indev->read_timer) lv_timer_delete(indev->read_timer); /*Remove the input device from the list*/ - _lv_ll_remove(indev_ll_head, indev); + lv_ll_remove(indev_ll_head, indev); /*Free the memory of the input device*/ lv_free(indev); } @@ -157,9 +161,9 @@ void lv_indev_delete(lv_indev_t * indev) lv_indev_t * lv_indev_get_next(lv_indev_t * indev) { if(indev == NULL) - return _lv_ll_get_head(indev_ll_head); + return lv_ll_get_head(indev_ll_head); else - return _lv_ll_get_next(indev_ll_head, indev); + return lv_ll_get_next(indev_ll_head, indev); } void indev_read_core(lv_indev_t * indev, lv_indev_data_t * data) @@ -211,8 +215,11 @@ void lv_indev_read(lv_indev_t * indev) /*Handle reset query before processing the point*/ indev_proc_reset_query_handler(indev); - if((indev->enabled == 0) || - (indev->disp->prev_scr != NULL)) return; /*Input disabled or screen animation active*/ + if(indev->enabled == 0) return; + if(indev->disp->prev_scr != NULL) { + LV_TRACE_INDEV("input blocked while screen animation active"); + return; + } LV_PROFILER_BEGIN; @@ -353,6 +360,27 @@ void lv_indev_set_display(lv_indev_t * indev, lv_display_t * disp) indev->disp = disp; } +void lv_indev_set_long_press_time(lv_indev_t * indev, uint16_t long_press_time) +{ + if(indev == NULL) return; + + indev->long_press_time = long_press_time; +} + +void lv_indev_set_scroll_limit(lv_indev_t * indev, uint8_t scroll_limit) +{ + if(indev == NULL) return; + + indev->scroll_limit = scroll_limit; +} + +void lv_indev_set_scroll_throw(lv_indev_t * indev, uint8_t scroll_throw) +{ + if(indev == NULL) return; + + indev->scroll_throw = scroll_throw; +} + void * lv_indev_get_user_data(const lv_indev_t * indev) { if(indev == NULL) return NULL; @@ -366,6 +394,13 @@ void * lv_indev_get_driver_data(const lv_indev_t * indev) return indev->driver_data; } +bool lv_indev_get_press_moved(const lv_indev_t * indev) +{ + if(indev == NULL) return false; + + return indev->pointer.press_moved; +} + void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj) { if(indev) { @@ -381,6 +416,12 @@ void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj) } } +void lv_indev_stop_processing(lv_indev_t * indev) +{ + if(indev == NULL) return; + indev->stop_processing_query = 1; +} + void lv_indev_reset_long_press(lv_indev_t * indev) { indev->long_pr_sent = 0; @@ -531,10 +572,10 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point) /*If the point is on this object check its children too*/ lv_area_t obj_coords = obj->coords; if(lv_obj_has_flag(obj, LV_OBJ_FLAG_OVERFLOW_VISIBLE)) { - int32_t ext_draw_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_draw_size = lv_obj_get_ext_draw_size(obj); lv_area_increase(&obj_coords, ext_draw_size, ext_draw_size); } - if(_lv_area_is_point_on(&obj_coords, &p_trans, 0)) { + if(lv_area_is_point_on(&obj_coords, &p_trans, 0)) { int32_t i; uint32_t child_cnt = lv_obj_get_child_count(obj); @@ -679,7 +720,6 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data) i->pointer.last_point.x = i->pointer.act_point.x; i->pointer.last_point.y = i->pointer.act_point.y; - } /** @@ -907,6 +947,10 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) i->longpr_rep_timestamp = lv_tick_get(); if(data->key == LV_KEY_ENTER) { + /* Always send event to indev callbacks*/ + lv_indev_send_event(indev_act, LV_EVENT_LONG_PRESSED, indev_obj_act); + if(indev_reset_check(indev_act)) return; + bool editable_or_scrollable = lv_obj_is_editable(indev_obj_act) || lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_SCROLLABLE); @@ -922,7 +966,8 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) /*If not editable then just send a long press event*/ else { if(is_enabled) { - if(send_event(LV_EVENT_LONG_PRESSED, indev_act) == LV_RESULT_INVALID) return; + lv_obj_send_event(indev_obj_act, LV_EVENT_LONG_PRESSED, indev_act); + if(indev_reset_check(indev_act)) return; } } } @@ -1116,7 +1161,7 @@ static void indev_proc_press(lv_indev_t * indev) indev_obj_act = pointer_search_obj(disp, &indev->pointer.act_point); new_obj_searched = true; } - /*If there is an active object it's not scrolled and not protected also search*/ + /*If there is an active object it's not scrolled and not press locked also search*/ else if(indev->pointer.scroll_obj == NULL && lv_obj_has_flag(indev_obj_act, LV_OBJ_FLAG_PRESS_LOCK) == false) { indev_obj_act = pointer_search_obj(disp, &indev->pointer.act_point); @@ -1125,14 +1170,13 @@ static void indev_proc_press(lv_indev_t * indev) /*The scroll object might have scroll throw. Stop it manually*/ if(new_obj_searched && indev->pointer.scroll_obj) { - /*Attempt to stop scroll throw animation firstly*/ if(indev->scroll_throw_anim) { lv_anim_delete(indev, indev_scroll_throw_anim_cb); indev->scroll_throw_anim = NULL; } - _lv_indev_scroll_throw_handler(indev); + lv_indev_scroll_throw_handler(indev); if(indev_reset_check(indev)) return; } @@ -1141,6 +1185,17 @@ static void indev_proc_press(lv_indev_t * indev) indev->pointer.last_point.x = indev->pointer.act_point.x; indev->pointer.last_point.y = indev->pointer.act_point.y; + /*Without `LV_OBJ_FLAG_PRESS_LOCK` new widget can be found while pressing.*/ + if(indev->pointer.last_hovered && indev->pointer.last_hovered != indev_obj_act) { + lv_obj_send_event(indev->pointer.last_hovered, LV_EVENT_HOVER_LEAVE, indev); + if(indev_reset_check(indev)) return; + + lv_indev_send_event(indev, LV_EVENT_HOVER_LEAVE, indev->pointer.last_hovered); + if(indev_reset_check(indev)) return; + + indev->pointer.last_hovered = indev_obj_act; + } + /*If a new object found the previous was lost, so send a PRESS_LOST event*/ if(indev->pointer.act_obj != NULL) { /*Save the obj because in special cases `act_obj` can change in the event */ @@ -1171,11 +1226,15 @@ static void indev_proc_press(lv_indev_t * indev) indev->pointer.gesture_sent = 0; indev->pointer.gesture_sum.x = 0; indev->pointer.gesture_sum.y = 0; + indev->pointer.press_moved = 0; indev->pointer.vect.x = 0; indev->pointer.vect.y = 0; const bool is_enabled = !lv_obj_has_state(indev_obj_act, LV_STATE_DISABLED); if(is_enabled) { + if(indev->pointer.last_hovered != indev_obj_act) { + if(send_event(LV_EVENT_HOVER_OVER, indev_act) == LV_RESULT_INVALID) return; + } if(send_event(LV_EVENT_PRESSED, indev_act) == LV_RESULT_INVALID) return; } @@ -1197,6 +1256,10 @@ static void indev_proc_press(lv_indev_t * indev) indev->pointer.scroll_throw_vect_ori = indev->pointer.scroll_throw_vect; + if(LV_ABS(indev->pointer.vect.x) > indev->scroll_limit || LV_ABS(indev->pointer.vect.y) > indev->scroll_limit) { + indev->pointer.press_moved = 1; + } + if(indev_obj_act) { const bool is_enabled = !lv_obj_has_state(indev_obj_act, LV_STATE_DISABLED); @@ -1206,7 +1269,7 @@ static void indev_proc_press(lv_indev_t * indev) if(indev_act->wait_until_release) return; - _lv_indev_scroll_handler(indev); + lv_indev_scroll_handler(indev); if(indev_reset_check(indev)) return; indev_gesture(indev); if(indev_reset_check(indev)) return; @@ -1247,6 +1310,25 @@ static void indev_proc_press(lv_indev_t * indev) */ static void indev_proc_release(lv_indev_t * indev) { + if(indev->wait_until_release || /*Hover the new widget even if the coordinates didn't changed*/ + (indev->pointer.last_point.x != indev->pointer.act_point.x || + indev->pointer.last_point.y != indev->pointer.act_point.y)) { + lv_obj_t ** last = &indev->pointer.last_hovered; + lv_obj_t * hovered = pointer_search_obj(lv_display_get_default(), &indev->pointer.act_point); + if(*last != hovered) { + lv_obj_send_event(hovered, LV_EVENT_HOVER_OVER, indev); + if(indev_reset_check(indev)) return; + lv_indev_send_event(indev, LV_EVENT_HOVER_OVER, hovered); + if(indev_reset_check(indev)) return; + + lv_obj_send_event(*last, LV_EVENT_HOVER_LEAVE, indev); + if(indev_reset_check(indev)) return; + lv_indev_send_event(indev, LV_EVENT_HOVER_LEAVE, *last); + if(indev_reset_check(indev)) return; + *last = hovered; + } + } + if(indev->wait_until_release) { lv_obj_send_event(indev->pointer.act_obj, LV_EVENT_PRESS_LOST, indev_act); if(indev_reset_check(indev)) return; @@ -1281,7 +1363,8 @@ static void indev_proc_release(lv_indev_t * indev) if(send_event(LV_EVENT_CLICKED, indev_act) == LV_RESULT_INVALID) return; } else { - if(send_event(LV_EVENT_SCROLL_THROW_BEGIN, indev_act) == LV_RESULT_INVALID) return; + lv_obj_send_event(scroll_obj, LV_EVENT_SCROLL_THROW_BEGIN, indev_act); + if(indev_reset_check(indev)) return; } } indev->pointer.act_obj = NULL; @@ -1334,7 +1417,7 @@ static void indev_proc_pointer_diff(lv_indev_t * indev) bool editable = lv_obj_is_editable(obj); if(editable) { - uint32_t indev_sensitivity = indev->rotary_sensitvity; + uint32_t indev_sensitivity = indev->rotary_sensitivity; uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(indev_obj_act, 0); int32_t diff = (int32_t)((int32_t)indev->pointer.diff * indev_sensitivity * obj_sensitivity + 32768) >> 16; send_event(LV_EVENT_ROTARY, &diff); @@ -1346,13 +1429,13 @@ static void indev_proc_pointer_diff(lv_indev_t * indev) indev->pointer.act_obj = obj; lv_obj_t * scroll_obj = lv_indev_find_scroll_obj(indev); if(scroll_obj == NULL) return; - uint32_t indev_sensitivity = indev->rotary_sensitvity; + uint32_t indev_sensitivity = indev->rotary_sensitivity; uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(scroll_obj, 0); int32_t diff = (int32_t)((int32_t)indev->pointer.diff * indev_sensitivity * obj_sensitivity + 32768) >> 16; indev->pointer.scroll_throw_vect.y = diff; indev->pointer.scroll_throw_vect_ori.y = diff; - _lv_indev_scroll_handler(indev); + lv_indev_scroll_handler(indev); } } @@ -1385,7 +1468,8 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) if(indev->reset_query) { indev->pointer.act_obj = NULL; indev->pointer.last_obj = NULL; - indev->pointer.scroll_obj = NULL; + indev->pointer.scroll_obj = NULL; + indev->pointer.last_hovered = NULL; indev->long_pr_sent = 0; indev->pr_timestamp = 0; indev->longpr_rep_timestamp = 0; @@ -1398,6 +1482,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) indev->pointer.gesture_sum.x = 0; indev->pointer.gesture_sum.y = 0; indev->reset_query = 0; + indev->stop_processing_query = 0; indev_obj_act = NULL; } } @@ -1519,7 +1604,7 @@ void indev_gesture(lv_indev_t * indev) lv_obj_send_event(gesture_obj, LV_EVENT_GESTURE, indev_act); if(indev_reset_check(indev)) return; - lv_indev_send_event(indev_act, LV_EVENT_LONG_PRESSED, gesture_obj); + lv_indev_send_event(indev_act, LV_EVENT_GESTURE, gesture_obj); if(indev_reset_check(indev_act)) return; } } @@ -1538,6 +1623,16 @@ static bool indev_reset_check(lv_indev_t * indev) return indev->reset_query; } +/** + * Checks if the stop_processing_query flag has been set. If so, do not send any events to the object + * @param indev pointer to an input device + * @return true if indev should stop processing the event. + */ +static bool indev_stop_processing_check(lv_indev_t * indev) +{ + return indev->stop_processing_query; +} + /** * Reset the indev and send event to active obj and scroll obj * @param indev pointer to an input device @@ -1577,24 +1672,36 @@ static void indev_reset_core(lv_indev_t * indev, lv_obj_t * obj) scroll_obj = NULL; } } + if(obj == NULL || indev->pointer.last_hovered == obj) { + indev->pointer.last_hovered = NULL; + } } } static lv_result_t send_event(lv_event_code_t code, void * param) { - lv_obj_send_event(indev_obj_act, code, param); - if(indev_reset_check(indev_act)) return LV_RESULT_INVALID; + lv_indev_t * indev = indev_act; if(code == LV_EVENT_PRESSED || + code == LV_EVENT_SHORT_CLICKED || code == LV_EVENT_CLICKED || code == LV_EVENT_RELEASED || code == LV_EVENT_LONG_PRESSED || code == LV_EVENT_LONG_PRESSED_REPEAT || code == LV_EVENT_ROTARY) { - lv_indev_send_event(indev_act, code, indev_obj_act); - if(indev_reset_check(indev_act)) return LV_RESULT_INVALID; + lv_indev_send_event(indev, code, indev_obj_act); + if(indev_reset_check(indev)) return LV_RESULT_INVALID; + + if(indev_stop_processing_check(indev)) { + /* Not send event to the object if stop processing query is set */ + indev->stop_processing_query = 0; + return LV_RESULT_OK; + } } + lv_obj_send_event(indev_obj_act, code, param); + if(indev_reset_check(indev)) return LV_RESULT_INVALID; + return LV_RESULT_OK; } @@ -1604,7 +1711,7 @@ static void indev_scroll_throw_anim_cb(void * var, int32_t v) LV_UNUSED(v); lv_indev_t * indev = (lv_indev_t *)var; - _lv_indev_scroll_throw_handler(indev); + lv_indev_scroll_throw_handler(indev); if(indev->pointer.scroll_dir == LV_DIR_NONE || indev->pointer.scroll_obj == NULL) { if(indev->scroll_throw_anim) { diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h index ea5794f2e..9b0ee4518 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h @@ -54,7 +54,7 @@ typedef struct { uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/ int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/ - lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/ + lv_indev_state_t state; /**< LV_INDEV_STATE_RELEASED or LV_INDEV_STATE_PRESSED*/ bool continue_reading; /**< If set to true, the read callback is invoked again, unless the device is in event-driven mode*/ } lv_indev_data_t; @@ -143,7 +143,28 @@ void lv_indev_set_driver_data(lv_indev_t * indev, void * driver_data); * @param indev pointer to an input device * @param disp pointer to an display */ -void lv_indev_set_display(lv_indev_t * indev, struct _lv_display_t * disp); +void lv_indev_set_display(lv_indev_t * indev, struct lv_display_t * disp); + +/** + * Set long press time to indev + * @param indev pointer to input device + * @param long_press_time time long press time in ms + */ +void lv_indev_set_long_press_time(lv_indev_t * indev, uint16_t long_press_time); + +/** + * Set scroll limit to the input device + * @param indev pointer to an input device + * @param scroll_limit the number of pixels to slide before actually drag the object + */ +void lv_indev_set_scroll_limit(lv_indev_t * indev, uint8_t scroll_limit); + +/** + * Set scroll throw slow-down to the indev. Greater value means faster slow-down + * @param indev pointer to an input device + * @param scroll_throw the slow-down in [%] + */ +void lv_indev_set_scroll_throw(lv_indev_t * indev, uint8_t scroll_throw); /** * Get the type of an input device @@ -194,6 +215,13 @@ void * lv_indev_get_user_data(const lv_indev_t * indev); */ void * lv_indev_get_driver_data(const lv_indev_t * indev); +/** + * Get whether indev is moved while pressed + * @param indev pointer to an input device + * @return true: indev is moved while pressed; false: indev is not moved while pressed + */ +bool lv_indev_get_press_moved(const lv_indev_t * indev); + /** * Reset one or all input devices * @param indev pointer to an input device to reset or NULL to reset all of them @@ -201,6 +229,13 @@ void * lv_indev_get_driver_data(const lv_indev_t * indev); */ void lv_indev_reset(lv_indev_t * indev, lv_obj_t * obj); +/** + * Touch and key related events are sent to the input device first and to the widget after that. + * If this functions called in an indev event, the event won't be sent to the widget. + * @param indev pointer to an input device + */ +void lv_indev_stop_processing(lv_indev_t * indev); + /** * Reset the long press state of an input device * @param indev pointer to an input device diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_private.h b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_private.h index 96ba4739a..a5fa23164 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_private.h +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_private.h @@ -23,11 +23,11 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_indev_t { - /**< Input device type*/ +struct lv_indev_t { + /** Input device type*/ lv_indev_type_t type; - /**< Function pointer to read input device data.*/ + /** Function pointer to read input device data.*/ lv_indev_read_cb_t read_cb; lv_indev_state_t state; /**< Current state of the input device.*/ @@ -38,6 +38,7 @@ struct _lv_indev_t { uint8_t reset_query : 1; uint8_t enabled : 1; uint8_t wait_until_release : 1; + uint8_t stop_processing_query : 1; uint32_t pr_timestamp; /**< Pressed time stamp*/ uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/ @@ -70,7 +71,7 @@ struct _lv_indev_t { uint16_t long_press_repeat_time; /**< Rotary diff count will be multiplied by this value and divided by 256*/ - int32_t rotary_sensitvity; + int32_t rotary_sensitivity; struct { /*Pointer and button data*/ @@ -85,14 +86,16 @@ struct _lv_indev_t { lv_obj_t * last_obj; /*The last object which was pressed*/ lv_obj_t * scroll_obj; /*The object being scrolled*/ lv_obj_t * last_pressed; /*The lastly pressed object*/ + lv_obj_t * last_hovered; /*The lastly hovered object*/ lv_area_t scroll_area; lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/ int32_t diff; /*Flags*/ - lv_dir_t scroll_dir : 4; - lv_dir_t gesture_dir : 4; + uint8_t scroll_dir : 4; + uint8_t gesture_dir : 4; uint8_t gesture_sent : 1; + uint8_t press_moved : 1; } pointer; struct { /*Keypad data*/ diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.c b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.c index 947bda5e6..f32786577 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.c +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.c @@ -6,6 +6,8 @@ /********************* * INCLUDES *********************/ +#include "../core/lv_obj_scroll_private.h" +#include "../core/lv_obj_private.h" #include "lv_indev.h" #include "lv_indev_private.h" #include "lv_indev_scroll.h" @@ -41,7 +43,7 @@ static int32_t elastic_diff(lv_obj_t * scroll_obj, int32_t diff, int32_t scroll_ * GLOBAL FUNCTIONS **********************/ -void _lv_indev_scroll_handler(lv_indev_t * indev) +void lv_indev_scroll_handler(lv_indev_t * indev) { if(indev->pointer.vect.x == 0 && indev->pointer.vect.y == 0) { return; @@ -104,13 +106,13 @@ void _lv_indev_scroll_handler(lv_indev_t * indev) /*Respect the scroll limit area*/ scroll_limit_diff(indev, &diff_x, &diff_y); - _lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y); + lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y); if(indev->reset_query) return; indev->pointer.scroll_sum.x += diff_x; indev->pointer.scroll_sum.y += diff_y; } -void _lv_indev_scroll_throw_handler(lv_indev_t * indev) +void lv_indev_scroll_throw_handler(lv_indev_t * indev) { lv_obj_t * scroll_obj = indev->pointer.scroll_obj; if(scroll_obj == NULL) return; @@ -139,7 +141,7 @@ void _lv_indev_scroll_throw_handler(lv_indev_t * indev) indev->pointer.scroll_throw_vect.y = elastic_diff(scroll_obj, indev->pointer.scroll_throw_vect.y, st, sb, LV_DIR_VER); - _lv_obj_scroll_by_raw(scroll_obj, 0, indev->pointer.scroll_throw_vect.y); + lv_obj_scroll_by_raw(scroll_obj, 0, indev->pointer.scroll_throw_vect.y); if(indev->reset_query) return; } /*With snapping find the nearest snap point and scroll there*/ @@ -165,7 +167,7 @@ void _lv_indev_scroll_throw_handler(lv_indev_t * indev) indev->pointer.scroll_throw_vect.x = elastic_diff(scroll_obj, indev->pointer.scroll_throw_vect.x, sl, sr, LV_DIR_HOR); - _lv_obj_scroll_by_raw(scroll_obj, indev->pointer.scroll_throw_vect.x, 0); + lv_obj_scroll_by_raw(scroll_obj, indev->pointer.scroll_throw_vect.x, 0); if(indev->reset_query) return; } /*With snapping find the nearest snap point and scroll there*/ @@ -327,11 +329,58 @@ lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev) if((scroll_dir & LV_DIR_TOP) == 0) up_en = false; if((scroll_dir & LV_DIR_BOTTOM) == 0) down_en = false; - /*The object is scrollable to a direction if its content overflow in that direction.*/ - int32_t st = lv_obj_get_scroll_top(obj_act); - int32_t sb = lv_obj_get_scroll_bottom(obj_act); - int32_t sl = lv_obj_get_scroll_left(obj_act); - int32_t sr = lv_obj_get_scroll_right(obj_act); + /*The object is scrollable to a direction if its content overflow in that direction. + *If there are at least 2 snapable children always assume + *scrolling to allow scrolling to the other child*/ + uint32_t snap_cnt = 0; + + /*Horizontal scroll*/ + int32_t sl = 0; + int32_t sr = 0; + lv_scroll_snap_t snap_x = lv_obj_get_scroll_snap_x(obj_act); + if(snap_x != LV_SCROLL_SNAP_NONE) { + uint32_t child_cnt = lv_obj_get_child_count(obj_act); + uint32_t i; + for(i = 0; i < child_cnt; i++) { + if(lv_obj_has_flag(lv_obj_get_child(obj_act, i), LV_OBJ_FLAG_SNAPPABLE)) { + snap_cnt++; + if(snap_cnt == 2) { + sl = 1; /*Assume scrolling*/ + sr = 1; + break; + } + } + } + } + if(snap_x == LV_SCROLL_SNAP_NONE || snap_cnt < 2) { + sl = lv_obj_get_scroll_left(obj_act); + sr = lv_obj_get_scroll_right(obj_act); + } + + /*Vertical scroll*/ + snap_cnt = 0; + int32_t st = 0; + int32_t sb = 0; + lv_scroll_snap_t snap_y = lv_obj_get_scroll_snap_y(obj_act); + if(snap_y != LV_SCROLL_SNAP_NONE) { + uint32_t child_cnt = lv_obj_get_child_count(obj_act); + uint32_t i; + for(i = 0; i < child_cnt; i++) { + if(lv_obj_has_flag(lv_obj_get_child(obj_act, i), LV_OBJ_FLAG_SNAPPABLE)) { + snap_cnt++; + if(snap_cnt == 2) { + st = 1; /*Assume scrolling*/ + sb = 1; + break; + } + } + } + } + if(snap_y == LV_SCROLL_SNAP_NONE || snap_cnt < 2) { + st = lv_obj_get_scroll_top(obj_act); + sb = lv_obj_get_scroll_bottom(obj_act); + } + /*If this object is scrollable into the current scroll direction then save it as a candidate. *It's important only to be scrollable on the current axis (hor/ver) because if the scroll @@ -440,6 +489,11 @@ static void init_scroll_limits(lv_indev_t * indev) } } + /*`find_snap_point_x/y()` return LV_COORD_MAX is not snap point was found, + *but x1/y1 should be small. */ + if(indev->pointer.scroll_area.x1 == LV_COORD_MAX) indev->pointer.scroll_area.x1 = LV_COORD_MIN; + if(indev->pointer.scroll_area.y1 == LV_COORD_MAX) indev->pointer.scroll_area.y1 = LV_COORD_MIN; + /*Allow scrolling on the edges. It will be reverted to the edge due to snapping anyway*/ if(indev->pointer.scroll_area.x1 == 0) indev->pointer.scroll_area.x1 = LV_COORD_MIN; if(indev->pointer.scroll_area.x2 == 0) indev->pointer.scroll_area.x2 = LV_COORD_MAX; @@ -448,18 +502,19 @@ static void init_scroll_limits(lv_indev_t * indev) } /** - * Search for snap point in the `min` - `max` range. + * Search for snap point in the min..max range. * @param obj the object on which snap point should be found * @param min ignore snap points smaller than this. (Absolute coordinate) * @param max ignore snap points greater than this. (Absolute coordinate) * @param ofs offset to snap points. Useful the get a snap point in an imagined case * what if children are already moved by this value - * @return the distance of the snap point. + * @return the absolute x coordinate of the nearest snap point + * or `LV_COORD_MAX` if there is no snap point in the min..max range */ static int32_t find_snap_point_x(const lv_obj_t * obj, int32_t min, int32_t max, int32_t ofs) { lv_scroll_snap_t align = lv_obj_get_scroll_snap_x(obj); - if(align == LV_SCROLL_SNAP_NONE) return 0; + if(align == LV_SCROLL_SNAP_NONE) return LV_COORD_MAX; int32_t dist = LV_COORD_MAX; @@ -499,22 +554,23 @@ static int32_t find_snap_point_x(const lv_obj_t * obj, int32_t min, int32_t max, } } - return dist == LV_COORD_MAX ? 0 : -dist; + return dist == LV_COORD_MAX ? LV_COORD_MAX : -dist; } /** - * Search for snap point in the `min` - `max` range. + * Search for snap point in the min..max range. * @param obj the object on which snap point should be found * @param min ignore snap points smaller than this. (Absolute coordinate) * @param max ignore snap points greater than this. (Absolute coordinate) * @param ofs offset to snap points. Useful to get a snap point in an imagined case * what if children are already moved by this value - * @return the distance of the snap point. + * @return the absolute y coordinate of the nearest snap point + * or `LV_COORD_MAX` if there is no snap point in the min..max range */ static int32_t find_snap_point_y(const lv_obj_t * obj, int32_t min, int32_t max, int32_t ofs) { lv_scroll_snap_t align = lv_obj_get_scroll_snap_y(obj); - if(align == LV_SCROLL_SNAP_NONE) return 0; + if(align == LV_SCROLL_SNAP_NONE) return LV_COORD_MAX; int32_t dist = LV_COORD_MAX; @@ -554,7 +610,7 @@ static int32_t find_snap_point_y(const lv_obj_t * obj, int32_t min, int32_t max, } } - return dist == LV_COORD_MAX ? 0 : -dist; + return dist == LV_COORD_MAX ? LV_COORD_MAX : -dist; } static void scroll_limit_diff(lv_indev_t * indev, int32_t * diff_x, int32_t * diff_y) @@ -583,76 +639,94 @@ static void scroll_limit_diff(lv_indev_t * indev, int32_t * diff_x, int32_t * di static int32_t elastic_diff(lv_obj_t * scroll_obj, int32_t diff, int32_t scroll_start, int32_t scroll_end, lv_dir_t dir) { - if(lv_obj_has_flag(scroll_obj, LV_OBJ_FLAG_SCROLL_ELASTIC)) { + /*Scroll back to the edge if required*/ + if(!lv_obj_has_flag(scroll_obj, LV_OBJ_FLAG_SCROLL_ELASTIC)) { + if(scroll_end + diff < 0) diff = - scroll_end; + if(scroll_start - diff < 0) diff = scroll_start; + } + /*Handle elastic scrolling*/ + else { /*If there is snapping in the current direction don't use the elastic factor because *it's natural that the first and last items are scrolled (snapped) in.*/ lv_scroll_snap_t snap; snap = dir == LV_DIR_HOR ? lv_obj_get_scroll_snap_x(scroll_obj) : lv_obj_get_scroll_snap_y(scroll_obj); - lv_obj_t * act_obj = lv_indev_get_active_obj(); - int32_t snap_point = 0; - int32_t act_obj_point = 0; + bool no_more_start_snap = false; + bool no_more_end_snap = false; - if(dir == LV_DIR_HOR) { - int32_t pad_left = lv_obj_get_style_pad_left(scroll_obj, LV_PART_MAIN); - int32_t pad_right = lv_obj_get_style_pad_right(scroll_obj, LV_PART_MAIN); - - switch(snap) { - case LV_SCROLL_SNAP_CENTER: - snap_point = pad_left + (lv_area_get_width(&scroll_obj->coords) - pad_left - pad_right) / 2 + scroll_obj->coords.x1; - act_obj_point = lv_area_get_width(&act_obj->coords) / 2 + act_obj->coords.x1; - break; - case LV_SCROLL_SNAP_START: - snap_point = scroll_obj->coords.x1 + pad_left; - act_obj_point = act_obj->coords.x1; - break; - case LV_SCROLL_SNAP_END: - snap_point = scroll_obj->coords.x2 - pad_right; - act_obj_point = act_obj->coords.x2; - break; + /*Without snapping just scale down the diff is scrolled out*/ + if(snap == LV_SCROLL_SNAP_NONE) { + if(scroll_end < 0 || scroll_start < 0) { + /*Rounding*/ + if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2; + if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2; + diff = diff / ELASTIC_SLOWNESS_FACTOR; } } + /*With snapping the widget is scrolled out if there are no more snap points*/ + else { + if(dir == LV_DIR_HOR) { + int32_t x = 0; + switch(snap) { + case LV_SCROLL_SNAP_CENTER: { + int32_t pad_left = lv_obj_get_style_pad_left(scroll_obj, 0); + int32_t pad_right = lv_obj_get_style_pad_right(scroll_obj, 0); + x = scroll_obj->coords.x1; + x += (lv_area_get_width(&scroll_obj->coords) - pad_left - pad_right) / 2; + x += pad_left; + } + break; + case LV_SCROLL_SNAP_START: + x = scroll_obj->coords.x1 + lv_obj_get_style_pad_left(scroll_obj, 0); + break; + case LV_SCROLL_SNAP_END: + x = scroll_obj->coords.x2 - lv_obj_get_style_pad_right(scroll_obj, 0); + break; + default: + break; + } + int32_t d; + d = find_snap_point_x(scroll_obj, x + 1, LV_COORD_MAX, 0); + if(d == LV_COORD_MAX) no_more_end_snap = true; + d = find_snap_point_x(scroll_obj, LV_COORD_MIN, x, 0); + if(d == LV_COORD_MAX) no_more_start_snap = true; + } + else { + int32_t y = 0; + switch(snap) { + case LV_SCROLL_SNAP_CENTER: { + int32_t pad_top = lv_obj_get_style_pad_top(scroll_obj, 0); + int32_t pad_bottom = lv_obj_get_style_pad_bottom(scroll_obj, 0); + y = scroll_obj->coords.y1; + y += (lv_area_get_height(&scroll_obj->coords) - pad_top - pad_bottom) / 2; + y += pad_top; + } + break; + case LV_SCROLL_SNAP_START: + y = scroll_obj->coords.y1 + lv_obj_get_style_pad_top(scroll_obj, 0); + break; + case LV_SCROLL_SNAP_END: + y = scroll_obj->coords.y2 - lv_obj_get_style_pad_bottom(scroll_obj, 0); + break; + default: + break; + } + int32_t d; + d = find_snap_point_y(scroll_obj, y, LV_COORD_MAX, 0); + if(d == LV_COORD_MAX) no_more_end_snap = true; + d = find_snap_point_y(scroll_obj, LV_COORD_MIN, y, 0); + if(d == LV_COORD_MAX) no_more_start_snap = true; + } + } + + if(no_more_start_snap || no_more_end_snap) { + if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2; + if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2; + return diff / ELASTIC_SLOWNESS_FACTOR; + } else { - int32_t pad_top = lv_obj_get_style_pad_top(scroll_obj, LV_PART_MAIN); - int32_t pad_bottom = lv_obj_get_style_pad_bottom(scroll_obj, LV_PART_MAIN); - - switch(snap) { - case LV_SCROLL_SNAP_CENTER: - snap_point = pad_top + (lv_area_get_height(&scroll_obj->coords) - pad_top - pad_bottom) / 2 + scroll_obj->coords.y1; - act_obj_point = lv_area_get_height(&act_obj->coords) / 2 + act_obj->coords.y1; - break; - case LV_SCROLL_SNAP_START: - snap_point = scroll_obj->coords.y1 + pad_top; - act_obj_point = act_obj->coords.y1; - break; - case LV_SCROLL_SNAP_END: - snap_point = scroll_obj->coords.y2 - pad_bottom; - act_obj_point = act_obj->coords.y2; - break; - } + return diff; } - - if(scroll_end < 0) { - if(snap != LV_SCROLL_SNAP_NONE && act_obj_point > snap_point) return diff; - - /*Rounding*/ - if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2; - if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2; - return diff / ELASTIC_SLOWNESS_FACTOR; - } - else if(scroll_start < 0) { - if(snap != LV_SCROLL_SNAP_NONE && act_obj_point < snap_point) return diff; - - /*Rounding*/ - if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2; - if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2; - return diff / ELASTIC_SLOWNESS_FACTOR; - } - } - else { - /*Scroll back to the boundary if required*/ - if(scroll_end + diff < 0) diff = - scroll_end; - if(scroll_start - diff < 0) diff = scroll_start; } return diff; diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.h b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.h index 64d1d018b..413376f16 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.h +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.h @@ -31,13 +31,13 @@ extern "C" { * Handle scrolling. Called by LVGL during input device processing * @param indev pointer to an input device */ -void _lv_indev_scroll_handler(lv_indev_t * indev); +void lv_indev_scroll_handler(lv_indev_t * indev); /** * Handle throwing after scrolling. Called by LVGL during input device processing * @param indev pointer to an input device */ -void _lv_indev_scroll_throw_handler(lv_indev_t * indev); +void lv_indev_scroll_throw_handler(lv_indev_t * indev); /** * Predict where would a scroll throw end diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.c b/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.c index 168f9de90..2af3bf35a 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.c +++ b/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.c @@ -8,7 +8,7 @@ *********************/ #include "lv_flex.h" #include "../lv_layout.h" -#include "../../core/lv_obj.h" +#include "../../core/lv_obj_private.h" #if LV_USE_FLEX @@ -96,7 +96,6 @@ void lv_flex_init(void) { layout_list_def[LV_LAYOUT_FLEX].cb = flex_update; layout_list_def[LV_LAYOUT_FLEX].user_data = NULL; - } void lv_obj_set_flex_flow(lv_obj_t * obj, lv_flex_flow_t flow) @@ -131,9 +130,9 @@ static void flex_update(lv_obj_t * cont, void * user_data) flex_t f; lv_flex_flow_t flow = lv_obj_get_style_flex_flow(cont, LV_PART_MAIN); - f.row = flow & _LV_FLEX_COLUMN ? 0 : 1; - f.wrap = flow & _LV_FLEX_WRAP ? 1 : 0; - f.rev = flow & _LV_FLEX_REVERSE ? 1 : 0; + f.row = flow & LV_FLEX_COLUMN ? 0 : 1; + f.wrap = flow & LV_FLEX_WRAP ? 1 : 0; + f.rev = flow & LV_FLEX_REVERSE ? 1 : 0; f.main_place = lv_obj_get_style_flex_main_place(cont, LV_PART_MAIN); f.cross_place = lv_obj_get_style_flex_cross_place(cont, LV_PART_MAIN); f.track_place = lv_obj_get_style_flex_track_place(cont, LV_PART_MAIN); @@ -472,7 +471,6 @@ static void place_content(lv_flex_align_t place, int32_t max_size, int32_t conte { if(item_cnt <= 1) { switch(place) { - case LV_FLEX_ALIGN_SPACE_BETWEEN: case LV_FLEX_ALIGN_SPACE_AROUND: case LV_FLEX_ALIGN_SPACE_EVENLY: place = LV_FLEX_ALIGN_CENTER; @@ -492,7 +490,7 @@ static void place_content(lv_flex_align_t place, int32_t max_size, int32_t conte *start_pos += max_size - content_size; break; case LV_FLEX_ALIGN_SPACE_BETWEEN: - *gap = (int32_t)(max_size - content_size) / (int32_t)(item_cnt - 1); + if(item_cnt > 1) *gap = (int32_t)(max_size - content_size) / (int32_t)(item_cnt - 1); break; case LV_FLEX_ALIGN_SPACE_AROUND: *gap += (int32_t)(max_size - content_size) / (int32_t)(item_cnt); diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.h b/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.h index 17e62790e..9724f9b1c 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.h +++ b/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.h @@ -22,9 +22,9 @@ extern "C" { * DEFINES *********************/ -#define _LV_FLEX_COLUMN (1 << 0) -#define _LV_FLEX_WRAP (1 << 2) -#define _LV_FLEX_REVERSE (1 << 3) +#define LV_FLEX_COLUMN (1 << 0) +#define LV_FLEX_WRAP (1 << 2) +#define LV_FLEX_REVERSE (1 << 3) /********************** * TYPEDEFS @@ -43,13 +43,13 @@ typedef enum { typedef enum { LV_FLEX_FLOW_ROW = 0x00, - LV_FLEX_FLOW_COLUMN = _LV_FLEX_COLUMN, - LV_FLEX_FLOW_ROW_WRAP = LV_FLEX_FLOW_ROW | _LV_FLEX_WRAP, - LV_FLEX_FLOW_ROW_REVERSE = LV_FLEX_FLOW_ROW | _LV_FLEX_REVERSE, - LV_FLEX_FLOW_ROW_WRAP_REVERSE = LV_FLEX_FLOW_ROW | _LV_FLEX_WRAP | _LV_FLEX_REVERSE, - LV_FLEX_FLOW_COLUMN_WRAP = LV_FLEX_FLOW_COLUMN | _LV_FLEX_WRAP, - LV_FLEX_FLOW_COLUMN_REVERSE = LV_FLEX_FLOW_COLUMN | _LV_FLEX_REVERSE, - LV_FLEX_FLOW_COLUMN_WRAP_REVERSE = LV_FLEX_FLOW_COLUMN | _LV_FLEX_WRAP | _LV_FLEX_REVERSE, + LV_FLEX_FLOW_COLUMN = LV_FLEX_COLUMN, + LV_FLEX_FLOW_ROW_WRAP = LV_FLEX_FLOW_ROW | LV_FLEX_WRAP, + LV_FLEX_FLOW_ROW_REVERSE = LV_FLEX_FLOW_ROW | LV_FLEX_REVERSE, + LV_FLEX_FLOW_ROW_WRAP_REVERSE = LV_FLEX_FLOW_ROW | LV_FLEX_WRAP | LV_FLEX_REVERSE, + LV_FLEX_FLOW_COLUMN_WRAP = LV_FLEX_FLOW_COLUMN | LV_FLEX_WRAP, + LV_FLEX_FLOW_COLUMN_REVERSE = LV_FLEX_FLOW_COLUMN | LV_FLEX_REVERSE, + LV_FLEX_FLOW_COLUMN_WRAP_REVERSE = LV_FLEX_FLOW_COLUMN | LV_FLEX_WRAP | LV_FLEX_REVERSE, } lv_flex_flow_t; /********************** @@ -61,8 +61,7 @@ typedef enum { **********************/ /** - * Initialize a flex layout the default values - * @param flex pointer to a flex layout descriptor + * Initialize a flex layout to default values */ void lv_flex_init(void); diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.c b/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.c index e5da88270..70d3f7936 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.c +++ b/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.c @@ -12,7 +12,7 @@ #include "../../stdlib/lv_string.h" #include "../lv_layout.h" -#include "../../core/lv_obj.h" +#include "../../core/lv_obj_private.h" #include "../../core/lv_global.h" /********************* * DEFINES @@ -44,7 +44,7 @@ typedef struct { uint32_t row_num; int32_t grid_w; int32_t grid_h; -} _lv_grid_calc_t; +} lv_grid_calc_t; /********************** * GLOBAL PROTOTYPES @@ -54,11 +54,11 @@ typedef struct { * STATIC PROTOTYPES **********************/ static void grid_update(lv_obj_t * cont, void * user_data); -static void calc(lv_obj_t * obj, _lv_grid_calc_t * calc); -static void calc_free(_lv_grid_calc_t * calc); -static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c); -static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c); -static void item_repos(lv_obj_t * item, _lv_grid_calc_t * c, item_repos_hint_t * hint); +static void calc(lv_obj_t * obj, lv_grid_calc_t * calc); +static void calc_free(lv_grid_calc_t * calc); +static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c); +static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c); +static void item_repos(lv_obj_t * item, lv_grid_calc_t * c, item_repos_hint_t * hint); static int32_t grid_align(int32_t cont_size, bool auto_size, lv_grid_align_t align, int32_t gap, uint32_t track_num, int32_t * size_array, int32_t * pos_array, bool reverse); @@ -115,6 +115,11 @@ static inline int32_t get_margin_ver(lv_obj_t * obj) + lv_obj_get_style_margin_bottom(obj, LV_PART_MAIN); } +static inline int32_t div_round_closest(int32_t dividend, int32_t divisor) +{ + return (dividend + divisor / 2) / divisor; +} + /********************** * GLOBAL VARIABLES **********************/ @@ -170,6 +175,11 @@ void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_align_t x_align, int32_t col_p lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj)); } +int32_t lv_grid_fr(uint8_t x) +{ + return LV_GRID_FR(x); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -183,7 +193,7 @@ static void grid_update(lv_obj_t * cont, void * user_data) // const int32_t * row_templ = get_row_dsc(cont); // if(col_templ == NULL || row_templ == NULL) return; - _lv_grid_calc_t c; + lv_grid_calc_t c; calc(cont, &c); item_repos_hint_t hint; @@ -218,12 +228,12 @@ static void grid_update(lv_obj_t * cont, void * user_data) * Calculate the grid cells coordinates * @param cont an object that has a grid * @param calc store the calculated cells sizes here - * @note `_lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore + * @note `lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore */ -static void calc(lv_obj_t * cont, _lv_grid_calc_t * calc_out) +static void calc(lv_obj_t * cont, lv_grid_calc_t * calc_out) { if(lv_obj_get_child(cont, 0) == NULL) { - lv_memzero(calc_out, sizeof(_lv_grid_calc_t)); + lv_memzero(calc_out, sizeof(lv_grid_calc_t)); return; } @@ -254,7 +264,7 @@ static void calc(lv_obj_t * cont, _lv_grid_calc_t * calc_out) * Free the a grid calculation's data * @param calc pointer to the calculated grid cell coordinates */ -static void calc_free(_lv_grid_calc_t * calc) +static void calc_free(lv_grid_calc_t * calc) { lv_free(calc->x); lv_free(calc->y); @@ -262,7 +272,7 @@ static void calc_free(_lv_grid_calc_t * calc) lv_free(calc->h); } -static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c) +static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c) { const int32_t * col_templ; @@ -337,29 +347,25 @@ static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c) int32_t free_w = cont_w - grid_w; if(free_w < 0) free_w = 0; - int32_t last_fr_i = -1; - int32_t last_fr_x = 0; - for(i = 0; i < c->col_num; i++) { + for(i = 0; i < c->col_num && col_fr_cnt; i++) { int32_t x = col_templ[i]; if(IS_FR(x)) { int32_t f = GET_FR(x); - c->w[i] = (free_w * f) / col_fr_cnt; - last_fr_i = i; - last_fr_x = f; + c->w[i] = div_round_closest(free_w * f, col_fr_cnt); + /*By updating remaining fr and width, we ensure f == col_fr_cnt + *in the last loop iteration. That means the last iteration will + *not have rounding errors and use all remaining space.*/ + col_fr_cnt -= f; + free_w -= c->w[i]; } } - /*To avoid rounding errors set the last FR track to the remaining size */ - if(last_fr_i >= 0) { - c->w[last_fr_i] = free_w - ((free_w * (col_fr_cnt - last_fr_x)) / col_fr_cnt); - } - if(subgrid) { lv_free((void *)col_templ); } } -static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c) +static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c) { const int32_t * row_templ; row_templ = get_row_dsc(cont); @@ -430,23 +436,19 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c) int32_t free_h = cont_h - grid_h; if(free_h < 0) free_h = 0; - int32_t last_fr_i = -1; - int32_t last_fr_x = 0; - for(i = 0; i < c->row_num; i++) { + for(i = 0; i < c->row_num && row_fr_cnt; i++) { int32_t x = row_templ[i]; if(IS_FR(x)) { int32_t f = GET_FR(x); - c->h[i] = (free_h * f) / row_fr_cnt; - last_fr_i = i; - last_fr_x = f; + c->h[i] = div_round_closest(free_h * f, row_fr_cnt); + /*By updating remaining fr and height, we ensure f == row_fr_cnt + *in the last loop iteration. That means the last iteration will + *not have rounding errors and use all remaining space.*/ + row_fr_cnt -= f; + free_h -= c->h[i]; } } - /*To avoid rounding errors set the last FR track to the remaining size */ - if(last_fr_i >= 0) { - c->h[last_fr_i] = free_h - ((free_h * (row_fr_cnt - last_fr_x)) / row_fr_cnt); - } - if(subgrid) { lv_free((void *)row_templ); } @@ -459,7 +461,7 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c) * @param child_id_ext helper value if the ID of the child is know (order from the oldest) else -1 * @param grid_abs helper value, the absolute position of the grid, NULL if unknown */ -static void item_repos(lv_obj_t * item, _lv_grid_calc_t * c, item_repos_hint_t * hint) +static void item_repos(lv_obj_t * item, lv_grid_calc_t * c, item_repos_hint_t * hint) { if(lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) return; uint32_t col_span = get_col_span(item); diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.h b/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.h index 3c64177e4..a7bf73822 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.h +++ b/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.h @@ -80,10 +80,7 @@ void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_align_t column_align, int32_t /** * Just a wrapper to `LV_GRID_FR` for bindings. */ -static inline int32_t lv_grid_fr(uint8_t x) -{ - return LV_GRID_FR(x); -} +int32_t lv_grid_fr(uint8_t x); /********************** * GLOBAL VARIABLES diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.c b/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.c index a14c1219f..ddb3b0e5a 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.c +++ b/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_layout.h" +#include "lv_layout_private.h" #include "../core/lv_global.h" #include "../core/lv_obj.h" @@ -36,7 +36,7 @@ * GLOBAL FUNCTIONS **********************/ -void _lv_layout_init(void) +void lv_layout_init(void) { /*Malloc a list for the built in layouts*/ layout_list_def = lv_malloc(layout_cnt * sizeof(lv_layout_dsc_t)); @@ -50,7 +50,7 @@ void _lv_layout_init(void) #endif } -void _lv_layout_deinit(void) +void lv_layout_deinit(void) { lv_free(layout_list_def); } @@ -65,7 +65,7 @@ uint32_t lv_layout_register(lv_layout_update_cb_t cb, void * user_data) return layout_cnt++; } -void _lv_layout_apply(lv_obj_t * obj) +void lv_layout_apply(lv_obj_t * obj) { lv_layout_t layout_id = lv_obj_get_style_layout(obj, LV_PART_MAIN); if(layout_id > 0 && layout_id <= layout_cnt) { diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.h b/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.h index f8258b598..a783d2b28 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.h +++ b/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout.h @@ -1,10 +1,10 @@ /** - * @file lv_layouts.h + * @file lv_layout.h * */ -#ifndef LV_LAYOUTS_H -#define LV_LAYOUTS_H +#ifndef LV_LAYOUT_H +#define LV_LAYOUT_H #ifdef __cplusplus extern "C" { @@ -25,10 +25,6 @@ extern "C" { **********************/ typedef void (*lv_layout_update_cb_t)(lv_obj_t *, void * user_data); -typedef struct { - lv_layout_update_cb_t cb; - void * user_data; -} lv_layout_dsc_t; typedef enum { LV_LAYOUT_NONE = 0, @@ -41,17 +37,9 @@ typedef enum { LV_LAYOUT_GRID, #endif - _LV_LAYOUT_LAST + LV_LAYOUT_LAST } lv_layout_t; -/********************** - * GLOBAL PROTOTYPES - **********************/ - -void _lv_layout_init(void); - -void _lv_layout_deinit(void); - /** * Register a new layout * @param cb the layout update callback @@ -60,12 +48,6 @@ void _lv_layout_deinit(void); */ uint32_t lv_layout_register(lv_layout_update_cb_t cb, void * user_data); -/** - * Update the layout of a widget - * @param obj pointer to a widget - */ -void _lv_layout_apply(lv_obj_t * obj); - /********************** * MACROS **********************/ @@ -82,4 +64,4 @@ void _lv_layout_apply(lv_obj_t * obj); } /*extern "C"*/ #endif -#endif /*LV_LAYOUTS_H*/ +#endif /*LV_LAYOUT_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout_private.h b/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout_private.h new file mode 100644 index 000000000..dace2fccb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/layouts/lv_layout_private.h @@ -0,0 +1,58 @@ +/** + * @file lv_layout_private.h + * + */ + +#ifndef LV_LAYOUT_PRIVATE_H +#define LV_LAYOUT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_layout.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_layout_update_cb_t cb; + void * user_data; +} lv_layout_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_layout_init(void); + +void lv_layout_deinit(void); + +/** + * Update the layout of a widget + * @param obj pointer to a widget + */ +void lv_layout_apply(lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LAYOUT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.c b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.c index 16eebcdd6..56885330b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_barcode.h" +#include "../../core/lv_obj_class_private.h" +#include "lv_barcode_private.h" #include "../../lvgl.h" #if LV_USE_BARCODE @@ -28,6 +29,7 @@ static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static bool lv_barcode_change_buf_size(lv_obj_t * obj, int32_t w, int32_t h); +static void lv_barcode_clear(lv_obj_t * obj); /********************** * STATIC VARIABLES @@ -94,16 +96,23 @@ void lv_barcode_set_direction(lv_obj_t * obj, lv_dir_t direction) barcode->direction = direction; } +void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_barcode_t * barcode = (lv_barcode_t *)obj; + barcode->tiled = tiled; + lv_image_set_inner_align(obj, tiled ? LV_IMAGE_ALIGN_TILE : LV_IMAGE_ALIGN_DEFAULT); +} + lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(data); - lv_result_t res = LV_RESULT_INVALID; - lv_barcode_t * barcode = (lv_barcode_t *)obj; - if(data == NULL || lv_strlen(data) == 0) { LV_LOG_WARN("data is empty"); + lv_barcode_clear(obj); return LV_RESULT_INVALID; } @@ -114,43 +123,92 @@ lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data) LV_ASSERT_MALLOC(out_buf); if(!out_buf) { LV_LOG_ERROR("malloc failed for out_buf"); + lv_barcode_clear(obj); return LV_RESULT_INVALID; } int32_t barcode_w = (int32_t) code128_encode_gs1(data, out_buf, len); - LV_LOG_INFO("barcode width = %d", (int)barcode_w); + LV_LOG_INFO("barcode width = %" LV_PRId32, barcode_w); + lv_barcode_t * barcode = (lv_barcode_t *)obj; LV_ASSERT(barcode->scale > 0); uint16_t scale = barcode->scale; - int32_t buf_w = (barcode->direction == LV_DIR_HOR) ? barcode_w * scale : 1; - int32_t buf_h = (barcode->direction == LV_DIR_VER) ? barcode_w * scale : 1; + int32_t buf_w; + int32_t buf_h; - if(!lv_barcode_change_buf_size(obj, buf_w, buf_h)) { - goto failed; + if(barcode->tiled) { + buf_w = (barcode->direction == LV_DIR_HOR) ? barcode_w * scale : 1; + buf_h = (barcode->direction == LV_DIR_VER) ? barcode_w * scale : 1; + } + else { + lv_obj_update_layout(obj); + buf_w = (barcode->direction == LV_DIR_HOR) ? barcode_w * scale : lv_obj_get_width(obj); + buf_h = (barcode->direction == LV_DIR_VER) ? barcode_w * scale : lv_obj_get_height(obj); } - lv_canvas_set_palette(obj, 0, lv_color_to_32(barcode->dark_color, 0xff)); - lv_canvas_set_palette(obj, 1, lv_color_to_32(barcode->light_color, 0xff)); + if(!lv_barcode_change_buf_size(obj, buf_w, buf_h)) { + lv_barcode_clear(obj); + lv_free(out_buf); + return LV_RESULT_INVALID; + } + + /* Temporarily disable invalidation to improve the efficiency of lv_canvas_set_px */ + lv_display_enable_invalidation(lv_obj_get_display(obj), false); + + lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj); + uint32_t stride = draw_buf->header.stride; + const lv_color_t color = lv_color_hex(1); + + /* Clear the canvas */ + lv_draw_buf_clear(draw_buf, NULL); + + /* Set the palette */ + lv_canvas_set_palette(obj, 0, lv_color_to_32(barcode->light_color, LV_OPA_COVER)); + lv_canvas_set_palette(obj, 1, lv_color_to_32(barcode->dark_color, LV_OPA_COVER)); for(int32_t x = 0; x < barcode_w; x++) { - lv_color_t color; - color = lv_color_hex(out_buf[x] ? 0 : 1); + /*skip empty data*/ + if(out_buf[x] == 0) { + continue; + } + for(uint16_t i = 0; i < scale; i++) { + int32_t offset = x * scale + i; if(barcode->direction == LV_DIR_HOR) { - lv_canvas_set_px(obj, x * scale + i, 0, color, LV_OPA_COVER); + lv_canvas_set_px(obj, offset, 0, color, LV_OPA_COVER); } - else { - lv_canvas_set_px(obj, 0, x * scale + i, color, LV_OPA_COVER); + else { /*LV_DIR_VER*/ + if(barcode->tiled) { + lv_canvas_set_px(obj, 0, offset, color, LV_OPA_COVER); + } + else { + uint8_t * dest = lv_draw_buf_goto_xy(draw_buf, 0, offset); + lv_memset(dest, 0xFF, stride); + } } } } - res = LV_RESULT_OK; + /* Copy pixels by row */ + if(!barcode->tiled && barcode->direction == LV_DIR_HOR && buf_h > 1) { + /* Skip the first row */ + int32_t h = buf_h - 1; + const uint8_t * src = lv_draw_buf_goto_xy(draw_buf, 0, 0); + uint8_t * dest = lv_draw_buf_goto_xy(draw_buf, 0, 1); + while(h--) { + lv_memcpy(dest, src, stride); + dest += stride; + } + } + + /* invalidate the canvas to refresh it */ + lv_display_enable_invalidation(lv_obj_get_display(obj), true); + lv_obj_invalidate(obj); -failed: lv_free(out_buf); - return res; + + return LV_RESULT_OK; } lv_color_t lv_barcode_get_dark_color(lv_obj_t * obj) @@ -190,7 +248,7 @@ static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob barcode->light_color = lv_color_white(); barcode->scale = 1; barcode->direction = LV_DIR_HOR; - lv_image_set_inner_align(obj, LV_IMAGE_ALIGN_TILE); + lv_image_set_inner_align(obj, LV_IMAGE_ALIGN_DEFAULT); } static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) @@ -208,7 +266,10 @@ static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj static bool lv_barcode_change_buf_size(lv_obj_t * obj, int32_t w, int32_t h) { LV_ASSERT_NULL(obj); - LV_ASSERT(w > 0); + if(w <= 0 || h <= 0) { + LV_LOG_WARN("invalid size: %" LV_PRId32 " x %" LV_PRId32, w, h); + return false; + } lv_draw_buf_t * old_buf = lv_canvas_get_draw_buf(obj); lv_draw_buf_t * new_buf = lv_draw_buf_create(w, h, LV_COLOR_FORMAT_I1, LV_STRIDE_AUTO); @@ -218,10 +279,22 @@ static bool lv_barcode_change_buf_size(lv_obj_t * obj, int32_t w, int32_t h) } lv_canvas_set_draw_buf(obj, new_buf); - LV_LOG_INFO("set canvas buffer: %p, width = %d", (void *)new_buf, (int)w); + LV_LOG_INFO("set canvas buffer: %p, width = %" LV_PRId32, (void *)new_buf, w); if(old_buf != NULL) lv_draw_buf_destroy(old_buf); return true; } +static void lv_barcode_clear(lv_obj_t * obj) +{ + lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj); + if(!draw_buf) { + return; + } + + lv_draw_buf_clear(draw_buf, NULL); + lv_image_cache_drop(draw_buf); + lv_obj_invalidate(obj); +} + #endif /*LV_USE_BARCODE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.h b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.h index 4f7b446b9..c9c0ce657 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.h @@ -1,5 +1,5 @@ /** - * @file lv_barcode.c + * @file lv_barcode.h * */ @@ -28,15 +28,6 @@ extern "C" { * TYPEDEFS **********************/ -/*Data of barcode*/ -typedef struct { - lv_canvas_t canvas; - lv_color_t dark_color; - lv_color_t light_color; - uint16_t scale; - lv_dir_t direction; -} lv_barcode_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_barcode_class; /********************** @@ -78,6 +69,13 @@ void lv_barcode_set_scale(lv_obj_t * obj, uint16_t scale); */ void lv_barcode_set_direction(lv_obj_t * obj, lv_dir_t direction); +/** + * Set the tiled mode of a barcode object + * @param obj pointer to barcode object + * @param tiled true: tiled mode, false: normal mode (default) + */ +void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled); + /** * Set the data of a barcode object * @param obj pointer to barcode object diff --git a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode_private.h b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode_private.h new file mode 100644 index 000000000..e6d18198f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_barcode_private.h + * + */ + +#ifndef LV_BARCODE_PRIVATE_H +#define LV_BARCODE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../widgets/canvas/lv_canvas_private.h" +#include "lv_barcode.h" + +#if LV_USE_BARCODE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of barcode*/ +struct lv_barcode_t { + lv_canvas_t canvas; + lv_color_t dark_color; + lv_color_t light_color; + uint16_t scale; + lv_dir_t direction; + bool tiled; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BARCODE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BARCODE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.c b/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.c index b6a44c89a..45edd65eb 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.c @@ -6,12 +6,14 @@ /********************* * INCLUDES *********************/ +#include "../../draw/lv_image_decoder_private.h" #include "lv_bin_decoder.h" #include "../../draw/lv_draw_image.h" #include "../../draw/lv_draw_buf.h" #include "../../stdlib/lv_string.h" #include "../../stdlib/lv_sprintf.h" #include "../../libs/rle/lv_rle.h" +#include "../../core/lv_global.h" #if LV_USE_LZ4_EXTERNAL #include @@ -25,6 +27,10 @@ * DEFINES *********************/ +#define DECODER_NAME "BIN" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -33,7 +39,7 @@ * Data format for compressed image data. */ -typedef struct _lv_image_compressed_t { +typedef struct lv_image_compressed_t { uint32_t method: 4; /*Compression method, see `lv_image_compress_t`*/ uint32_t reserved : 28; /*Reserved to be used later*/ uint32_t compressed_size; /*Compressed data size in byte*/ @@ -101,14 +107,17 @@ void lv_bin_decoder_init(void) lv_image_decoder_set_open_cb(decoder, lv_bin_decoder_open); lv_image_decoder_set_get_area_cb(decoder, lv_bin_decoder_get_area); lv_image_decoder_set_close_cb(decoder, lv_bin_decoder_close); - lv_image_decoder_set_cache_free_cb(decoder, NULL); /*Use general cache free method*/ + + decoder->name = DECODER_NAME; } -lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { LV_UNUSED(decoder); /*Unused*/ - lv_image_src_t src_type = lv_image_src_get_type(src); + const void * src = dsc->src; + lv_image_src_t src_type = dsc->src_type; + if(src_type == LV_IMAGE_SRC_VARIABLE) { lv_image_dsc_t * image = (lv_image_dsc_t *)src; lv_memcpy(header, &image->header, sizeof(lv_image_header_t)); @@ -117,31 +126,28 @@ lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, const void * src, /*Support only "*.bin" files*/ if(lv_strcmp(lv_fs_get_ext(src), "bin")) return LV_RESULT_INVALID; - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, src, LV_FS_MODE_RD); - if(res == LV_FS_RES_OK) { - uint32_t rn; - res = lv_fs_read(&f, header, sizeof(lv_image_header_t), &rn); - lv_fs_close(&f); - if(res != LV_FS_RES_OK || rn != sizeof(lv_image_header_t)) { - LV_LOG_WARN("Read file header failed: %d", res); - return LV_RESULT_INVALID; - } + lv_fs_res_t res; + uint32_t rn; + res = lv_fs_read(&dsc->file, header, sizeof(lv_image_header_t), &rn); - /** - * @todo - * This is a temp backward compatibility solution after adding - * magic in image header. - */ - if(header->magic != LV_IMAGE_HEADER_MAGIC) { - LV_LOG_WARN("Legacy bin image detected: %s", (char *)src); - header->cf = header->magic; - header->magic = LV_IMAGE_HEADER_MAGIC; - } - - /*File is always read to buf, thus data can be modified.*/ - header->flags |= LV_IMAGE_FLAGS_MODIFIABLE; + if(res != LV_FS_RES_OK || rn != sizeof(lv_image_header_t)) { + LV_LOG_WARN("Read file header failed: %d", res); + return LV_RESULT_INVALID; } + + /** + * @todo + * This is a temp backward compatibility solution after adding + * magic in image header. + */ + if(header->magic != LV_IMAGE_HEADER_MAGIC) { + LV_LOG_WARN("Legacy bin image detected: %s", (char *)src); + header->cf = header->magic; + header->magic = LV_IMAGE_HEADER_MAGIC; + } + + /*File is always read to buf, thus data can be modified.*/ + header->flags |= LV_IMAGE_FLAGS_MODIFIABLE; } else if(src_type == LV_IMAGE_SRC_SYMBOL) { /*The size depend on the font but it is unknown here. It should be handled outside of the @@ -175,7 +181,8 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d { LV_UNUSED(decoder); - lv_fs_res_t res = LV_RESULT_INVALID; + lv_result_t res = LV_RESULT_INVALID; + lv_fs_res_t fs_res = LV_FS_RES_UNKNOWN; bool use_directly = false; /*If the image is already decoded and can be used directly*/ /*Open the file if it's a file*/ @@ -196,9 +203,9 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d return LV_RESULT_INVALID; } - res = lv_fs_open(f, dsc->src, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) { - LV_LOG_WARN("Open file failed: %d", res); + fs_res = lv_fs_open(f, dsc->src, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Open file failed: %d", fs_res); lv_free(f); free_decoder_data(dsc); return LV_RESULT_INVALID; @@ -287,7 +294,14 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d } else { decoded = &decoder_data->c_array; - lv_draw_buf_from_image(decoded, image); + if(image->header.stride == 0) { + /*If image doesn't have stride, treat it as lvgl v8 legacy image format*/ + lv_image_dsc_t tmp = *image; + tmp.header.stride = (tmp.header.w * lv_color_format_get_bpp(cf) + 7) >> 3; + lv_draw_buf_from_image(decoded, &tmp); + } + else + lv_draw_buf_from_image(decoded, image); } dsc->decoded = decoded; @@ -327,7 +341,8 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(use_directly || dsc->args.no_cache) return LV_RESULT_OK; /*Do not put image to cache if it can be used directly.*/ -#if LV_CACHE_DEF_SIZE > 0 + /*If the image cache is disabled, just return the decoded image*/ + if(!lv_image_cache_is_enabled()) return LV_RESULT_OK; /*Add it to cache*/ lv_image_cache_data_t search_key; @@ -343,7 +358,6 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d dsc->cache_entry = cache_entry; decoder_data_t * decoder_data = get_decoder_data(dsc); decoder_data->decoded = NULL; /*Cache will take care of it*/ -#endif return LV_RESULT_OK; } @@ -359,12 +373,6 @@ void lv_bin_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * } free_decoder_data(dsc); - - if(dsc->cache_entry) { - /*Decoded data is in cache, release it from cache's callback*/ - lv_cache_release(dsc->cache, dsc->cache_entry, NULL); - } - } lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, @@ -387,7 +395,7 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod return LV_RESULT_INVALID; } - lv_result_t res = LV_RESULT_INVALID; + lv_fs_res_t res = LV_FS_RES_UNKNOWN; decoder_data_t * decoder_data = dsc->user_data; if(decoder_data == NULL) { LV_LOG_ERROR("Unexpected null decoder data"); @@ -404,28 +412,25 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod /*We only support read line by line for now*/ if(decoded_area->y1 == LV_COORD_MIN) { /*Indexed image is converted to ARGB888*/ - uint32_t len = LV_COLOR_FORMAT_IS_INDEXED(cf) ? sizeof(lv_color32_t) * 8 : bpp; lv_color_format_t cf_decoded = LV_COLOR_FORMAT_IS_INDEXED(cf) ? LV_COLOR_FORMAT_ARGB8888 : cf; - len = (len * w_px) / 8; - decoded = decoder_data->decoded_partial; - if(decoded && decoded->header.w == w_px) { - /*Use existing one directly*/ + decoded = lv_draw_buf_reshape(decoder_data->decoded_partial, cf_decoded, w_px, 1, LV_STRIDE_AUTO); + if(decoded == NULL) { + if(decoder_data->decoded_partial != NULL) { + lv_draw_buf_destroy(decoder_data->decoded_partial); + decoder_data->decoded_partial = NULL; + } + decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, w_px, 1, cf_decoded, LV_STRIDE_AUTO); + if(decoded == NULL) return LV_RESULT_INVALID; + decoder_data->decoded_partial = decoded; /*Free on decoder close*/ } - else { - decoded = lv_draw_buf_create(w_px, 1, cf_decoded, LV_STRIDE_AUTO); - if(decoded == NULL) - return LV_RESULT_INVALID; - } - *decoded_area = *full_area; decoded_area->y2 = decoded_area->y1; - decoder_data->decoded_partial = decoded; /*Free on decoder close*/ } else { decoded_area->y1++; decoded_area->y2++; - decoded = decoder_data->decoded_partial; /*Already alloced*/ + decoded = decoder_data->decoded_partial; /*Already allocated*/ } img_data = decoded->data; /*Get the buffer to operate on*/ @@ -549,7 +554,7 @@ static void free_decoder_data(lv_image_decoder_dsc_t * dsc) static lv_result_t decode_indexed(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); /*Unused*/ - lv_result_t res; + lv_fs_res_t res; uint32_t rn; decoder_data_t * decoder_data = dsc->user_data; lv_fs_file_t * f = decoder_data->f; @@ -585,7 +590,8 @@ static lv_result_t decode_indexed(lv_image_decoder_t * decoder, lv_image_decoder decoder_data->palette = (void *)palette; /*Need to free when decoder closes*/ #if LV_BIN_DECODER_RAM_LOAD - draw_buf_indexed = lv_draw_buf_create(dsc->header.w, dsc->header.h, cf, dsc->header.stride); + draw_buf_indexed = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, cf, + dsc->header.stride); if(draw_buf_indexed == NULL) { LV_LOG_ERROR("Draw buffer alloc failed"); goto exit_with_buf; @@ -623,8 +629,9 @@ static lv_result_t decode_indexed(lv_image_decoder_t * decoder, lv_image_decoder #if LV_BIN_DECODER_RAM_LOAD /*Convert to ARGB8888, since sw renderer cannot render it directly even it's in RAM*/ - lv_draw_buf_t * decoded = lv_draw_buf_create(dsc->header.w, dsc->header.h, LV_COLOR_FORMAT_ARGB8888, - 0); + lv_draw_buf_t * decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, + LV_COLOR_FORMAT_ARGB8888, + 0); if(decoded == NULL) { LV_LOG_ERROR("No memory for indexed image"); goto exit_with_buf; @@ -677,7 +684,7 @@ static lv_result_t load_indexed(lv_image_decoder_t * decoder, lv_image_decoder_d LV_UNUSED(decoder); /*Unused*/ - lv_result_t res; + lv_fs_res_t res; uint32_t rn; decoder_data_t * decoder_data = dsc->user_data; @@ -715,7 +722,8 @@ static lv_result_t load_indexed(lv_image_decoder_t * decoder, lv_image_decoder_d if(dsc->src_type == LV_IMAGE_SRC_FILE) { lv_color_format_t cf = dsc->header.cf; lv_fs_file_t * f = decoder_data->f; - lv_draw_buf_t * decoded = lv_draw_buf_create(dsc->header.w, dsc->header.h, cf, dsc->header.stride); + lv_draw_buf_t * decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, cf, + dsc->header.stride); if(decoded == NULL) { LV_LOG_ERROR("Draw buffer alloc failed"); return LV_RESULT_INVALID; @@ -762,7 +770,7 @@ static lv_result_t load_indexed(lv_image_decoder_t * decoder, lv_image_decoder_d static lv_result_t decode_rgb(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); - lv_result_t res; + lv_fs_res_t res; decoder_data_t * decoder_data = dsc->user_data; lv_fs_file_t * f = decoder_data->f; lv_color_format_t cf = dsc->header.cf; @@ -772,7 +780,8 @@ static lv_result_t decode_rgb(lv_image_decoder_t * decoder, lv_image_decoder_dsc len += (dsc->header.stride / 2) * dsc->header.h; /*A8 mask*/ } - lv_draw_buf_t * decoded = lv_draw_buf_create(dsc->header.w, dsc->header.h, cf, dsc->header.stride); + lv_draw_buf_t * decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, cf, + dsc->header.stride); if(decoded == NULL) { LV_LOG_ERROR("No memory for rgb file read"); return LV_RESULT_INVALID; @@ -814,7 +823,7 @@ static inline uint8_t bit_extend(uint8_t value, uint8_t bpp) static lv_result_t decode_alpha_only(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); - lv_result_t res; + lv_fs_res_t res; uint32_t rn; decoder_data_t * decoder_data = dsc->user_data; uint8_t bpp = lv_color_format_get_bpp(dsc->header.cf); @@ -824,7 +833,8 @@ static lv_result_t decode_alpha_only(lv_image_decoder_t * decoder, lv_image_deco lv_draw_buf_t * decoded; uint32_t file_len = (uint32_t)dsc->header.stride * dsc->header.h; - decoded = lv_draw_buf_create(dsc->header.w, dsc->header.h, LV_COLOR_FORMAT_A8, buf_stride); + decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, LV_COLOR_FORMAT_A8, + buf_stride); if(decoded == NULL) { LV_LOG_ERROR("Out of memory"); return LV_RESULT_INVALID; @@ -889,6 +899,7 @@ static lv_result_t decode_compressed(lv_image_decoder_t * decoder, lv_image_deco uint32_t compressed_len; decoder_data_t * decoder_data = get_decoder_data(dsc); lv_result_t res; + lv_fs_res_t fs_res; uint8_t * file_buf = NULL; lv_image_compressed_t * compressed = &decoder_data->compressed; @@ -908,9 +919,9 @@ static lv_result_t decode_compressed(lv_image_decoder_t * decoder, lv_image_deco /*Read compress header*/ len = 12; - res = fs_read_file_at(f, sizeof(lv_image_header_t), compressed, len, &rn); - if(res != LV_FS_RES_OK || rn != len) { - LV_LOG_WARN("Read compressed header failed: %d", res); + fs_res = fs_read_file_at(f, sizeof(lv_image_header_t), compressed, len, &rn); + if(fs_res != LV_FS_RES_OK || rn != len) { + LV_LOG_WARN("Read compressed header failed: %d", fs_res); return LV_RESULT_INVALID; } @@ -927,9 +938,9 @@ static lv_result_t decode_compressed(lv_image_decoder_t * decoder, lv_image_deco } /*Continue to read the compressed data following compression header*/ - res = lv_fs_read(f, file_buf, compressed_len, &rn); - if(res != LV_FS_RES_OK || rn != compressed_len) { - LV_LOG_WARN("Read compressed file failed: %d", res); + fs_res = lv_fs_read(f, file_buf, compressed_len, &rn); + if(fs_res != LV_FS_RES_OK || rn != compressed_len) { + LV_LOG_WARN("Read compressed file failed: %d", fs_res); lv_free(file_buf); return LV_RESULT_INVALID; } @@ -1078,13 +1089,20 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image LV_UNUSED(input_len); LV_UNUSED(out_len); - lv_draw_buf_t * decompressed = lv_draw_buf_create(dsc->header.w, dsc->header.h, dsc->header.cf, - dsc->header.stride); + lv_draw_buf_t * decompressed = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, + dsc->header.cf, + dsc->header.stride); if(decompressed == NULL) { LV_LOG_WARN("No memory for decompressed image, input: %" LV_PRIu32 ", output: %" LV_PRIu32, input_len, out_len); return LV_RESULT_INVALID; } + if(out_len > decompressed->data_size) { + LV_LOG_ERROR("Decompressed size mismatch: %" LV_PRIu32 " > %" LV_PRIu32, out_len, decompressed->data_size); + lv_draw_buf_destroy(decompressed); + return LV_RESULT_INVALID; + } + img_data = decompressed->data; if(compressed->method == LV_IMAGE_COMPRESS_RLE) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.h b/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.h index 2966dac39..d441230d0 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/bin_decoder/lv_bin_decoder.h @@ -35,11 +35,11 @@ void lv_bin_decoder_init(void); /** * Get info about a lvgl binary image * @param decoder the decoder where this function belongs - * @param src the image source: pointer to an `lv_image_dsc_t` variable, a file path or a symbol + * @param dsc image descriptor containing the source and type of the image and other info. * @param header store the image data here * @return LV_RESULT_OK: the info is successfully stored in `header`; LV_RESULT_INVALID: unknown format or other error. */ -lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, const lv_area_t * full_area, lv_area_t * decoded_area); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/bmp/lv_bmp.c b/lib/libesp32_lvgl/lvgl/src/libs/bmp/lv_bmp.c index c36f2cc12..aeb9dad29 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/bmp/lv_bmp.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/bmp/lv_bmp.c @@ -6,15 +6,21 @@ /********************* * INCLUDES *********************/ +#include "../../draw/lv_image_decoder_private.h" #include "../../../lvgl.h" #if LV_USE_BMP #include +#include "../../core/lv_global.h" /********************* * DEFINES *********************/ +#define DECODER_NAME "BMP" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -31,7 +37,7 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * src, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, @@ -57,6 +63,8 @@ void lv_bmp_init(void) lv_image_decoder_set_open_cb(dec, decoder_open); lv_image_decoder_set_get_area_cb(dec, decoder_get_area); lv_image_decoder_set_close_cb(dec, decoder_close); + + dec->name = DECODER_NAME; } void lv_bmp_deinit(void) @@ -76,34 +84,31 @@ void lv_bmp_deinit(void) /** * Get info about a BMP image - * @param src can be file name or pointer to a C array + * @param dsc image descriptor containing the source and type of the image and other info. * @param header store the info here * @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info */ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { LV_UNUSED(decoder); - lv_image_src_t src_type = lv_image_src_get_type(src); /*Get the source type*/ + const void * src = dsc->src; + lv_image_src_t src_type = dsc->src_type; /*Get the source type*/ /*If it's a BMP file...*/ if(src_type == LV_IMAGE_SRC_FILE) { const char * fn = src; if(lv_strcmp(lv_fs_get_ext(fn), "bmp") == 0) { /*Check the extension*/ /*Save the data in the header*/ - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, src, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) return LV_RESULT_INVALID; uint8_t headers[54]; - lv_fs_read(&f, headers, 54, NULL); + lv_fs_read(&dsc->file, headers, 54, NULL); uint32_t w; uint32_t h; lv_memcpy(&w, headers + 18, 4); lv_memcpy(&h, headers + 22, 4); header->w = w; header->h = h; - lv_fs_close(&f); uint16_t bpp; lv_memcpy(&bpp, headers + 28, 2); @@ -155,7 +160,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d lv_memset(&b, 0x00, sizeof(b)); lv_fs_res_t res = lv_fs_open(&b.f, dsc->src, LV_FS_MODE_RD); - if(res == LV_RESULT_OK) return LV_RESULT_INVALID; + if(res != LV_FS_RES_OK) return LV_RESULT_INVALID; uint8_t header[54]; lv_fs_read(&b.f, header, 54, NULL); @@ -196,7 +201,20 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod if(decoded_area->y1 == LV_COORD_MIN) { *decoded_area = *full_area; decoded_area->y2 = decoded_area->y1; - if(decoded == NULL) decoded = lv_draw_buf_create(lv_area_get_width(full_area), 1, dsc->header.cf, LV_STRIDE_AUTO); + int32_t w_px = lv_area_get_width(full_area); + lv_draw_buf_t * reshaped = lv_draw_buf_reshape(decoded, dsc->header.cf, w_px, 1, LV_STRIDE_AUTO); + if(reshaped == NULL) { + if(decoded != NULL) { + lv_draw_buf_destroy(decoded); + decoded = NULL; + dsc->decoded = NULL; + } + decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, w_px, 1, dsc->header.cf, LV_STRIDE_AUTO); + if(decoded == NULL) return LV_RESULT_INVALID; + } + else { + decoded = reshaped; + } dsc->decoded = decoded; } else { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.c b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.c index 29d674938..8290944a5 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.c @@ -6,8 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_ffmpeg.h" +#include "lv_ffmpeg_private.h" #if LV_USE_FFMPEG != 0 +#include "../../draw/lv_image_decoder_private.h" +#include "../../core/lv_obj_class_private.h" #include #include @@ -19,6 +21,9 @@ /********************* * DEFINES *********************/ + +#define DECODER_NAME "FFMPEG" + #if LV_COLOR_DEPTH == 8 #define AV_PIX_FMT_TRUE_COLOR AV_PIX_FMT_RGB8 #elif LV_COLOR_DEPTH == 16 @@ -66,7 +71,7 @@ struct lv_image_pixel_color_s { * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * src, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static void decoder_close(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc); @@ -113,6 +118,8 @@ void lv_ffmpeg_init(void) lv_image_decoder_set_open_cb(dec, decoder_open); lv_image_decoder_set_close_cb(dec, decoder_close); + dec->name = DECODER_NAME; + #if LV_FFMPEG_AV_DUMP_FORMAT == 0 av_log_set_level(AV_LOG_QUIET); #endif @@ -248,12 +255,13 @@ void lv_ffmpeg_player_set_auto_restart(lv_obj_t * obj, bool en) * STATIC FUNCTIONS **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { LV_UNUSED(decoder); /* Get the source type */ - lv_image_src_t src_type = lv_image_src_get_type(src); + const void * src = dsc->src; + lv_image_src_t src_type = dsc->src_type; if(src_type == LV_IMAGE_SRC_FILE) { const char * fn = src; @@ -798,7 +806,7 @@ static void ffmpeg_close(struct ffmpeg_context_s * ffmpeg_ctx) static void lv_ffmpeg_player_frame_update_cb(lv_timer_t * timer) { - lv_obj_t * obj = (lv_obj_t *)timer->user_data; + lv_obj_t * obj = (lv_obj_t *)lv_timer_get_user_data(timer); lv_ffmpeg_player_t * player = (lv_ffmpeg_player_t *)obj; if(!player->ffmpeg_ctx) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.h b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.h index 51203e543..1cb86b9d4 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.h @@ -13,8 +13,8 @@ extern "C" { * INCLUDES *********************/ #include "../../lv_conf_internal.h" -#include "../../widgets/image/lv_image.h" #if LV_USE_FFMPEG != 0 +#include "../../misc/lv_types.h" /********************* * DEFINES @@ -27,20 +27,12 @@ struct ffmpeg_context_s; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_ffmpeg_player_class; -typedef struct { - lv_image_t img; - lv_timer_t * timer; - lv_image_dsc_t imgdsc; - bool auto_restart; - struct ffmpeg_context_s * ffmpeg_ctx; -} lv_ffmpeg_player_t; - typedef enum { LV_FFMPEG_PLAYER_CMD_START, LV_FFMPEG_PLAYER_CMD_STOP, LV_FFMPEG_PLAYER_CMD_PAUSE, LV_FFMPEG_PLAYER_CMD_RESUME, - _LV_FFMPEG_PLAYER_CMD_LAST + LV_FFMPEG_PLAYER_CMD_LAST } lv_ffmpeg_player_cmd_t; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h new file mode 100644 index 000000000..b27b6bf02 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h @@ -0,0 +1,51 @@ +/** + * @file lv_ffmpeg_private.h + * + */ + +#ifndef LV_FFMPEG_PRIVATE_H +#define LV_FFMPEG_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_ffmpeg.h" +#if LV_USE_FFMPEG != 0 +#include "../../widgets/image/lv_image_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_ffmpeg_player_t { + lv_image_t img; + lv_timer_t * timer; + lv_image_dsc_t imgdsc; + bool auto_restart; + struct ffmpeg_context_s * ffmpeg_ctx; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FFMPEG*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FFMPEG_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.c b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.c index 93729199b..b1da8f13e 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_freetype.h" +#include "../../misc/lv_fs_private.h" +#include "lv_freetype_private.h" #if LV_USE_FREETYPE @@ -88,7 +89,7 @@ lv_result_t lv_freetype_init(uint32_t max_glyph_cnt) return LV_RESULT_INVALID; } - _lv_ll_init(&ctx->face_id_ll, sizeof(face_id_node_t)); + lv_ll_init(&ctx->face_id_ll, sizeof(face_id_node_t)); lv_cache_ops_t ops = { .compare_cb = (lv_cache_compare_cb_t)cache_node_cache_compare_cb, @@ -96,6 +97,7 @@ lv_result_t lv_freetype_init(uint32_t max_glyph_cnt) .free_cb = (lv_cache_free_cb_t)cache_node_cache_free_cb, }; ctx->cache_node_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(lv_freetype_cache_node_t), INT32_MAX, ops); + lv_cache_set_name(ctx->cache_node_cache, "FREETYPE_CACHE_NODE"); return LV_RESULT_OK; } @@ -180,7 +182,6 @@ void lv_freetype_font_delete(lv_font_t * font) LV_ASSERT_NULL(font); lv_freetype_context_t * ctx = lv_freetype_get_context(); lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)(font->dsc); - LV_ASSERT_NULL(dsc); LV_ASSERT_FREETYPE_FONT_DSC(dsc); lv_cache_release(ctx->cache_node_cache, dsc->cache_node_entry, NULL); @@ -289,7 +290,7 @@ static FTC_FaceID lv_freetype_req_face_id(lv_freetype_context_t * ctx, const cha face_id_node_t * node; /* search cache */ - _LV_LL_READ(ll_p, node) { + LV_LL_READ(ll_p, node) { if(strcmp(node->pathname, pathname) == 0) { node->ref_cnt++; LV_LOG_INFO("reuse face_id: %s, ref_cnt = %d", node->pathname, node->ref_cnt); @@ -298,7 +299,7 @@ static FTC_FaceID lv_freetype_req_face_id(lv_freetype_context_t * ctx, const cha } /* insert new cache */ - node = _lv_ll_ins_tail(ll_p); + node = lv_ll_ins_tail(ll_p); LV_ASSERT_MALLOC(node); #if LV_USE_FS_MEMFS @@ -327,13 +328,13 @@ static void lv_freetype_drop_face_id(lv_freetype_context_t * ctx, FTC_FaceID fac { lv_ll_t * ll_p = &ctx->face_id_ll; face_id_node_t * node; - _LV_LL_READ(ll_p, node) { + LV_LL_READ(ll_p, node) { if(face_id == node->pathname) { LV_LOG_INFO("found face_id: %s, ref_cnt = %d", node->pathname, node->ref_cnt); node->ref_cnt--; if(node->ref_cnt == 0) { LV_LOG_INFO("drop face_id: %s", node->pathname); - _lv_ll_remove(ll_p, node); + lv_ll_remove(ll_p, node); lv_free(node->pathname); lv_free(node); } @@ -368,12 +369,14 @@ static bool cache_node_cache_create_cb(lv_freetype_cache_node_t * node, void * u } node->face = face; + lv_mutex_init(&node->face_lock); return true; } static void cache_node_cache_free_cb(lv_freetype_cache_node_t * node, void * user_data) { FT_Done_Face(node->face); + lv_mutex_delete(&node->face_lock); if(node->glyph_cache) { lv_cache_destroy(node->glyph_cache, user_data); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.h b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.h index 7104e2f1b..76b9f7b56 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.h @@ -15,7 +15,7 @@ extern "C" { #include "../../lv_conf_internal.h" #include "../../misc/lv_types.h" #include "../../misc/lv_event.h" -#include +#include LV_STDBOOL_INCLUDE #if LV_USE_FREETYPE @@ -34,21 +34,18 @@ extern "C" { * TYPEDEFS **********************/ -enum { +typedef enum { LV_FREETYPE_FONT_STYLE_NORMAL = 0, LV_FREETYPE_FONT_STYLE_ITALIC = 1 << 0, LV_FREETYPE_FONT_STYLE_BOLD = 1 << 1, -}; +} lv_freetype_font_style_t; -typedef uint16_t lv_freetype_font_style_t; typedef lv_freetype_font_style_t LV_FT_FONT_STYLE; -enum { +typedef enum { LV_FREETYPE_FONT_RENDER_MODE_BITMAP = 0, LV_FREETYPE_FONT_RENDER_MODE_OUTLINE = 1, -}; - -typedef uint16_t lv_freetype_font_render_mode_t; +} lv_freetype_font_render_mode_t; typedef void * lv_freetype_outline_t; @@ -60,19 +57,6 @@ typedef enum { LV_FREETYPE_OUTLINE_CONIC_TO, } lv_freetype_outline_type_t; -typedef struct { - int32_t x; - int32_t y; -} lv_freetype_outline_vector_t; - -typedef struct { - lv_freetype_outline_t outline; - lv_freetype_outline_type_t type; - lv_freetype_outline_vector_t to; - lv_freetype_outline_vector_t control1; - lv_freetype_outline_vector_t control2; -} lv_freetype_outline_event_param_t; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_glyph.c b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_glyph.c index e0bbcd7e2..7ed217883 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_glyph.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_glyph.c @@ -16,10 +16,12 @@ * DEFINES *********************/ +#define CACHE_NAME "FREETYPE_GLYPH" + /********************** * TYPEDEFS **********************/ -typedef struct _lv_freetype_glyph_cache_data_t { +typedef struct lv_freetype_glyph_cache_data_t { uint32_t unicode; uint32_t size; @@ -59,6 +61,7 @@ lv_cache_t * lv_freetype_create_glyph_cache(uint32_t cache_size) lv_cache_t * glyph_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(lv_freetype_glyph_cache_data_t), cache_size, ops); + lv_cache_set_name(glyph_cache, CACHE_NAME); return glyph_cache; } @@ -129,13 +132,15 @@ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void lv_font_glyph_dsc_t * dsc_out = &data->glyph_dsc; + lv_mutex_lock(&dsc->cache_node->face_lock); FT_Face face = dsc->cache_node->face; FT_UInt glyph_index = FT_Get_Char_Index(face, data->unicode); FT_Set_Pixel_Sizes(face, 0, dsc->size); - error = FT_Load_Glyph(face, glyph_index, FT_LOAD_COMPUTE_METRICS | FT_LOAD_NO_BITMAP); + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_COMPUTE_METRICS | FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT); if(error) { FT_ERROR_MSG("FT_Load_Glyph", error); + lv_mutex_unlock(&dsc->cache_node->face_lock); return false; } @@ -170,7 +175,9 @@ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void } dsc_out->is_placeholder = glyph_index == 0; - dsc_out->glyph_index = glyph_index; + dsc_out->gid.index = (uint32_t)glyph_index; + + lv_mutex_unlock(&dsc->cache_node->face_lock); return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_image.c b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_image.c index 7a7b04d46..ab7dad292 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_image.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_image.c @@ -12,15 +12,21 @@ #if LV_USE_FREETYPE +#include "../../core/lv_global.h" + +#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers) + /********************* * DEFINES *********************/ +#define CACHE_NAME "FREETYPE_IMAGE" + /********************** * TYPEDEFS **********************/ -typedef struct _lv_freetype_image_cache_data_t { +typedef struct lv_freetype_image_cache_data_t { FT_UInt glyph_index; uint32_t size; @@ -30,9 +36,7 @@ typedef struct _lv_freetype_image_cache_data_t { /********************** * STATIC PROTOTYPES **********************/ -static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, - uint32_t unicode_letter, - lv_draw_buf_t * draw_buf); +static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void * user_data); static void freetype_image_free_cb(lv_freetype_image_cache_data_t * node, void * user_data); @@ -62,6 +66,7 @@ lv_cache_t * lv_freetype_create_draw_data_image(uint32_t cache_size) lv_cache_t * draw_data_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(lv_freetype_image_cache_data_t), cache_size, ops); + lv_cache_set_name(draw_data_cache, CACHE_NAME); return draw_data_cache; } @@ -77,18 +82,14 @@ void lv_freetype_set_cbs_image_font(lv_freetype_font_dsc_t * dsc) * STATIC FUNCTIONS **********************/ -static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, - uint32_t unicode_letter, - lv_draw_buf_t * draw_buf) +static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) { - LV_UNUSED(unicode_letter); LV_UNUSED(draw_buf); const lv_font_t * font = g_dsc->resolved_font; lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc; LV_ASSERT_FREETYPE_FONT_DSC(dsc); - FT_Face face = dsc->cache_node->face; - FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter); + FT_UInt glyph_index = (FT_UInt)g_dsc->gid.index; lv_cache_t * cache = dsc->cache_node->draw_data_cache; @@ -123,16 +124,20 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void FT_Error error; + lv_mutex_lock(&dsc->cache_node->face_lock); + FT_Face face = dsc->cache_node->face; FT_Set_Pixel_Sizes(face, 0, dsc->size); - error = FT_Load_Glyph(face, data->glyph_index, FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL); + error = FT_Load_Glyph(face, data->glyph_index, FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_AUTOHINT); if(error) { FT_ERROR_MSG("FT_Load_Glyph", error); + lv_mutex_unlock(&dsc->cache_node->face_lock); return false; } error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); if(error) { FT_ERROR_MSG("FT_Render_Glyph", error); + lv_mutex_unlock(&dsc->cache_node->face_lock); return false; } @@ -140,6 +145,7 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void error = FT_Get_Glyph(face->glyph, &glyph); if(error) { FT_ERROR_MSG("FT_Get_Glyph", error); + lv_mutex_unlock(&dsc->cache_node->face_lock); return false; } @@ -149,7 +155,7 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void uint16_t box_w = glyph_bitmap->bitmap.width; /*Width of the bitmap in [px]*/ uint32_t stride = lv_draw_buf_width_to_stride(box_w, LV_COLOR_FORMAT_A8); - data->draw_buf = lv_draw_buf_create(box_w, box_h, LV_COLOR_FORMAT_A8, stride); + data->draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, box_w, box_h, LV_COLOR_FORMAT_A8, stride); for(int y = 0; y < box_h; ++y) { lv_memcpy((uint8_t *)(data->draw_buf->data) + y * stride, glyph_bitmap->bitmap.buffer + y * box_w, @@ -158,6 +164,8 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void FT_Done_Glyph(glyph); + lv_mutex_unlock(&dsc->cache_node->face_lock); + return true; } static void freetype_image_free_cb(lv_freetype_image_cache_data_t * data, void * user_data) diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_outline.c b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_outline.c index 43c66cc18..77d40fef3 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_outline.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_outline.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ +#include "../../misc/lv_event_private.h" #include "../../lvgl.h" #include "lv_freetype_private.h" @@ -16,11 +17,13 @@ * DEFINES *********************/ +#define CACHE_NAME "FREETYPE_OUTLINE" + /********************** * TYPEDEFS **********************/ -typedef struct _lv_freetype_outline_node_t { +typedef struct lv_freetype_outline_node_t { FT_UInt glyph_index; lv_freetype_outline_t outline; } lv_freetype_outline_node_t; @@ -32,12 +35,10 @@ typedef struct _lv_freetype_outline_node_t { static lv_freetype_outline_t outline_create(lv_freetype_context_t * ctx, FT_Face face, FT_UInt glyph_index, uint32_t size, uint32_t strength); static lv_result_t outline_delete(lv_freetype_context_t * ctx, lv_freetype_outline_t outline); -static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, - uint32_t unicode_letter, - lv_draw_buf_t * draw_buf); +static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc); -static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, uint32_t unicode_letter); +static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, FT_UInt glyph_index); /*glyph dsc cache lru callbacks*/ static bool freetype_glyph_outline_create_cb(lv_freetype_outline_node_t * node, lv_freetype_font_dsc_t * dsc); @@ -68,6 +69,7 @@ lv_cache_t * lv_freetype_create_draw_data_outline(uint32_t cache_size) lv_cache_t * draw_data_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(lv_freetype_outline_node_t), cache_size, glyph_outline_cache_ops); + lv_cache_set_name(draw_data_cache, CACHE_NAME); return draw_data_cache; } @@ -119,11 +121,14 @@ bool lv_freetype_is_outline_font(const lv_font_t * font) static bool freetype_glyph_outline_create_cb(lv_freetype_outline_node_t * node, lv_freetype_font_dsc_t * dsc) { lv_freetype_outline_t outline; + + lv_mutex_lock(&dsc->cache_node->face_lock); outline = outline_create(dsc->context, dsc->cache_node->face, node->glyph_index, dsc->cache_node->ref_size, dsc->style & LV_FREETYPE_FONT_STYLE_BOLD ? 1 : 0); + lv_mutex_unlock(&dsc->cache_node->face_lock); if(!outline) { return false; @@ -153,15 +158,14 @@ static lv_cache_compare_res_t freetype_glyph_outline_cmp_cb(const lv_freetype_ou return node_a->glyph_index > node_b->glyph_index ? 1 : -1; } -static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, - uint32_t unicode_letter, - lv_draw_buf_t * draw_buf) +static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) { LV_UNUSED(draw_buf); + const lv_font_t * font = g_dsc->resolved_font; lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc; LV_ASSERT_FREETYPE_FONT_DSC(dsc); - lv_cache_entry_t * entry = lv_freetype_outline_lookup(dsc, unicode_letter); + lv_cache_entry_t * entry = lv_freetype_outline_lookup(dsc, (FT_UInt)g_dsc->gid.index); if(entry == NULL) { return NULL; } @@ -184,13 +188,10 @@ static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_ g_dsc->entry = NULL; } -static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, uint32_t unicode_letter) +static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, FT_UInt glyph_index) { lv_freetype_cache_node_t * cache_node = dsc->cache_node; - FT_Face face = cache_node->face; - FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter); - lv_freetype_outline_node_t tmp_node; tmp_node.glyph_index = glyph_index; @@ -302,8 +303,11 @@ static lv_freetype_outline_t outline_create( return NULL; } - /* Load glyph */ - error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP); + /** + * Disable AUTOHINT(https://freetype.org/autohinting/hinter.html) to avoid display clipping + * caused by inconsistent glyph measurement and outline. + */ + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT); if(error) { FT_ERROR_MSG("FT_Load_Glyph", error); return NULL; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_private.h b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_private.h index 976e54fea..7644101ab 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_private.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype_private.h @@ -14,7 +14,10 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "lv_freetype.h" +#include "../../misc/cache/lv_cache.h" +#include "../../misc/lv_ll.h" +#include "../../font/lv_font.h" #if LV_USE_FREETYPE @@ -43,7 +46,8 @@ extern "C" { #define LV_ASSERT_FREETYPE_FONT_DSC(dsc) \ do { \ LV_ASSERT_NULL(dsc); \ - LV_ASSERT_MSG(LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc), "Invalid font descriptor"); \ + LV_ASSERT_FORMAT_MSG(LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc), \ + "Invalid font descriptor: 0x%" LV_PRIx32, (dsc)->magic_num); \ } while (0) #define FT_INT_TO_F26DOT6(x) ((x) << 6) @@ -56,9 +60,23 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct _lv_freetype_cache_node_t lv_freetype_cache_node_t; +struct lv_freetype_outline_vector_t { + int32_t x; + int32_t y; +}; -struct _lv_freetype_cache_node_t { +struct lv_freetype_outline_event_param_t { + lv_freetype_outline_t outline; + lv_freetype_outline_type_t type; + lv_freetype_outline_vector_t to; + lv_freetype_outline_vector_t control1; + lv_freetype_outline_vector_t control2; +}; + + +typedef struct lv_freetype_cache_node_t lv_freetype_cache_node_t; + +struct lv_freetype_cache_node_t { const char * pathname; lv_freetype_font_style_t style; lv_freetype_font_render_mode_t render_mode; @@ -66,6 +84,7 @@ struct _lv_freetype_cache_node_t { uint32_t ref_size; /**< Reference size for calculating outline glyph's real size.*/ FT_Face face; + lv_mutex_t face_lock; /*glyph cache*/ lv_cache_t * glyph_cache; @@ -74,7 +93,7 @@ struct _lv_freetype_cache_node_t { lv_cache_t * draw_data_cache; }; -typedef struct _lv_freetype_context_t { +typedef struct lv_freetype_context_t { FT_Library library; lv_ll_t face_id_ll; lv_event_cb_t event_cb; @@ -84,7 +103,7 @@ typedef struct _lv_freetype_context_t { lv_cache_t * cache_node_cache; } lv_freetype_context_t; -typedef struct _lv_freetype_font_dsc_t { +typedef struct lv_freetype_font_dsc_t { uint32_t magic_num; lv_font_t font; uint32_t size; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp new file mode 100644 index 000000000..cd8df4cf7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp @@ -0,0 +1,201 @@ +#include "../../../lvgl.h" +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + +#include "../../core/lv_global.h" +#include "LittleFS.h" + +#if LV_FS_ARDUINO_ESP_LITTLEFS_LETTER == '\0' + #error "LV_FS_ARDUINO_ESP_LITTLEFS_LETTER must be set to a valid value" +#else + #if (LV_FS_ARDUINO_ESP_LITTLEFS_LETTER < 'A') || (LV_FS_ARDUINO_ESP_LITTLEFS_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_ARDUINO_ESP_LITTLEFS_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_ARDUINO_ESP_LITTLEFS_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + +typedef struct ArduinoEspLittleFile { + File file; +} ArduinoEspLittleFile; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void fs_init(void); +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +/** + * Register a driver for the LittleFS File System interface + */ +extern "C" void lv_fs_arduino_esp_littlefs_init(void) +{ + fs_init(); + + lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_esp_littlefs_fs_drv); + lv_fs_drv_init(fs_drv); + + fs_drv->letter = LV_FS_ARDUINO_ESP_LITTLEFS_LETTER; + fs_drv->open_cb = fs_open; + fs_drv->close_cb = fs_close; + fs_drv->read_cb = fs_read; + fs_drv->write_cb = fs_write; + fs_drv->seek_cb = fs_seek; + fs_drv->tell_cb = fs_tell; + + fs_drv->dir_close_cb = NULL; + fs_drv->dir_open_cb = NULL; + fs_drv->dir_read_cb = NULL; + + lv_fs_drv_register(fs_drv); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/*Initialize your Storage device and File system.*/ +static void fs_init(void) +{ + LittleFS.begin(); +} + +/** + * Open a file + * @param drv pointer to a driver where this function belongs + * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) + * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR + * @return a file descriptor or NULL on error + */ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + LV_UNUSED(drv); + + const char * flags; + if(mode == LV_FS_MODE_WR) + flags = FILE_WRITE; + else if(mode == LV_FS_MODE_RD) + flags = FILE_READ; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) + flags = FILE_WRITE; + + File file = LittleFS.open(path, flags); + if(!file) { + return NULL; + } + + ArduinoEspLittleFile * lf = new ArduinoEspLittleFile{file}; + + return (void *)lf; +} + +/** + * Close an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + lf->file.close(); + delete lf; + + return LV_FS_RES_OK; +} + +/** + * Read data from an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. + * @param buf pointer to a memory block where to store the read data + * @param btr number of Bytes To Read + * @param br the real number of read bytes (Byte Read) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + *br = lf->file.read((uint8_t *)buf, btr); + + return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Write into a file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable + * @param buf pointer to a buffer with the bytes to write + * @param btw Bytes To Write + * @param bw the number of real written bytes (Bytes Written) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + *bw = lf->file.write((uint8_t *)buf, btw); + + return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Set the read write pointer. Also expand the file size if necessary. + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open ) + * @param pos the new position of read write pointer + * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + LV_UNUSED(drv); + SeekMode mode; + if(whence == LV_FS_SEEK_SET) + mode = SeekSet; + else if(whence == LV_FS_SEEK_CUR) + mode = SeekCur; + else if(whence == LV_FS_SEEK_END) + mode = SeekEnd; + + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + + int rc = lf->file.seek(pos, mode); + + return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Give the position of the read write pointer + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_p variable + * @param pos_p pointer to store the result + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + + *pos_p = lf->file.position(); + + return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +#else /*LV_USE_FS_ARDUINO_ESP_LITTLEFS == 0*/ + +#if defined(LV_FS_ARDUINO_ESP_LITTLEFS_LETTER) && LV_FS_ARDUINO_ESP_LITTLEFS_LETTER != '\0' + #warning "LV_USE_FS_ARDUINO_ESP_LITTLEFS is not enabled but LV_FS_ARDUINO_ESP_LITTLEFS_LETTER is set" +#endif + +#endif /*LV_USE_FS_ARDUINO_ESP_LITTLEFS*/ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_sd.cpp b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_sd.cpp new file mode 100644 index 000000000..14941aca0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_arduino_sd.cpp @@ -0,0 +1,192 @@ +#include "../../../lvgl.h" +#if LV_USE_FS_ARDUINO_SD + +#include "../../core/lv_global.h" +#include +#include "SD.h" + +#if LV_FS_ARDUINO_SD_LETTER == '\0' + #error "LV_FS_ARDUINO_SD_LETTER must be set to a valid value" +#else + #if (LV_FS_ARDUINO_SD_LETTER < 'A') || (LV_FS_ARDUINO_SD_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_ARDUINO_SD_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_ARDUINO_SD_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + +typedef struct SdFile { + File file; +} SdFile; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +/** + * Register a driver for the SD File System interface + */ +extern "C" void lv_fs_arduino_sd_init(void) +{ + lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_sd_fs_drv); + lv_fs_drv_init(fs_drv); + + fs_drv->letter = LV_FS_ARDUINO_SD_LETTER; + fs_drv->open_cb = fs_open; + fs_drv->close_cb = fs_close; + fs_drv->read_cb = fs_read; + fs_drv->write_cb = fs_write; + fs_drv->seek_cb = fs_seek; + fs_drv->tell_cb = fs_tell; + + fs_drv->dir_close_cb = NULL; + fs_drv->dir_open_cb = NULL; + fs_drv->dir_read_cb = NULL; + + lv_fs_drv_register(fs_drv); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Open a file + * @param drv pointer to a driver where this function belongs + * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) + * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR + * @return a file descriptor or NULL on error + */ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + LV_UNUSED(drv); + + const char * flags; + if(mode == LV_FS_MODE_WR) + flags = FILE_WRITE; + else if(mode == LV_FS_MODE_RD) + flags = FILE_READ; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) + flags = FILE_WRITE; + + File file = SD.open(path, flags); + if(!file) { + return NULL; + } + + SdFile * lf = new SdFile{file}; + + return (void *)lf; +} + +/** + * Close an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + lf->file.close(); + delete lf; + + return LV_FS_RES_OK; +} + +/** + * Read data from an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. + * @param buf pointer to a memory block where to store the read data + * @param btr number of Bytes To Read + * @param br the real number of read bytes (Byte Read) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + *br = lf->file.read((uint8_t *)buf, btr); + + return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Write into a file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable + * @param buf pointer to a buffer with the bytes to write + * @param btw Bytes To Write + * @param bw the number of real written bytes (Bytes Written) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + *bw = lf->file.write((uint8_t *)buf, btw); + + return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Set the read write pointer. Also expand the file size if necessary. + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open ) + * @param pos the new position of read write pointer + * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + LV_UNUSED(drv); + SeekMode mode; + if(whence == LV_FS_SEEK_SET) + mode = SeekSet; + else if(whence == LV_FS_SEEK_CUR) + mode = SeekCur; + else if(whence == LV_FS_SEEK_END) + mode = SeekEnd; + + SdFile * lf = (SdFile *)file_p; + + int rc = lf->file.seek(pos, mode); + + return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Give the position of the read write pointer + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_p variable + * @param pos_p pointer to store the result + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + LV_UNUSED(drv); + SdFile * lf = (SdFile *)file_p; + + *pos_p = lf->file.position(); + + return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +#else /*LV_USE_FS_ARDUINO_SD == 0*/ + +#if defined(LV_FS_ARDUINO_SD_LETTER) && LV_FS_ARDUINO_SD_LETTER != '\0' + #warning "LV_USE_FS_ARDUINO_SD is not enabled but LV_FS_ARDUINO_SD_LETTER is set" +#endif + +#endif /*LV_USE_FS_ARDUINO_SD*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_fatfs.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_fatfs.c index e4343220e..79c62a367 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_fatfs.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_fatfs.c @@ -16,8 +16,21 @@ * DEFINES *********************/ +#ifdef ESP_PLATFORM + #define DIR FF_DIR /* ESP IDF typedefs `DIR` as `FF_DIR` in its version of ff.h. Use `FF_DIR` in LVGL too */ +#endif + #if LV_FS_FATFS_LETTER == '\0' - #error "LV_FS_FATFS_LETTER must be an upper case ASCII letter" + #error "LV_FS_FATFS_LETTER must be set to a valid value" +#else + #if (LV_FS_FATFS_LETTER < 'A') || (LV_FS_FATFS_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_FATFS_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_FATFS_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif #endif /********************** @@ -248,6 +261,8 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len) { LV_UNUSED(drv); + if(fn_len == 0) return LV_FS_RES_INV_PARAM; + FRESULT res; FILINFO fno; fn[0] = '\0'; @@ -261,7 +276,7 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint3 if(fno.fattrib & AM_DIR) { lv_snprintf(fn, fn_len, "/%s", fno.fname); } - else lv_strncpy(fn, fno.fname, fn_len); + else lv_strlcpy(fn, fno.fname, fn_len); } while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0); @@ -288,4 +303,4 @@ static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p) #warning "LV_USE_FS_FATFS is not enabled but LV_FS_FATFS_LETTER is set" #endif -#endif /*LV_USE_FS_POSIX*/ +#endif /*LV_USE_FS_FATFS*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_littlefs.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_littlefs.c index 3ac523361..490c6feeb 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_littlefs.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_littlefs.c @@ -4,10 +4,27 @@ #include "lfs.h" #include "../../core/lv_global.h" +#if LV_FS_LITTLEFS_LETTER == '\0' + #error "LV_FS_LITTLEFS_LETTER must be set to a valid value" +#else + #if (LV_FS_LITTLEFS_LETTER < 'A') || (LV_FS_LITTLEFS_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_LITTLEFS_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_LITTLEFS_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + typedef struct LittleFile { lfs_file_t file; } LittleFile; +typedef struct LittleDirectory { + lfs_dir_t dir; +} LittleDirectory; + /********************** * STATIC PROTOTYPES **********************/ @@ -17,6 +34,9 @@ static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); +static void * fs_dir_open(lv_fs_drv_t * drv, const char * path); +static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p); +static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len); void lv_littlefs_set_handler(lfs_t * lfs) { @@ -40,9 +60,9 @@ void lv_fs_littlefs_init(void) fs_drv->seek_cb = fs_seek; fs_drv->tell_cb = fs_tell; - fs_drv->dir_close_cb = NULL; - fs_drv->dir_open_cb = NULL; - fs_drv->dir_read_cb = NULL; + fs_drv->dir_open_cb = fs_dir_open; + fs_drv->dir_close_cb = fs_dir_close; + fs_drv->dir_read_cb = fs_dir_read; lv_fs_drv_register(fs_drv); } @@ -60,9 +80,7 @@ void lv_fs_littlefs_init(void) */ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) { - LV_UNUSED(drv); - - int flags; + int flags = 0; if(mode == LV_FS_MODE_WR) flags = LFS_O_WRONLY; else if(mode == LV_FS_MODE_RD) @@ -70,10 +88,10 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = LFS_O_RDWR; - LittleFile * lf = (LittleFile *)lv_malloc(sizeof(LittleFile)); - LV_ASSERT_NULL(lf); + LittleFile * lf = lv_malloc(sizeof(LittleFile)); + LV_ASSERT_MALLOC(lf); - lfs_t * lfs = (lfs_t *)drv->user_data; + lfs_t * lfs = drv->user_data; int err = lfs_file_open(lfs, &lf->file, path, flags); if(err) { return NULL; @@ -90,10 +108,9 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) */ static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) { - LV_UNUSED(drv); - LittleFile * lf = (LittleFile *)file_p; + LittleFile * lf = file_p; - lfs_t * lfs = (lfs_t *)drv->user_data; + lfs_t * lfs = drv->user_data; lfs_file_close(lfs, &lf->file); lv_free(lf); @@ -111,10 +128,9 @@ static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) */ static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) { - LV_UNUSED(drv); - LittleFile * lf = (LittleFile *)file_p; + LittleFile * lf = file_p; - lfs_t * lfs = (lfs_t *)drv->user_data; + lfs_t * lfs = drv->user_data; *br = lfs_file_read(lfs, &lf->file, (uint8_t *)buf, btr); return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; @@ -131,10 +147,9 @@ static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_ */ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) { - LV_UNUSED(drv); - LittleFile * lf = (LittleFile *)file_p; + LittleFile * lf = file_p; - lfs_t * lfs = (lfs_t *)drv->user_data; + lfs_t * lfs = drv->user_data; *bw = lfs_file_write(lfs, &lf->file, (uint8_t *)buf, btw); return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; @@ -143,15 +158,14 @@ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, /** * Set the read write pointer. Also expand the file size if necessary. * @param drv pointer to a driver where this function belongs - * @param file_p pointer to a file_t variable. (opened with fs_open ) + * @param file_p pointer to a file_t variable. (opened with fs_open) * @param pos the new position of read write pointer * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum */ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) { - LV_UNUSED(drv); - int mode; + int mode = 0; if(whence == LV_FS_SEEK_SET) mode = LFS_SEEK_SET; else if(whence == LV_FS_SEEK_CUR) @@ -159,9 +173,9 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs else if(whence == LV_FS_SEEK_END) mode = LFS_SEEK_END; - LittleFile * lf = (LittleFile *)file_p; + LittleFile * lf = file_p; - lfs_t * lfs = (lfs_t *)drv->user_data; + lfs_t * lfs = drv->user_data; int rc = lfs_file_seek(lfs, &lf->file, pos, mode); return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; @@ -176,13 +190,97 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs */ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) { - LV_UNUSED(drv); - LittleFile * lf = (LittleFile *)file_p; + LittleFile * lf = file_p; - lfs_t * lfs = (lfs_t *)drv->user_data; + lfs_t * lfs = drv->user_data; *pos_p = lfs_file_tell(lfs, &lf->file); return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; } +/** + * Open a directory + * @param drv pointer to a driver where this function belongs + * @param path path to the directory beginning with the driver letter (e.g. S:/folder) + * @return a directory descriptor or NULL on error + */ +static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) +{ + LittleDirectory * ld = lv_malloc(sizeof(LittleDirectory)); + LV_ASSERT_MALLOC(ld); + + lfs_t * lfs = drv->user_data; + int err = lfs_dir_open(lfs, &ld->dir, path); + if(err != LFS_ERR_OK) { + lv_free(ld); + return NULL; + } + + return (void *)ld; +} + +/** + * Close an opened directory + * @param drv pointer to a driver where this function belongs + * @param dir_p pointer to a dir_p variable. (opened with fs_dir_open) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p) +{ + LittleDirectory * ld = dir_p; + + lfs_t * lfs = drv->user_data; + int rc = lfs_dir_close(lfs, &ld->dir); + + if(rc < 0) return LV_FS_RES_UNKNOWN; + lv_free(ld); + + return LV_FS_RES_OK; +} + +/** + * Read data from an opened directory + * @param drv pointer to a driver where this function belongs + * @param dir_p pointer to a file_t variable. + * @param fn pointer to a buffer to store the filename + * @param fn_len length of the buffer to store the filename + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len) +{ + if(fn_len == 0) return LV_FS_RES_INV_PARAM; + + LittleDirectory * lf = dir_p; + + lfs_t * lfs = drv->user_data; + + fn[0] = '\0'; + do { + struct lfs_info info; + int res = lfs_dir_read(lfs, &lf->dir, &info); + + if(res < 0) return LV_FS_RES_UNKNOWN; + if(res == 0) { /* End of the directory */ + fn[0] = '\0'; + break; + } + + if(info.type != LFS_TYPE_DIR) { + lv_strlcpy(fn, info.name, fn_len); + } + else { + lv_snprintf(fn, fn_len, "/%s", info.name); + } + + } while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0); + + return LV_FS_RES_OK; +} + +#else /*LV_USE_FS_LITTLEFS == 0*/ + +#if defined(LV_FS_LITTLEFS_LETTER) && LV_FS_LITTLEFS_LETTER != '\0' + #warning "LV_USE_FS_LITTLEFS is not enabled but LV_FS_LITTLEFS_LETTER is set" #endif + +#endif /*LV_USE_FS_LITTLEFS*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_memfs.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_memfs.c index 52379beb7..c207c76fd 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_memfs.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_memfs.c @@ -40,12 +40,25 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_fs_private.h" #include "../../../lvgl.h" #if LV_USE_FS_MEMFS /********************* * DEFINES *********************/ +#if LV_FS_MEMFS_LETTER == '\0' + #error "LV_FS_MEMFS_LETTER must be set to a valid value" +#else + #if (LV_FS_MEMFS_LETTER < 'A') || (LV_FS_MEMFS_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_MEMFS_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_MEMFS_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif /********************** * TYPEDEFS diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_posix.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_posix.c index 839742fc5..f1e66fd23 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_posix.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_posix.c @@ -15,13 +15,24 @@ #include #include #include +#include +#include "../../core/lv_global.h" /********************* * DEFINES *********************/ #if LV_FS_POSIX_LETTER == '\0' - #error "LV_FS_POSIX_LETTER must be an upper case ASCII letter" + #error "LV_FS_POSIX_LETTER must be set to a valid value" +#else + #if (LV_FS_POSIX_LETTER < 'A') || (LV_FS_POSIX_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_POSIX_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_POSIX_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif #endif /** The reason for 'fd + 1' is because open() may return a legal fd with a value of 0, @@ -104,7 +115,7 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) { LV_UNUSED(drv); - uint32_t flags = 0; + int flags = 0; if(mode == LV_FS_MODE_WR) flags = O_WRONLY | O_CREAT; else if(mode == LV_FS_MODE_RD) flags = O_RDONLY; else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = O_RDWR | O_CREAT; @@ -113,10 +124,13 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) char buf[256]; lv_snprintf(buf, sizeof(buf), LV_FS_POSIX_PATH "%s", path); - int f = open(buf, flags, 0666); - if(f < 0) return NULL; + int fd = open(buf, flags, 0666); + if(fd < 0) { + LV_LOG_WARN("Could not open file: %s, flags: 0x%x, errno: %d", buf, flags, errno); + return NULL; + } - return FD2FILEP(f); + return FD2FILEP(fd); } /** @@ -129,7 +143,14 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) { LV_UNUSED(drv); - close(FILEP2FD(file_p)); + + int fd = FILEP2FD(file_p); + int ret = close(fd); + if(ret < 0) { + LV_LOG_WARN("Could not close file: %d, errno: %d", fd, errno); + return LV_FS_RES_FS_ERR; + } + return LV_FS_RES_OK; } @@ -146,8 +167,16 @@ static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) { LV_UNUSED(drv); - *br = read(FILEP2FD(file_p), buf, btr); - return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; + + int fd = FILEP2FD(file_p); + ssize_t ret = read(fd, buf, btr); + if(ret < 0) { + LV_LOG_WARN("Could not read file: %d, errno: %d", fd, errno); + return LV_FS_RES_FS_ERR; + } + + *br = (uint32_t)ret; + return LV_FS_RES_OK; } /** @@ -162,8 +191,16 @@ static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) { LV_UNUSED(drv); - *bw = write(FILEP2FD(file_p), buf, btw); - return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; + + int fd = FILEP2FD(file_p); + ssize_t ret = write(fd, buf, btw); + if(ret < 0) { + LV_LOG_WARN("Could not write file: %d, errno: %d", fd, errno); + return LV_FS_RES_FS_ERR; + } + + *bw = (uint32_t)ret; + return LV_FS_RES_OK; } /** @@ -192,8 +229,14 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs return LV_FS_RES_INV_PARAM; } - off_t offset = lseek(FILEP2FD(file_p), pos, w); - return offset < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK; + int fd = FILEP2FD(file_p); + off_t offset = lseek(fd, pos, w); + if(offset < 0) { + LV_LOG_WARN("Could not seek file: %d, errno: %d", fd, errno); + return LV_FS_RES_FS_ERR; + } + + return LV_FS_RES_OK; } /** @@ -207,9 +250,16 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) { LV_UNUSED(drv); - off_t offset = lseek(FILEP2FD(file_p), 0, SEEK_CUR); - *pos_p = offset; - return offset < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK; + + int fd = FILEP2FD(file_p); + off_t offset = lseek(fd, 0, SEEK_CUR); + if(offset < 0) { + LV_LOG_WARN("Could not get position of file: %d, errno: %d", fd, errno); + return LV_FS_RES_FS_ERR; + } + + *pos_p = (uint32_t)offset; + return LV_FS_RES_OK; } /** @@ -225,7 +275,14 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) /*Make the path relative to the current directory (the projects root folder)*/ char buf[256]; lv_snprintf(buf, sizeof(buf), LV_FS_POSIX_PATH "%s", path); - return opendir(buf); + + void * dir = opendir(buf); + if(!dir) { + LV_LOG_WARN("Could not open directory: %s, errno: %d", buf, errno); + return NULL; + } + + return dir; } /** @@ -240,16 +297,17 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len) { LV_UNUSED(drv); + if(fn_len == 0) return LV_FS_RES_INV_PARAM; struct dirent * entry; do { entry = readdir(dir_p); if(entry) { if(entry->d_type == DT_DIR) lv_snprintf(fn, fn_len, "/%s", entry->d_name); - else lv_strncpy(fn, entry->d_name, fn_len); + else lv_strlcpy(fn, entry->d_name, fn_len); } else { - lv_strncpy(fn, "", fn_len); + lv_strlcpy(fn, "", fn_len); } } while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0); @@ -266,7 +324,12 @@ static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p) { LV_UNUSED(drv); - closedir(dir_p); + int ret = closedir(dir_p); + if(ret < 0) { + LV_LOG_WARN("Could not close directory: errno: %d", errno); + return LV_FS_RES_FS_ERR; + } + return LV_FS_RES_OK; } #else /*LV_USE_FS_POSIX == 0*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_stdio.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_stdio.c index 020749d65..a6c901e15 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_stdio.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_stdio.c @@ -21,13 +21,26 @@ /********************* * DEFINES *********************/ +#if LV_FS_STDIO_LETTER == '\0' + #error "LV_FS_STDIO_LETTER must be set to a valid value" +#else + #if (LV_FS_STDIO_LETTER < 'A') || (LV_FS_STDIO_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_STDIO_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_STDIO_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + #define MAX_PATH_LEN 256 /********************** * TYPEDEFS **********************/ typedef struct { -#ifdef WIN32 +#ifdef _WIN32 HANDLE dir_p; char next_fn[MAX_PATH_LEN]; #else @@ -276,6 +289,8 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len) { LV_UNUSED(drv); + if(fn_len == 0) return LV_FS_RES_INV_PARAM; + dir_handle_t * handle = (dir_handle_t *)dir_p; #ifndef WIN32 struct dirent * entry; @@ -284,16 +299,16 @@ static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint3 if(entry) { /*Note, DT_DIR is not defined in C99*/ if(entry->d_type == DT_DIR) lv_snprintf(fn, fn_len, "/%s", entry->d_name); - else lv_strncpy(fn, entry->d_name, fn_len); + else lv_strlcpy(fn, entry->d_name, fn_len); } else { - lv_strncpy(fn, "", fn_len); + lv_strlcpy(fn, "", fn_len); } } while(lv_strcmp(fn, "/.") == 0 || lv_strcmp(fn, "/..") == 0); #else - lv_strncpy(fn, handle->next_fn, fn_len); + lv_strlcpy(fn, handle->next_fn, fn_len); - lv_strncpy(handle->next_fn, "", fn_len); + lv_strcpy(handle->next_fn, ""); WIN32_FIND_DATAA fdata; if(FindNextFileA(handle->dir_p, &fdata) == false) return LV_FS_RES_OK; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_win32.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_win32.c index e021219ed..d5fb36487 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_win32.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_win32.c @@ -17,6 +17,19 @@ /********************* * DEFINES *********************/ +#if LV_FS_WIN32_LETTER == '\0' + #error "LV_FS_WIN32_LETTER must be set to a valid value" +#else + #if (LV_FS_WIN32_LETTER < 'A') || (LV_FS_WIN32_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + #error "LV_FS_WIN32_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_WIN32_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism + #endif + #endif +#endif + #define MAX_PATH_LEN 256 /********************** @@ -413,8 +426,10 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len) { LV_UNUSED(drv); + if(fn_len == 0) return LV_FS_RES_INV_PARAM; + dir_handle_t * handle = (dir_handle_t *)dir_p; - lv_strcpy(fn, handle->next_fn); + lv_strlcpy(fn, handle->next_fn, fn_len); lv_fs_res_t current_error = handle->next_error; lv_strcpy(handle->next_fn, ""); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fsdrv.h b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fsdrv.h index 993a96735..f830c3a2d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fsdrv.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fsdrv.h @@ -48,9 +48,19 @@ void lv_fs_memfs_init(void); #endif #if LV_USE_FS_LITTLEFS +struct lfs; +void lv_littlefs_set_handler(struct lfs *); void lv_fs_littlefs_init(void); #endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS +void lv_fs_arduino_esp_littlefs_init(void); +#endif + +#if LV_USE_FS_ARDUINO_SD +void lv_fs_arduino_sd_init(void); +#endif + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c index b35a5730f..8e97ab503 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c @@ -84,13 +84,13 @@ static gd_GIF * gif_open(gd_GIF * gif_base) /* Header */ f_gif_read(gif_base, sigver, 3); if(memcmp(sigver, "GIF", 3) != 0) { - LV_LOG_WARN("invalid signature\n"); + LV_LOG_WARN("invalid signature"); goto fail; } /* Version */ f_gif_read(gif_base, sigver, 3); if(memcmp(sigver, "89a", 3) != 0) { - LV_LOG_WARN("invalid version\n"); + LV_LOG_WARN("invalid version"); goto fail; } /* Width x Height */ @@ -100,7 +100,7 @@ static gd_GIF * gif_open(gd_GIF * gif_base) f_gif_read(gif_base, &fdsz, 1); /* Presence of GCT */ if(!(fdsz & 0x80)) { - LV_LOG_WARN("no global color table\n"); + LV_LOG_WARN("no global color table"); goto fail; } /* Color Space's Depth */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.h b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.h index 3fd60bf3b..21ff210ab 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.h @@ -5,10 +5,10 @@ extern "C" { #endif -#include #include "../../misc/lv_fs.h" #if LV_USE_GIF +#include typedef struct _gd_Palette { int size; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c index e1eab06b0..ca48f13fd 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_gif.h" +#include "../../misc/lv_timer_private.h" +#include "../../core/lv_obj_class_private.h" +#include "lv_gif_private.h" #if LV_USE_GIF #include "gifdec.h" @@ -59,32 +61,39 @@ lv_obj_t * lv_gif_create(lv_obj_t * parent) void lv_gif_set_src(lv_obj_t * obj, const void * src) { lv_gif_t * gifobj = (lv_gif_t *) obj; + gd_GIF * gif = gifobj->gif; /*Close previous gif if any*/ - if(gifobj->gif) { + if(gif != NULL) { lv_image_cache_drop(lv_image_get_src(obj)); - gd_close_gif(gifobj->gif); + gd_close_gif(gif); gifobj->gif = NULL; gifobj->imgdsc.data = NULL; } if(lv_image_src_get_type(src) == LV_IMAGE_SRC_VARIABLE) { const lv_image_dsc_t * img_dsc = src; - gifobj->gif = gd_open_gif_data(img_dsc->data); + gif = gd_open_gif_data(img_dsc->data); } else if(lv_image_src_get_type(src) == LV_IMAGE_SRC_FILE) { - gifobj->gif = gd_open_gif_file(src); + gif = gd_open_gif_file(src); } - if(gifobj->gif == NULL) { + if(gif == NULL) { LV_LOG_WARN("Couldn't load the source"); return; } - gifobj->imgdsc.data = gifobj->gif->canvas; + gifobj->gif = gif; + gifobj->imgdsc.data = gif->canvas; + gifobj->imgdsc.header.magic = LV_IMAGE_HEADER_MAGIC; + gifobj->imgdsc.header.flags = LV_IMAGE_FLAGS_MODIFIABLE; gifobj->imgdsc.header.cf = LV_COLOR_FORMAT_ARGB8888; - gifobj->imgdsc.header.h = gifobj->gif->height; - gifobj->imgdsc.header.w = gifobj->gif->width; + gifobj->imgdsc.header.h = gif->height; + gifobj->imgdsc.header.w = gif->width; + gifobj->imgdsc.header.stride = gif->width * 4; + gifobj->imgdsc.data_size = gif->width * gif->height * 4; + gifobj->last_call = lv_tick_get(); lv_image_set_src(obj, &gifobj->imgdsc); @@ -169,7 +178,7 @@ static void next_frame_task_cb(lv_timer_t * t) /*It was the last repeat*/ lv_result_t res = lv_obj_send_event(obj, LV_EVENT_READY, NULL); lv_timer_pause(t); - if(res != LV_FS_RES_OK) return; + if(res != LV_RESULT_OK) return; } gd_render_frame(gifobj->gif, (uint8_t *)gifobj->imgdsc.data); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h index 9228bf557..fc6323fa6 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.h @@ -14,7 +14,13 @@ extern "C" { * INCLUDES *********************/ -#include "../../../lvgl.h" +#include "../../lv_conf_internal.h" +#include "../../misc/lv_types.h" +#include "../../draw/lv_draw_buf.h" +#include "../../widgets/image/lv_image.h" +#include "../../core/lv_obj_class.h" +#include LV_STDBOOL_INCLUDE +#include LV_STDINT_INCLUDE #if LV_USE_GIF #include "gifdec.h" @@ -27,14 +33,6 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct { - lv_image_t img; - gd_GIF * gif; - lv_timer_t * timer; - lv_draw_buf_t imgdsc; - uint32_t last_call; -} lv_gif_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_gif_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif_private.h b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif_private.h new file mode 100644 index 000000000..c4ea17af7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_gif_private.h + * + */ + +#ifndef LV_GIF_PRIVATE_H +#define LV_GIF_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../widgets/image/lv_image_private.h" +#include "lv_gif.h" + +#if LV_USE_GIF + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_gif_t { + lv_image_t img; + gd_GIF * gif; + lv_timer_t * timer; + lv_image_dsc_t imgdsc; + uint32_t last_call; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_GIF */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GIF_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c b/lib/libesp32_lvgl/lvgl/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c index f3ac140d2..f058728e0 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "../../draw/lv_image_decoder_private.h" #include "../../../lvgl.h" #if LV_USE_LIBJPEG_TURBO @@ -14,10 +15,16 @@ #include #include #include +#include "../../core/lv_global.h" /********************* * DEFINES *********************/ + +#define DECODER_NAME "JPEG_TURBO" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + #define JPEG_PIXEL_SIZE 3 /* RGB888 */ #define JPEG_SIGNATURE 0xFFD8FF #define IS_JPEG_SIGNATURE(x) (((x) & 0x00FFFFFF) == JPEG_SIGNATURE) @@ -33,7 +40,7 @@ typedef struct error_mgr_s { /********************** * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static lv_draw_buf_t * decode_jpeg_file(const char * filename); @@ -72,7 +79,8 @@ void lv_libjpeg_turbo_init(void) lv_image_decoder_set_info_cb(dec, decoder_info); lv_image_decoder_set_open_cb(dec, decoder_open); lv_image_decoder_set_close_cb(dec, decoder_close); - lv_image_decoder_set_cache_free_cb(dec, NULL); /*Use general cache free method*/ + + dec->name = DECODER_NAME; } void lv_libjpeg_turbo_deinit(void) @@ -92,42 +100,34 @@ void lv_libjpeg_turbo_deinit(void) /** * Get info about a JPEG image - * @param src can be file name or pointer to a C array + * @param dsc image descriptor containing the source and type of the image and other info. * @param header store the info here * @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info */ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { LV_UNUSED(decoder); /*Unused*/ - lv_image_src_t src_type = lv_image_src_get_type(src); /*Get the source type*/ + lv_image_src_t src_type = dsc->src_type; /*Get the source type*/ /*If it's a JPEG file...*/ if(src_type == LV_IMAGE_SRC_FILE) { - const char * fn = src; - - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) { - LV_LOG_WARN("Can't open file: %s", fn); - return LV_RESULT_INVALID; - } - + const char * src = dsc->src; uint32_t jpg_signature = 0; uint32_t rn; - lv_fs_read(&f, &jpg_signature, sizeof(jpg_signature), &rn); - lv_fs_close(&f); + lv_fs_read(&dsc->file, &jpg_signature, sizeof(jpg_signature), &rn); if(rn != sizeof(jpg_signature)) { - LV_LOG_WARN("file: %s signature len = %" LV_PRIu32 " error", fn, rn); + LV_LOG_WARN("file: %s signature len = %" LV_PRIu32 " error", src, rn); return LV_RESULT_INVALID; } - bool is_jpeg_ext = (lv_strcmp(lv_fs_get_ext(fn), "jpg") == 0) - || (lv_strcmp(lv_fs_get_ext(fn), "jpeg") == 0); + const char * ext = lv_fs_get_ext(src); + bool is_jpeg_ext = (lv_strcmp(ext, "jpg") == 0) + || (lv_strcmp(ext, "jpeg") == 0); if(!IS_JPEG_SIGNATURE(jpg_signature)) { if(is_jpeg_ext) { - LV_LOG_WARN("file: %s signature = 0X%" LV_PRIX32 " error", fn, jpg_signature); + LV_LOG_WARN("file: %s signature = 0X%" LV_PRIX32 " error", src, jpg_signature); } return LV_RESULT_INVALID; } @@ -136,7 +136,7 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, uint32_t height; uint32_t orientation = 0; - if(!get_jpeg_head_info(fn, &width, &height, &orientation)) { + if(!get_jpeg_head_info(src, &width, &height, &orientation)) { return LV_RESULT_INVALID; } @@ -172,9 +172,12 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d dsc->decoded = decoded; - if(dsc->args.no_cache) return LV_RES_OK; + if(dsc->args.no_cache) return LV_RESULT_OK; -#if LV_CACHE_DEF_SIZE > 0 + /*If the image cache is disabled, just return the decoded image*/ + if(!lv_image_cache_is_enabled()) return LV_RESULT_OK; + + /*Add the decoded image to the cache*/ lv_image_cache_data_t search_key; search_key.src_type = dsc->src_type; search_key.src = dsc->src; @@ -187,7 +190,6 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d return LV_RESULT_INVALID; } dsc->cache_entry = entry; -#endif return LV_RESULT_OK; /*If not returned earlier then it failed*/ } @@ -201,10 +203,8 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * { LV_UNUSED(decoder); /*Unused*/ - if(dsc->args.no_cache || LV_CACHE_DEF_SIZE == 0) - lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); - else - lv_cache_release(dsc->cache, dsc->cache_entry, NULL); + if(dsc->args.no_cache || + !lv_image_cache_is_enabled()) lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); } static uint8_t * read_file(const char * filename, uint32_t * size) @@ -368,7 +368,8 @@ static lv_draw_buf_t * decode_jpeg_file(const char * filename) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); uint32_t buf_width = (image_angle % 180) ? cinfo.output_height : cinfo.output_width; uint32_t buf_height = (image_angle % 180) ? cinfo.output_width : cinfo.output_height; - decoded = lv_draw_buf_create(buf_width, buf_height, LV_COLOR_FORMAT_RGB888, LV_STRIDE_AUTO); + decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, buf_width, buf_height, LV_COLOR_FORMAT_RGB888, + LV_STRIDE_AUTO); if(decoded != NULL) { uint32_t line_index = 0; /* while (scan lines remain to be read) */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/libpng/lv_libpng.c b/lib/libesp32_lvgl/lvgl/src/libs/libpng/lv_libpng.c index 8f539b86b..587e5fc69 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/libpng/lv_libpng.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/libpng/lv_libpng.c @@ -6,16 +6,23 @@ /********************* * INCLUDES *********************/ +#include "../../draw/lv_image_decoder_private.h" #include "../../../lvgl.h" #if LV_USE_LIBPNG #include "lv_libpng.h" #include +#include +#include "../../core/lv_global.h" /********************* * DEFINES *********************/ +#define DECODER_NAME "PNG" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -23,10 +30,10 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * src, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); -static lv_draw_buf_t * decode_png_file(const char * filename); +static lv_draw_buf_t * decode_png(lv_image_decoder_dsc_t * dsc); /********************** * STATIC VARIABLES @@ -49,7 +56,8 @@ void lv_libpng_init(void) lv_image_decoder_set_info_cb(dec, decoder_info); lv_image_decoder_set_open_cb(dec, decoder_open); lv_image_decoder_set_close_cb(dec, decoder_close); - lv_image_decoder_set_cache_free_cb(dec, NULL); /*Use general cache free method*/ + + dec->name = DECODER_NAME; } void lv_libpng_deinit(void) @@ -69,38 +77,46 @@ void lv_libpng_deinit(void) /** * Get info about a PNG image - * @param src can be file name or pointer to a C array + * @param dsc can be file name or pointer to a C array * @param header store the info here * @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info */ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { LV_UNUSED(decoder); /*Unused*/ - lv_image_src_t src_type = lv_image_src_get_type(src); /*Get the source type*/ - /*If it's a PNG file...*/ - if(src_type == LV_IMAGE_SRC_FILE) { - const char * fn = src; + lv_image_src_t src_type = dsc->src_type; /*Get the source type*/ - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) return LV_RESULT_INVALID; - - /* Read the width and height from the file. They have a constant location: - * [16..19]: width - * [20..23]: height - */ + if(src_type == LV_IMAGE_SRC_FILE || src_type == LV_IMAGE_SRC_VARIABLE) { + uint32_t * size; + static const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; uint8_t buf[24]; - uint32_t rn; - lv_fs_read(&f, buf, sizeof(buf), &rn); - lv_fs_close(&f); - if(rn != sizeof(buf)) return LV_RESULT_INVALID; + /*If it's a PNG file...*/ + if(src_type == LV_IMAGE_SRC_FILE) { + /* Read the width and height from the file. They have a constant location: + * [16..19]: width + * [20..23]: height + */ + uint32_t rn; + lv_fs_read(&dsc->file, buf, sizeof(buf), &rn); - const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; - if(memcmp(buf, magic, sizeof(magic)) != 0) return LV_RESULT_INVALID; + if(rn != sizeof(buf)) return LV_RESULT_INVALID; + + if(lv_memcmp(buf, magic, sizeof(magic)) != 0) return LV_RESULT_INVALID; + + size = (uint32_t *)&buf[16]; + } + /*If it's a PNG file in a C array...*/ + else { + const lv_image_dsc_t * img_dsc = dsc->src; + const uint32_t data_size = img_dsc->data_size; + size = ((uint32_t *)img_dsc->data) + 4; + + if(data_size < sizeof(magic)) return LV_RESULT_INVALID; + if(lv_memcmp(img_dsc->data, magic, sizeof(magic)) != 0) return LV_RESULT_INVALID; + } - uint32_t * size = (uint32_t *)&buf[16]; /*Save the data in the header*/ header->cf = LV_COLOR_FORMAT_ARGB8888; /*The width and height are stored in Big endian format so convert them to little endian*/ @@ -122,49 +138,47 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); /*Unused*/ + lv_draw_buf_t * decoded; + decoded = decode_png(dsc); - /*If it's a PNG file...*/ - if(dsc->src_type == LV_IMAGE_SRC_FILE) { - const char * fn = dsc->src; - lv_draw_buf_t * decoded = decode_png_file(fn); - if(decoded == NULL) { - return LV_RESULT_INVALID; - } - - lv_draw_buf_t * adjusted = lv_image_decoder_post_process(dsc, decoded); - if(adjusted == NULL) { - lv_draw_buf_destroy(decoded); - return LV_RESULT_INVALID; - } - - /*The adjusted draw buffer is newly allocated.*/ - if(adjusted != decoded) { - lv_draw_buf_destroy(decoded); - decoded = adjusted; - } - - dsc->decoded = decoded; - - if(dsc->args.no_cache) return LV_RES_OK; - -#if LV_CACHE_DEF_SIZE > 0 - lv_image_cache_data_t search_key; - search_key.src_type = dsc->src_type; - search_key.src = dsc->src; - search_key.slot.size = decoded->data_size; - - lv_cache_entry_t * entry = lv_image_decoder_add_to_cache(decoder, &search_key, decoded, NULL); - - if(entry == NULL) { - lv_draw_buf_destroy(decoded); - return LV_RESULT_INVALID; - } - dsc->cache_entry = entry; -#endif - return LV_RESULT_OK; /*The image is fully decoded. Return with its pointer*/ + if(decoded == NULL) { + return LV_RESULT_INVALID; } - return LV_RESULT_INVALID; /*If not returned earlier then it failed*/ + lv_draw_buf_t * adjusted = lv_image_decoder_post_process(dsc, decoded); + if(adjusted == NULL) { + lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + return LV_RESULT_INVALID; + } + + /*The adjusted draw buffer is newly allocated.*/ + if(adjusted != decoded) { + lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + decoded = adjusted; + } + + dsc->decoded = decoded; + + if(dsc->args.no_cache) return LV_RESULT_OK; + + /*If the image cache is disabled, just return the decoded image*/ + if(!lv_image_cache_is_enabled()) return LV_RESULT_OK; + + /*Add the decoded image to the cache*/ + lv_image_cache_data_t search_key; + search_key.src_type = dsc->src_type; + search_key.src = dsc->src; + search_key.slot.size = decoded->data_size; + + lv_cache_entry_t * entry = lv_image_decoder_add_to_cache(decoder, &search_key, decoded, NULL); + + if(entry == NULL) { + lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + return LV_RESULT_INVALID; + } + dsc->cache_entry = entry; + + return LV_RESULT_OK; /*The image is fully decoded. Return with its pointer*/ } /** @@ -174,10 +188,8 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * { LV_UNUSED(decoder); /*Unused*/ - if(dsc->args.no_cache || LV_CACHE_DEF_SIZE == 0) - lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); - else - lv_cache_release(dsc->cache, dsc->cache_entry, NULL); + if(dsc->args.no_cache || + !lv_image_cache_is_enabled()) lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, (lv_draw_buf_t *)dsc->decoded); } static uint8_t * alloc_file(const char * filename, uint32_t * size) @@ -235,49 +247,81 @@ failed: return data; } -static lv_draw_buf_t * decode_png_file(const char * filename) +static lv_draw_buf_t * decode_png(lv_image_decoder_dsc_t * dsc) { int ret; - + uint8_t * png_data; + uint32_t png_data_size; /*Prepare png_image*/ png_image image; lv_memzero(&image, sizeof(image)); image.version = PNG_IMAGE_VERSION; - uint32_t data_size; - uint8_t * data = alloc_file(filename, &data_size); - if(data == NULL) { - LV_LOG_WARN("can't load file: %s", filename); - return NULL; + if(dsc->src_type == LV_IMAGE_SRC_FILE) { + if(lv_strcmp(lv_fs_get_ext(dsc->src), "png") != 0) { /*Check the extension*/ + return NULL; + } + + png_data = alloc_file(dsc->src, &png_data_size); + if(png_data == NULL) { + LV_LOG_WARN("can't load file: %s", (const char *)dsc->src); + return NULL; + } } + else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) { + const lv_image_dsc_t * img_dsc = dsc->src; + png_data = (uint8_t *)img_dsc->data; + png_data_size = img_dsc->data_size; + } + else + return NULL; /*Ready to read file*/ - ret = png_image_begin_read_from_memory(&image, data, data_size); + ret = png_image_begin_read_from_memory(&image, png_data, png_data_size); if(!ret) { - LV_LOG_ERROR("png file: %s read failed: %d", filename, ret); - lv_free(data); + LV_LOG_ERROR("png read failed: %d", ret); + if(dsc->src_type == LV_IMAGE_SRC_FILE) + lv_free(png_data); return NULL; } - /*Set color format*/ - image.format = PNG_FORMAT_BGRA; + lv_color_format_t cf; + if(dsc->args.use_indexed && (image.format & PNG_FORMAT_FLAG_COLORMAP)) { + cf = LV_COLOR_FORMAT_I8; + image.format = PNG_FORMAT_BGRA_COLORMAP; + } + else { + cf = LV_COLOR_FORMAT_ARGB8888; + image.format = PNG_FORMAT_BGRA; + } /*Alloc image buffer*/ lv_draw_buf_t * decoded; - decoded = lv_draw_buf_create(image.width, image.height, LV_COLOR_FORMAT_ARGB8888, PNG_IMAGE_ROW_STRIDE(image)); + decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, image.width, image.height, cf, LV_STRIDE_AUTO); if(decoded == NULL) { - LV_LOG_ERROR("alloc PNG_IMAGE_SIZE(%" LV_PRIu32 ") failed: %s", (uint32_t)PNG_IMAGE_SIZE(image), filename); - lv_free(data); + + if(dsc->src_type == LV_IMAGE_SRC_FILE) { + LV_LOG_ERROR("alloc PNG_IMAGE_SIZE(%" LV_PRIu32 ") failed: %s", (uint32_t)PNG_IMAGE_SIZE(image), + (const char *)dsc->src); + lv_free(png_data); + } + else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) + LV_LOG_ERROR("alloc PNG_IMAGE_SIZE(%" LV_PRIu32 ")", (uint32_t)PNG_IMAGE_SIZE(image)); + return NULL; } + void * palette = decoded->data; + void * map = decoded->data + LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t); + /*Start decoding*/ - ret = png_image_finish_read(&image, NULL, decoded->data, 0, NULL); + ret = png_image_finish_read(&image, NULL, map, decoded->header.stride, palette); png_image_free(&image); - lv_free(data); + if(dsc->src_type == LV_IMAGE_SRC_FILE) + lv_free(png_data); if(!ret) { - LV_LOG_ERROR("png decode failed: %d", ret); - lv_draw_buf_destroy(decoded); + LV_LOG_ERROR("png decode failed: %s", image.message); + lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); return NULL; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.c b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.c index 385cf4588..a3f0b59a1 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.c @@ -1,7 +1,7 @@ /* -LodePNG version 20201017 +LodePNG version 20230410 -Copyright (c) 2005-2020 Lode Vandevenne +Copyright (c) 2005-2023 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,9 +30,13 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for #include "lodepng.h" #if LV_USE_LODEPNG +#include "../../core/lv_global.h" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) #ifdef LODEPNG_COMPILE_DISK #include /* LONG_MAX */ + #include /* file handling */ #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ALLOCATORS @@ -44,10 +48,10 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ #endif /*_MSC_VER */ -const char * LODEPNG_VERSION_STRING = "20201017"; +const char * LODEPNG_VERSION_STRING = "20230410"; /* -This source file is built up in the following large parts. The code sections +This source file is divided into the following large parts. The code sections with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. -Tools for C and common code for PNG and Zlib -C Code for Zlib (huffman, deflate, ...) @@ -144,7 +148,6 @@ static size_t lodepng_strlen(const char * a) #define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b)) #define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define LODEPNG_ABS(x) ((x) < 0 ? -(x) : (x)) #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER) /* Safely check if adding two integers will overflow (no undefined @@ -278,7 +281,7 @@ typedef struct ucvector { } ucvector; /*returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned ucvector_resize(ucvector * p, size_t size) +static unsigned ucvector_reserve(ucvector * p, size_t size) { if(size > p->allocsize) { size_t newsize = size + (p->allocsize >> 1u); @@ -289,10 +292,16 @@ static unsigned ucvector_resize(ucvector * p, size_t size) } else return 0; /*error: not enough memory*/ } - p->size = size; return 1; /*success*/ } +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_resize(ucvector * p, size_t size) +{ + p->size = size; + return ucvector_reserve(p, size); +} + static ucvector ucvector_init(unsigned char * buffer, size_t size) { ucvector v; @@ -507,36 +516,29 @@ static unsigned LodePNGBitReader_init(LodePNGBitReader * reader, const unsigned ensureBits functions: Ensures the reader can at least read nbits bits in one or more readBits calls, safely even if not enough bits are available. -Returns 1 if there are enough bits available, 0 if not. +The nbits parameter is unused but is given for documentation purposes, error +checking for amount of bits must be done beforehand. */ -/*See ensureBits documentation above. This one ensures exactly 1 bit */ -/*static unsigned ensureBits1(LodePNGBitReader* reader) { - if(reader->bp >= reader->bitsize) return 0; - reader->buffer = (unsigned)reader->data[reader->bp >> 3u] >> (reader->bp & 7u); - return 1; -}*/ - /*See ensureBits documentation above. This one ensures up to 9 bits */ -static unsigned ensureBits9(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE void ensureBits9(LodePNGBitReader * reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; if(start + 1u < size) { reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u); reader->buffer >>= (reader->bp & 7u); - return 1; } else { reader->buffer = 0; - if(start + 0u < size) reader->buffer |= reader->data[start + 0]; + if(start + 0u < size) reader->buffer = reader->data[start + 0]; reader->buffer >>= (reader->bp & 7u); - return reader->bp + nbits <= reader->bitsize; } + (void)nbits; } /*See ensureBits documentation above. This one ensures up to 17 bits */ -static unsigned ensureBits17(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE void ensureBits17(LodePNGBitReader * reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; @@ -544,19 +546,18 @@ static unsigned ensureBits17(LodePNGBitReader * reader, size_t nbits) reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u); reader->buffer >>= (reader->bp & 7u); - return 1; } else { reader->buffer = 0; if(start + 0u < size) reader->buffer |= reader->data[start + 0]; if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); reader->buffer >>= (reader->bp & 7u); - return reader->bp + nbits <= reader->bitsize; } + (void)nbits; } /*See ensureBits documentation above. This one ensures up to 25 bits */ -static LODEPNG_INLINE unsigned ensureBits25(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE void ensureBits25(LodePNGBitReader * reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; @@ -564,7 +565,6 @@ static LODEPNG_INLINE unsigned ensureBits25(LodePNGBitReader * reader, size_t nb reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); reader->buffer >>= (reader->bp & 7u); - return 1; } else { reader->buffer = 0; @@ -572,12 +572,12 @@ static LODEPNG_INLINE unsigned ensureBits25(LodePNGBitReader * reader, size_t nb if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); reader->buffer >>= (reader->bp & 7u); - return reader->bp + nbits <= reader->bitsize; } + (void)nbits; } /*See ensureBits documentation above. This one ensures up to 32 bits */ -static LODEPNG_INLINE unsigned ensureBits32(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE void ensureBits32(LodePNGBitReader * reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; @@ -586,7 +586,6 @@ static LODEPNG_INLINE unsigned ensureBits32(LodePNGBitReader * reader, size_t nb ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); reader->buffer >>= (reader->bp & 7u); reader->buffer |= (((unsigned)reader->data[start + 4] << 24u) << (8u - (reader->bp & 7u))); - return 1; } else { reader->buffer = 0; @@ -595,55 +594,31 @@ static LODEPNG_INLINE unsigned ensureBits32(LodePNGBitReader * reader, size_t nb if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); if(start + 3u < size) reader->buffer |= ((unsigned)reader->data[start + 3] << 24u); reader->buffer >>= (reader->bp & 7u); - return reader->bp + nbits <= reader->bitsize; } + (void)nbits; } /* Get bits without advancing the bit pointer. Must have enough bits available with ensureBits. Max nbits is 31. */ -static unsigned peekBits(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE unsigned peekBits(LodePNGBitReader * reader, size_t nbits) { /* The shift allows nbits to be only up to 31. */ return reader->buffer & ((1u << nbits) - 1u); } /* Must have enough bits available with ensureBits */ -static void advanceBits(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE void advanceBits(LodePNGBitReader * reader, size_t nbits) { reader->buffer >>= nbits; reader->bp += nbits; } /* Must have enough bits available with ensureBits */ -static unsigned readBits(LodePNGBitReader * reader, size_t nbits) +static LODEPNG_INLINE unsigned readBits(LodePNGBitReader * reader, size_t nbits) { unsigned result = peekBits(reader, nbits); advanceBits(reader, nbits); return result; } - -#if 0 /*Disable because tests fail due to unused declaration*/ -/* Public for testing only. steps and result must have numsteps values. */ -static unsigned lode_png_test_bitreader(const unsigned char * data, size_t size, - size_t numsteps, const size_t * steps, unsigned * result) -{ - size_t i; - LodePNGBitReader reader; - unsigned error = LodePNGBitReader_init(&reader, data, size); - if(error) return 0; - for(i = 0; i < numsteps; i++) { - size_t step = steps[i]; - unsigned ok; - if(step > 25) ok = ensureBits32(&reader, step); - else if(step > 17) ok = ensureBits25(&reader, step); - else if(step > 9) ok = ensureBits17(&reader, step); - else ok = ensureBits9(&reader, step); - if(!ok) return 0; - result[i] = readBits(&reader, step); - } - return 1; -} -#endif - #endif /*LODEPNG_COMPILE_DECODER*/ static unsigned reverseBits(unsigned bits, unsigned num) @@ -759,7 +734,7 @@ static unsigned HuffmanTree_makeTable(HuffmanTree * tree) size = headsize; for(i = 0; i < headsize; ++i) { unsigned l = maxlens[i]; - if(l > FIRSTBITS) size += (1u << (l - FIRSTBITS)); + if(l > FIRSTBITS) size += (((size_t)1) << (l - FIRSTBITS)); } tree->table_len = (unsigned char *)lodepng_malloc(size * sizeof(*tree->table_len)); tree->table_value = (unsigned short *)lodepng_malloc(size * sizeof(*tree->table_value)); @@ -777,8 +752,8 @@ static unsigned HuffmanTree_makeTable(HuffmanTree * tree) unsigned l = maxlens[i]; if(l <= FIRSTBITS) continue; tree->table_len[i] = l; - tree->table_value[i] = pointer; - pointer += (1u << (l - FIRSTBITS)); + tree->table_value[i] = (unsigned short)pointer; + pointer += (((size_t)1) << (l - FIRSTBITS)); } lodepng_free(maxlens); @@ -786,10 +761,11 @@ static unsigned HuffmanTree_makeTable(HuffmanTree * tree) numpresent = 0; for(i = 0; i < tree->numcodes; ++i) { unsigned l = tree->lengths[i]; - unsigned symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/ - /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/ - unsigned reverse = reverseBits(symbol, l); + unsigned symbol, reverse; if(l == 0) continue; + symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/ + /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/ + reverse = reverseBits(symbol, l); numpresent++; if(l <= FIRSTBITS) { @@ -801,7 +777,7 @@ static unsigned HuffmanTree_makeTable(HuffmanTree * tree) unsigned index = reverse | (j << l); if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ tree->table_len[index] = l; - tree->table_value[index] = i; + tree->table_value[index] = (unsigned short)i; } } else { @@ -819,7 +795,7 @@ static unsigned HuffmanTree_makeTable(HuffmanTree * tree) unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */ unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS))); tree->table_len[index2] = l; - tree->table_value[index2] = i; + tree->table_value[index2] = (unsigned short)i; } } } @@ -1169,11 +1145,10 @@ static unsigned huffmanDecodeSymbol(LodePNGBitReader * reader, const HuffmanTree return value; } else { - unsigned index2; advanceBits(reader, FIRSTBITS); - index2 = value + peekBits(reader, l - FIRSTBITS); - advanceBits(reader, codetree->table_len[index2] - FIRSTBITS); - return codetree->table_value[index2]; + value += peekBits(reader, l - FIRSTBITS); + advanceBits(reader, codetree->table_len[value] - FIRSTBITS); + return codetree->table_value[value]; } } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -1208,7 +1183,8 @@ static unsigned getTreeInflateDynamic(HuffmanTree * tree_ll, HuffmanTree * tree_ unsigned * bitlen_cl = 0; HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ - if(!ensureBits17(reader, 14)) return 49; /*error: the bit pointer is or will go past the memory*/ + if(reader->bitsize - reader->bp < 14) return 49; /*error: the bit pointer is or will go past the memory*/ + ensureBits17(reader, 14); /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ HLIT = readBits(reader, 5) + 257; @@ -1338,6 +1314,11 @@ static unsigned inflateHuffmanBlock(ucvector * out, LodePNGBitReader * reader, unsigned error = 0; HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ HuffmanTree tree_d; /*the huffman tree for distance codes*/ + const size_t reserved_size = + 260; /* must be at least 258 for max length, and a few extra for adding a few extra literals */ + int done = 0; + + if(!ucvector_reserve(out, out->size + reserved_size)) return 83; /*alloc fail*/ HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); @@ -1345,14 +1326,21 @@ static unsigned inflateHuffmanBlock(ucvector * out, LodePNGBitReader * reader, if(btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d); else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader); - while(!error) { /*decode all symbols until end reached, breaks at end code*/ + + while(!error && !done) { /*decode all symbols until end reached, breaks at end code*/ /*code_ll is literal, length or end code*/ unsigned code_ll; - ensureBits25(reader, 20); /* up to 15 for the huffman symbol, up to 5 for the length extra bits */ + /* ensure enough bits for 2 huffman code reads (15 bits each): if the first is a literal, a second literal is read at once. This + appears to be slightly faster, than ensuring 20 bits here for 1 huffman symbol and the potential 5 extra bits for the length symbol.*/ + ensureBits32(reader, 30); code_ll = huffmanDecodeSymbol(reader, &tree_ll); + if(code_ll <= 255) { + /*slightly faster code path if multiple literals in a row*/ + out->data[out->size++] = (unsigned char)code_ll; + code_ll = huffmanDecodeSymbol(reader, &tree_ll); + } if(code_ll <= 255) { /*literal symbol*/ - if(!ucvector_resize(out, out->size + 1)) ERROR_BREAK(83 /*alloc fail*/); - out->data[out->size - 1] = (unsigned char)code_ll; + out->data[out->size++] = (unsigned char)code_ll; } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) { /*length code*/ unsigned code_d, distance; @@ -1366,6 +1354,7 @@ static unsigned inflateHuffmanBlock(ucvector * out, LodePNGBitReader * reader, numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; if(numextrabits_l != 0) { /* bits already ensured above */ + ensureBits25(reader, 5); length += readBits(reader, numextrabits_l); } @@ -1394,7 +1383,7 @@ static unsigned inflateHuffmanBlock(ucvector * out, LodePNGBitReader * reader, if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ backward = start - distance; - if(!ucvector_resize(out, out->size + length)) ERROR_BREAK(83 /*alloc fail*/); + out->size += length; if(distance < length) { size_t forward; lodepng_memcpy(out->data + start, out->data + backward, distance); @@ -1408,11 +1397,14 @@ static unsigned inflateHuffmanBlock(ucvector * out, LodePNGBitReader * reader, } } else if(code_ll == 256) { - break; /*end code, break the loop*/ + done = 1; /*end code, finish the loop*/ } else { /*if(code_ll == INVALIDSYMBOL)*/ ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ } + if(out->allocsize - out->size < reserved_size) { + if(!ucvector_reserve(out, out->size + reserved_size)) ERROR_BREAK(83); /*alloc fail*/ + } /*check if any of the ensureBits above went out of bounds*/ if(reader->bp > reader->bitsize) { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol @@ -1458,8 +1450,11 @@ static unsigned inflateNoCompression(ucvector * out, LodePNGBitReader * reader, /*read the literal data: LEN bytes are now stored in the out buffer*/ if(bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/ - lodepng_memcpy(out->data + out->size - LEN, reader->data + bytepos, LEN); - bytepos += LEN; + /*out->data can be NULL (when LEN is zero), and arithmetics on NULL ptr is undefined*/ + if(LEN) { + lodepng_memcpy(out->data + out->size - LEN, reader->data + bytepos, LEN); + bytepos += LEN; + } reader->bp = bytepos << 3u; @@ -1478,7 +1473,8 @@ static unsigned lodepng_inflatev(ucvector * out, while(!BFINAL) { unsigned BTYPE; - if(!ensureBits9(&reader, 3)) return 52; /*error, bit pointer will jump past memory*/ + if(reader.bitsize - reader.bp < 3) return 52; /*error, bit pointer will jump past memory*/ + ensureBits9(&reader, 3); BFINAL = readBits(&reader, 1); BTYPE = readBits(&reader, 2); @@ -1530,7 +1526,7 @@ static unsigned inflatev(ucvector * out, const unsigned char * in, size_t insize /* / Deflator (Compressor) / */ /* ////////////////////////////////////////////////////////////////////////// */ -static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; +static const unsigned MAX_SUPPORTED_DEFLATE_LENGTH = 258; /*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/ @@ -1936,7 +1932,7 @@ static unsigned deflateDynamic(LodePNGBitWriter * writer, Hash * hash, size_t datasize = dataend - datapos; /* - If we could call "bitlen_cl" the the code length code lengths ("clcl"), that is the bit lengths of codes to represent + If we could call "bitlen_cl" the code length code lengths ("clcl"), that is the bit lengths of codes to represent tree_cl in CLCL_ORDER, then due to the huffman compression of huffman tree representations ("two levels"), there are some analogies: bitlen_lld is to tree_cl what data is to tree_ll and tree_d. @@ -2433,7 +2429,7 @@ static unsigned zlib_decompress(unsigned char ** out, size_t * outsize, size_t e const unsigned char * in, size_t insize, const LodePNGDecompressSettings * settings) { if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ - LV_UNUSED(expected_size); + (void)expected_size; return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2505,56 +2501,332 @@ const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, /* ////////////////////////////////////////////////////////////////////////// */ -#ifndef LODEPNG_NO_COMPILE_CRC -/* CRC polynomial: 0xedb88320 */ -static unsigned lodepng_crc32_table[256] = { - 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, - 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, - 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, - 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, - 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, - 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, - 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, - 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, - 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, - 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, - 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, - 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, - 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, - 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, - 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, - 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, - 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, - 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, - 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, - 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, - 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, - 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, - 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, - 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, - 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, - 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, - 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, - 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, - 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, - 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, - 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, - 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u +#ifdef LODEPNG_COMPILE_CRC + +static const unsigned lodepng_crc32_table0[256] = { + 0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u, + 0x0edb8832u, 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u, + 0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu, 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u, + 0x136c9856u, 0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u, + 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu, + 0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u, + 0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, 0xb8bda50fu, + 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du, + 0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u, + 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u, + 0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u, + 0x65b0d9c6u, 0x12b7e950u, 0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u, + 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u, 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu, + 0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u, 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u, + 0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u, 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu, + 0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, 0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu, + 0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u, 0x73dc1683u, + 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u, + 0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u, + 0xfed41b76u, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u, + 0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu, + 0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u, + 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u, 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu, + 0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du, + 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au, 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u, + 0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u, + 0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u, + 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u, + 0xa00ae278u, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu, + 0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, 0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u, + 0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u, 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu, + 0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du }; -/*Return the CRC of the bytes buf[0..len-1].*/ +static const unsigned lodepng_crc32_table1[256] = { + 0x00000000u, 0x191b3141u, 0x32366282u, 0x2b2d53c3u, 0x646cc504u, 0x7d77f445u, 0x565aa786u, 0x4f4196c7u, + 0xc8d98a08u, 0xd1c2bb49u, 0xfaefe88au, 0xe3f4d9cbu, 0xacb54f0cu, 0xb5ae7e4du, 0x9e832d8eu, 0x87981ccfu, + 0x4ac21251u, 0x53d92310u, 0x78f470d3u, 0x61ef4192u, 0x2eaed755u, 0x37b5e614u, 0x1c98b5d7u, 0x05838496u, + 0x821b9859u, 0x9b00a918u, 0xb02dfadbu, 0xa936cb9au, 0xe6775d5du, 0xff6c6c1cu, 0xd4413fdfu, 0xcd5a0e9eu, + 0x958424a2u, 0x8c9f15e3u, 0xa7b24620u, 0xbea97761u, 0xf1e8e1a6u, 0xe8f3d0e7u, 0xc3de8324u, 0xdac5b265u, + 0x5d5daeaau, 0x44469febu, 0x6f6bcc28u, 0x7670fd69u, 0x39316baeu, 0x202a5aefu, 0x0b07092cu, 0x121c386du, + 0xdf4636f3u, 0xc65d07b2u, 0xed705471u, 0xf46b6530u, 0xbb2af3f7u, 0xa231c2b6u, 0x891c9175u, 0x9007a034u, + 0x179fbcfbu, 0x0e848dbau, 0x25a9de79u, 0x3cb2ef38u, 0x73f379ffu, 0x6ae848beu, 0x41c51b7du, 0x58de2a3cu, + 0xf0794f05u, 0xe9627e44u, 0xc24f2d87u, 0xdb541cc6u, 0x94158a01u, 0x8d0ebb40u, 0xa623e883u, 0xbf38d9c2u, + 0x38a0c50du, 0x21bbf44cu, 0x0a96a78fu, 0x138d96ceu, 0x5ccc0009u, 0x45d73148u, 0x6efa628bu, 0x77e153cau, + 0xbabb5d54u, 0xa3a06c15u, 0x888d3fd6u, 0x91960e97u, 0xded79850u, 0xc7cca911u, 0xece1fad2u, 0xf5facb93u, + 0x7262d75cu, 0x6b79e61du, 0x4054b5deu, 0x594f849fu, 0x160e1258u, 0x0f152319u, 0x243870dau, 0x3d23419bu, + 0x65fd6ba7u, 0x7ce65ae6u, 0x57cb0925u, 0x4ed03864u, 0x0191aea3u, 0x188a9fe2u, 0x33a7cc21u, 0x2abcfd60u, + 0xad24e1afu, 0xb43fd0eeu, 0x9f12832du, 0x8609b26cu, 0xc94824abu, 0xd05315eau, 0xfb7e4629u, 0xe2657768u, + 0x2f3f79f6u, 0x362448b7u, 0x1d091b74u, 0x04122a35u, 0x4b53bcf2u, 0x52488db3u, 0x7965de70u, 0x607eef31u, + 0xe7e6f3feu, 0xfefdc2bfu, 0xd5d0917cu, 0xcccba03du, 0x838a36fau, 0x9a9107bbu, 0xb1bc5478u, 0xa8a76539u, + 0x3b83984bu, 0x2298a90au, 0x09b5fac9u, 0x10aecb88u, 0x5fef5d4fu, 0x46f46c0eu, 0x6dd93fcdu, 0x74c20e8cu, + 0xf35a1243u, 0xea412302u, 0xc16c70c1u, 0xd8774180u, 0x9736d747u, 0x8e2de606u, 0xa500b5c5u, 0xbc1b8484u, + 0x71418a1au, 0x685abb5bu, 0x4377e898u, 0x5a6cd9d9u, 0x152d4f1eu, 0x0c367e5fu, 0x271b2d9cu, 0x3e001cddu, + 0xb9980012u, 0xa0833153u, 0x8bae6290u, 0x92b553d1u, 0xddf4c516u, 0xc4eff457u, 0xefc2a794u, 0xf6d996d5u, + 0xae07bce9u, 0xb71c8da8u, 0x9c31de6bu, 0x852aef2au, 0xca6b79edu, 0xd37048acu, 0xf85d1b6fu, 0xe1462a2eu, + 0x66de36e1u, 0x7fc507a0u, 0x54e85463u, 0x4df36522u, 0x02b2f3e5u, 0x1ba9c2a4u, 0x30849167u, 0x299fa026u, + 0xe4c5aeb8u, 0xfdde9ff9u, 0xd6f3cc3au, 0xcfe8fd7bu, 0x80a96bbcu, 0x99b25afdu, 0xb29f093eu, 0xab84387fu, + 0x2c1c24b0u, 0x350715f1u, 0x1e2a4632u, 0x07317773u, 0x4870e1b4u, 0x516bd0f5u, 0x7a468336u, 0x635db277u, + 0xcbfad74eu, 0xd2e1e60fu, 0xf9ccb5ccu, 0xe0d7848du, 0xaf96124au, 0xb68d230bu, 0x9da070c8u, 0x84bb4189u, + 0x03235d46u, 0x1a386c07u, 0x31153fc4u, 0x280e0e85u, 0x674f9842u, 0x7e54a903u, 0x5579fac0u, 0x4c62cb81u, + 0x8138c51fu, 0x9823f45eu, 0xb30ea79du, 0xaa1596dcu, 0xe554001bu, 0xfc4f315au, 0xd7626299u, 0xce7953d8u, + 0x49e14f17u, 0x50fa7e56u, 0x7bd72d95u, 0x62cc1cd4u, 0x2d8d8a13u, 0x3496bb52u, 0x1fbbe891u, 0x06a0d9d0u, + 0x5e7ef3ecu, 0x4765c2adu, 0x6c48916eu, 0x7553a02fu, 0x3a1236e8u, 0x230907a9u, 0x0824546au, 0x113f652bu, + 0x96a779e4u, 0x8fbc48a5u, 0xa4911b66u, 0xbd8a2a27u, 0xf2cbbce0u, 0xebd08da1u, 0xc0fdde62u, 0xd9e6ef23u, + 0x14bce1bdu, 0x0da7d0fcu, 0x268a833fu, 0x3f91b27eu, 0x70d024b9u, 0x69cb15f8u, 0x42e6463bu, 0x5bfd777au, + 0xdc656bb5u, 0xc57e5af4u, 0xee530937u, 0xf7483876u, 0xb809aeb1u, 0xa1129ff0u, 0x8a3fcc33u, 0x9324fd72u +}; + +static const unsigned lodepng_crc32_table2[256] = { + 0x00000000u, 0x01c26a37u, 0x0384d46eu, 0x0246be59u, 0x0709a8dcu, 0x06cbc2ebu, 0x048d7cb2u, 0x054f1685u, + 0x0e1351b8u, 0x0fd13b8fu, 0x0d9785d6u, 0x0c55efe1u, 0x091af964u, 0x08d89353u, 0x0a9e2d0au, 0x0b5c473du, + 0x1c26a370u, 0x1de4c947u, 0x1fa2771eu, 0x1e601d29u, 0x1b2f0bacu, 0x1aed619bu, 0x18abdfc2u, 0x1969b5f5u, + 0x1235f2c8u, 0x13f798ffu, 0x11b126a6u, 0x10734c91u, 0x153c5a14u, 0x14fe3023u, 0x16b88e7au, 0x177ae44du, + 0x384d46e0u, 0x398f2cd7u, 0x3bc9928eu, 0x3a0bf8b9u, 0x3f44ee3cu, 0x3e86840bu, 0x3cc03a52u, 0x3d025065u, + 0x365e1758u, 0x379c7d6fu, 0x35dac336u, 0x3418a901u, 0x3157bf84u, 0x3095d5b3u, 0x32d36beau, 0x331101ddu, + 0x246be590u, 0x25a98fa7u, 0x27ef31feu, 0x262d5bc9u, 0x23624d4cu, 0x22a0277bu, 0x20e69922u, 0x2124f315u, + 0x2a78b428u, 0x2bbade1fu, 0x29fc6046u, 0x283e0a71u, 0x2d711cf4u, 0x2cb376c3u, 0x2ef5c89au, 0x2f37a2adu, + 0x709a8dc0u, 0x7158e7f7u, 0x731e59aeu, 0x72dc3399u, 0x7793251cu, 0x76514f2bu, 0x7417f172u, 0x75d59b45u, + 0x7e89dc78u, 0x7f4bb64fu, 0x7d0d0816u, 0x7ccf6221u, 0x798074a4u, 0x78421e93u, 0x7a04a0cau, 0x7bc6cafdu, + 0x6cbc2eb0u, 0x6d7e4487u, 0x6f38fadeu, 0x6efa90e9u, 0x6bb5866cu, 0x6a77ec5bu, 0x68315202u, 0x69f33835u, + 0x62af7f08u, 0x636d153fu, 0x612bab66u, 0x60e9c151u, 0x65a6d7d4u, 0x6464bde3u, 0x662203bau, 0x67e0698du, + 0x48d7cb20u, 0x4915a117u, 0x4b531f4eu, 0x4a917579u, 0x4fde63fcu, 0x4e1c09cbu, 0x4c5ab792u, 0x4d98dda5u, + 0x46c49a98u, 0x4706f0afu, 0x45404ef6u, 0x448224c1u, 0x41cd3244u, 0x400f5873u, 0x4249e62au, 0x438b8c1du, + 0x54f16850u, 0x55330267u, 0x5775bc3eu, 0x56b7d609u, 0x53f8c08cu, 0x523aaabbu, 0x507c14e2u, 0x51be7ed5u, + 0x5ae239e8u, 0x5b2053dfu, 0x5966ed86u, 0x58a487b1u, 0x5deb9134u, 0x5c29fb03u, 0x5e6f455au, 0x5fad2f6du, + 0xe1351b80u, 0xe0f771b7u, 0xe2b1cfeeu, 0xe373a5d9u, 0xe63cb35cu, 0xe7fed96bu, 0xe5b86732u, 0xe47a0d05u, + 0xef264a38u, 0xeee4200fu, 0xeca29e56u, 0xed60f461u, 0xe82fe2e4u, 0xe9ed88d3u, 0xebab368au, 0xea695cbdu, + 0xfd13b8f0u, 0xfcd1d2c7u, 0xfe976c9eu, 0xff5506a9u, 0xfa1a102cu, 0xfbd87a1bu, 0xf99ec442u, 0xf85cae75u, + 0xf300e948u, 0xf2c2837fu, 0xf0843d26u, 0xf1465711u, 0xf4094194u, 0xf5cb2ba3u, 0xf78d95fau, 0xf64fffcdu, + 0xd9785d60u, 0xd8ba3757u, 0xdafc890eu, 0xdb3ee339u, 0xde71f5bcu, 0xdfb39f8bu, 0xddf521d2u, 0xdc374be5u, + 0xd76b0cd8u, 0xd6a966efu, 0xd4efd8b6u, 0xd52db281u, 0xd062a404u, 0xd1a0ce33u, 0xd3e6706au, 0xd2241a5du, + 0xc55efe10u, 0xc49c9427u, 0xc6da2a7eu, 0xc7184049u, 0xc25756ccu, 0xc3953cfbu, 0xc1d382a2u, 0xc011e895u, + 0xcb4dafa8u, 0xca8fc59fu, 0xc8c97bc6u, 0xc90b11f1u, 0xcc440774u, 0xcd866d43u, 0xcfc0d31au, 0xce02b92du, + 0x91af9640u, 0x906dfc77u, 0x922b422eu, 0x93e92819u, 0x96a63e9cu, 0x976454abu, 0x9522eaf2u, 0x94e080c5u, + 0x9fbcc7f8u, 0x9e7eadcfu, 0x9c381396u, 0x9dfa79a1u, 0x98b56f24u, 0x99770513u, 0x9b31bb4au, 0x9af3d17du, + 0x8d893530u, 0x8c4b5f07u, 0x8e0de15eu, 0x8fcf8b69u, 0x8a809decu, 0x8b42f7dbu, 0x89044982u, 0x88c623b5u, + 0x839a6488u, 0x82580ebfu, 0x801eb0e6u, 0x81dcdad1u, 0x8493cc54u, 0x8551a663u, 0x8717183au, 0x86d5720du, + 0xa9e2d0a0u, 0xa820ba97u, 0xaa6604ceu, 0xaba46ef9u, 0xaeeb787cu, 0xaf29124bu, 0xad6fac12u, 0xacadc625u, + 0xa7f18118u, 0xa633eb2fu, 0xa4755576u, 0xa5b73f41u, 0xa0f829c4u, 0xa13a43f3u, 0xa37cfdaau, 0xa2be979du, + 0xb5c473d0u, 0xb40619e7u, 0xb640a7beu, 0xb782cd89u, 0xb2cddb0cu, 0xb30fb13bu, 0xb1490f62u, 0xb08b6555u, + 0xbbd72268u, 0xba15485fu, 0xb853f606u, 0xb9919c31u, 0xbcde8ab4u, 0xbd1ce083u, 0xbf5a5edau, 0xbe9834edu +}; + +static const unsigned lodepng_crc32_table3[256] = { + 0x00000000u, 0xb8bc6765u, 0xaa09c88bu, 0x12b5afeeu, 0x8f629757u, 0x37def032u, 0x256b5fdcu, 0x9dd738b9u, + 0xc5b428efu, 0x7d084f8au, 0x6fbde064u, 0xd7018701u, 0x4ad6bfb8u, 0xf26ad8ddu, 0xe0df7733u, 0x58631056u, + 0x5019579fu, 0xe8a530fau, 0xfa109f14u, 0x42acf871u, 0xdf7bc0c8u, 0x67c7a7adu, 0x75720843u, 0xcdce6f26u, + 0x95ad7f70u, 0x2d111815u, 0x3fa4b7fbu, 0x8718d09eu, 0x1acfe827u, 0xa2738f42u, 0xb0c620acu, 0x087a47c9u, + 0xa032af3eu, 0x188ec85bu, 0x0a3b67b5u, 0xb28700d0u, 0x2f503869u, 0x97ec5f0cu, 0x8559f0e2u, 0x3de59787u, + 0x658687d1u, 0xdd3ae0b4u, 0xcf8f4f5au, 0x7733283fu, 0xeae41086u, 0x525877e3u, 0x40edd80du, 0xf851bf68u, + 0xf02bf8a1u, 0x48979fc4u, 0x5a22302au, 0xe29e574fu, 0x7f496ff6u, 0xc7f50893u, 0xd540a77du, 0x6dfcc018u, + 0x359fd04eu, 0x8d23b72bu, 0x9f9618c5u, 0x272a7fa0u, 0xbafd4719u, 0x0241207cu, 0x10f48f92u, 0xa848e8f7u, + 0x9b14583du, 0x23a83f58u, 0x311d90b6u, 0x89a1f7d3u, 0x1476cf6au, 0xaccaa80fu, 0xbe7f07e1u, 0x06c36084u, + 0x5ea070d2u, 0xe61c17b7u, 0xf4a9b859u, 0x4c15df3cu, 0xd1c2e785u, 0x697e80e0u, 0x7bcb2f0eu, 0xc377486bu, + 0xcb0d0fa2u, 0x73b168c7u, 0x6104c729u, 0xd9b8a04cu, 0x446f98f5u, 0xfcd3ff90u, 0xee66507eu, 0x56da371bu, + 0x0eb9274du, 0xb6054028u, 0xa4b0efc6u, 0x1c0c88a3u, 0x81dbb01au, 0x3967d77fu, 0x2bd27891u, 0x936e1ff4u, + 0x3b26f703u, 0x839a9066u, 0x912f3f88u, 0x299358edu, 0xb4446054u, 0x0cf80731u, 0x1e4da8dfu, 0xa6f1cfbau, + 0xfe92dfecu, 0x462eb889u, 0x549b1767u, 0xec277002u, 0x71f048bbu, 0xc94c2fdeu, 0xdbf98030u, 0x6345e755u, + 0x6b3fa09cu, 0xd383c7f9u, 0xc1366817u, 0x798a0f72u, 0xe45d37cbu, 0x5ce150aeu, 0x4e54ff40u, 0xf6e89825u, + 0xae8b8873u, 0x1637ef16u, 0x048240f8u, 0xbc3e279du, 0x21e91f24u, 0x99557841u, 0x8be0d7afu, 0x335cb0cau, + 0xed59b63bu, 0x55e5d15eu, 0x47507eb0u, 0xffec19d5u, 0x623b216cu, 0xda874609u, 0xc832e9e7u, 0x708e8e82u, + 0x28ed9ed4u, 0x9051f9b1u, 0x82e4565fu, 0x3a58313au, 0xa78f0983u, 0x1f336ee6u, 0x0d86c108u, 0xb53aa66du, + 0xbd40e1a4u, 0x05fc86c1u, 0x1749292fu, 0xaff54e4au, 0x322276f3u, 0x8a9e1196u, 0x982bbe78u, 0x2097d91du, + 0x78f4c94bu, 0xc048ae2eu, 0xd2fd01c0u, 0x6a4166a5u, 0xf7965e1cu, 0x4f2a3979u, 0x5d9f9697u, 0xe523f1f2u, + 0x4d6b1905u, 0xf5d77e60u, 0xe762d18eu, 0x5fdeb6ebu, 0xc2098e52u, 0x7ab5e937u, 0x680046d9u, 0xd0bc21bcu, + 0x88df31eau, 0x3063568fu, 0x22d6f961u, 0x9a6a9e04u, 0x07bda6bdu, 0xbf01c1d8u, 0xadb46e36u, 0x15080953u, + 0x1d724e9au, 0xa5ce29ffu, 0xb77b8611u, 0x0fc7e174u, 0x9210d9cdu, 0x2aacbea8u, 0x38191146u, 0x80a57623u, + 0xd8c66675u, 0x607a0110u, 0x72cfaefeu, 0xca73c99bu, 0x57a4f122u, 0xef189647u, 0xfdad39a9u, 0x45115eccu, + 0x764dee06u, 0xcef18963u, 0xdc44268du, 0x64f841e8u, 0xf92f7951u, 0x41931e34u, 0x5326b1dau, 0xeb9ad6bfu, + 0xb3f9c6e9u, 0x0b45a18cu, 0x19f00e62u, 0xa14c6907u, 0x3c9b51beu, 0x842736dbu, 0x96929935u, 0x2e2efe50u, + 0x2654b999u, 0x9ee8defcu, 0x8c5d7112u, 0x34e11677u, 0xa9362eceu, 0x118a49abu, 0x033fe645u, 0xbb838120u, + 0xe3e09176u, 0x5b5cf613u, 0x49e959fdu, 0xf1553e98u, 0x6c820621u, 0xd43e6144u, 0xc68bceaau, 0x7e37a9cfu, + 0xd67f4138u, 0x6ec3265du, 0x7c7689b3u, 0xc4caeed6u, 0x591dd66fu, 0xe1a1b10au, 0xf3141ee4u, 0x4ba87981u, + 0x13cb69d7u, 0xab770eb2u, 0xb9c2a15cu, 0x017ec639u, 0x9ca9fe80u, 0x241599e5u, 0x36a0360bu, 0x8e1c516eu, + 0x866616a7u, 0x3eda71c2u, 0x2c6fde2cu, 0x94d3b949u, 0x090481f0u, 0xb1b8e695u, 0xa30d497bu, 0x1bb12e1eu, + 0x43d23e48u, 0xfb6e592du, 0xe9dbf6c3u, 0x516791a6u, 0xccb0a91fu, 0x740cce7au, 0x66b96194u, 0xde0506f1u +}; + +static const unsigned lodepng_crc32_table4[256] = { + 0x00000000u, 0x3d6029b0u, 0x7ac05360u, 0x47a07ad0u, 0xf580a6c0u, 0xc8e08f70u, 0x8f40f5a0u, 0xb220dc10u, + 0x30704bc1u, 0x0d106271u, 0x4ab018a1u, 0x77d03111u, 0xc5f0ed01u, 0xf890c4b1u, 0xbf30be61u, 0x825097d1u, + 0x60e09782u, 0x5d80be32u, 0x1a20c4e2u, 0x2740ed52u, 0x95603142u, 0xa80018f2u, 0xefa06222u, 0xd2c04b92u, + 0x5090dc43u, 0x6df0f5f3u, 0x2a508f23u, 0x1730a693u, 0xa5107a83u, 0x98705333u, 0xdfd029e3u, 0xe2b00053u, + 0xc1c12f04u, 0xfca106b4u, 0xbb017c64u, 0x866155d4u, 0x344189c4u, 0x0921a074u, 0x4e81daa4u, 0x73e1f314u, + 0xf1b164c5u, 0xccd14d75u, 0x8b7137a5u, 0xb6111e15u, 0x0431c205u, 0x3951ebb5u, 0x7ef19165u, 0x4391b8d5u, + 0xa121b886u, 0x9c419136u, 0xdbe1ebe6u, 0xe681c256u, 0x54a11e46u, 0x69c137f6u, 0x2e614d26u, 0x13016496u, + 0x9151f347u, 0xac31daf7u, 0xeb91a027u, 0xd6f18997u, 0x64d15587u, 0x59b17c37u, 0x1e1106e7u, 0x23712f57u, + 0x58f35849u, 0x659371f9u, 0x22330b29u, 0x1f532299u, 0xad73fe89u, 0x9013d739u, 0xd7b3ade9u, 0xead38459u, + 0x68831388u, 0x55e33a38u, 0x124340e8u, 0x2f236958u, 0x9d03b548u, 0xa0639cf8u, 0xe7c3e628u, 0xdaa3cf98u, + 0x3813cfcbu, 0x0573e67bu, 0x42d39cabu, 0x7fb3b51bu, 0xcd93690bu, 0xf0f340bbu, 0xb7533a6bu, 0x8a3313dbu, + 0x0863840au, 0x3503adbau, 0x72a3d76au, 0x4fc3fedau, 0xfde322cau, 0xc0830b7au, 0x872371aau, 0xba43581au, + 0x9932774du, 0xa4525efdu, 0xe3f2242du, 0xde920d9du, 0x6cb2d18du, 0x51d2f83du, 0x167282edu, 0x2b12ab5du, + 0xa9423c8cu, 0x9422153cu, 0xd3826fecu, 0xeee2465cu, 0x5cc29a4cu, 0x61a2b3fcu, 0x2602c92cu, 0x1b62e09cu, + 0xf9d2e0cfu, 0xc4b2c97fu, 0x8312b3afu, 0xbe729a1fu, 0x0c52460fu, 0x31326fbfu, 0x7692156fu, 0x4bf23cdfu, + 0xc9a2ab0eu, 0xf4c282beu, 0xb362f86eu, 0x8e02d1deu, 0x3c220dceu, 0x0142247eu, 0x46e25eaeu, 0x7b82771eu, + 0xb1e6b092u, 0x8c869922u, 0xcb26e3f2u, 0xf646ca42u, 0x44661652u, 0x79063fe2u, 0x3ea64532u, 0x03c66c82u, + 0x8196fb53u, 0xbcf6d2e3u, 0xfb56a833u, 0xc6368183u, 0x74165d93u, 0x49767423u, 0x0ed60ef3u, 0x33b62743u, + 0xd1062710u, 0xec660ea0u, 0xabc67470u, 0x96a65dc0u, 0x248681d0u, 0x19e6a860u, 0x5e46d2b0u, 0x6326fb00u, + 0xe1766cd1u, 0xdc164561u, 0x9bb63fb1u, 0xa6d61601u, 0x14f6ca11u, 0x2996e3a1u, 0x6e369971u, 0x5356b0c1u, + 0x70279f96u, 0x4d47b626u, 0x0ae7ccf6u, 0x3787e546u, 0x85a73956u, 0xb8c710e6u, 0xff676a36u, 0xc2074386u, + 0x4057d457u, 0x7d37fde7u, 0x3a978737u, 0x07f7ae87u, 0xb5d77297u, 0x88b75b27u, 0xcf1721f7u, 0xf2770847u, + 0x10c70814u, 0x2da721a4u, 0x6a075b74u, 0x576772c4u, 0xe547aed4u, 0xd8278764u, 0x9f87fdb4u, 0xa2e7d404u, + 0x20b743d5u, 0x1dd76a65u, 0x5a7710b5u, 0x67173905u, 0xd537e515u, 0xe857cca5u, 0xaff7b675u, 0x92979fc5u, + 0xe915e8dbu, 0xd475c16bu, 0x93d5bbbbu, 0xaeb5920bu, 0x1c954e1bu, 0x21f567abu, 0x66551d7bu, 0x5b3534cbu, + 0xd965a31au, 0xe4058aaau, 0xa3a5f07au, 0x9ec5d9cau, 0x2ce505dau, 0x11852c6au, 0x562556bau, 0x6b457f0au, + 0x89f57f59u, 0xb49556e9u, 0xf3352c39u, 0xce550589u, 0x7c75d999u, 0x4115f029u, 0x06b58af9u, 0x3bd5a349u, + 0xb9853498u, 0x84e51d28u, 0xc34567f8u, 0xfe254e48u, 0x4c059258u, 0x7165bbe8u, 0x36c5c138u, 0x0ba5e888u, + 0x28d4c7dfu, 0x15b4ee6fu, 0x521494bfu, 0x6f74bd0fu, 0xdd54611fu, 0xe03448afu, 0xa794327fu, 0x9af41bcfu, + 0x18a48c1eu, 0x25c4a5aeu, 0x6264df7eu, 0x5f04f6ceu, 0xed242adeu, 0xd044036eu, 0x97e479beu, 0xaa84500eu, + 0x4834505du, 0x755479edu, 0x32f4033du, 0x0f942a8du, 0xbdb4f69du, 0x80d4df2du, 0xc774a5fdu, 0xfa148c4du, + 0x78441b9cu, 0x4524322cu, 0x028448fcu, 0x3fe4614cu, 0x8dc4bd5cu, 0xb0a494ecu, 0xf704ee3cu, 0xca64c78cu +}; + +static const unsigned lodepng_crc32_table5[256] = { + 0x00000000u, 0xcb5cd3a5u, 0x4dc8a10bu, 0x869472aeu, 0x9b914216u, 0x50cd91b3u, 0xd659e31du, 0x1d0530b8u, + 0xec53826du, 0x270f51c8u, 0xa19b2366u, 0x6ac7f0c3u, 0x77c2c07bu, 0xbc9e13deu, 0x3a0a6170u, 0xf156b2d5u, + 0x03d6029bu, 0xc88ad13eu, 0x4e1ea390u, 0x85427035u, 0x9847408du, 0x531b9328u, 0xd58fe186u, 0x1ed33223u, + 0xef8580f6u, 0x24d95353u, 0xa24d21fdu, 0x6911f258u, 0x7414c2e0u, 0xbf481145u, 0x39dc63ebu, 0xf280b04eu, + 0x07ac0536u, 0xccf0d693u, 0x4a64a43du, 0x81387798u, 0x9c3d4720u, 0x57619485u, 0xd1f5e62bu, 0x1aa9358eu, + 0xebff875bu, 0x20a354feu, 0xa6372650u, 0x6d6bf5f5u, 0x706ec54du, 0xbb3216e8u, 0x3da66446u, 0xf6fab7e3u, + 0x047a07adu, 0xcf26d408u, 0x49b2a6a6u, 0x82ee7503u, 0x9feb45bbu, 0x54b7961eu, 0xd223e4b0u, 0x197f3715u, + 0xe82985c0u, 0x23755665u, 0xa5e124cbu, 0x6ebdf76eu, 0x73b8c7d6u, 0xb8e41473u, 0x3e7066ddu, 0xf52cb578u, + 0x0f580a6cu, 0xc404d9c9u, 0x4290ab67u, 0x89cc78c2u, 0x94c9487au, 0x5f959bdfu, 0xd901e971u, 0x125d3ad4u, + 0xe30b8801u, 0x28575ba4u, 0xaec3290au, 0x659ffaafu, 0x789aca17u, 0xb3c619b2u, 0x35526b1cu, 0xfe0eb8b9u, + 0x0c8e08f7u, 0xc7d2db52u, 0x4146a9fcu, 0x8a1a7a59u, 0x971f4ae1u, 0x5c439944u, 0xdad7ebeau, 0x118b384fu, + 0xe0dd8a9au, 0x2b81593fu, 0xad152b91u, 0x6649f834u, 0x7b4cc88cu, 0xb0101b29u, 0x36846987u, 0xfdd8ba22u, + 0x08f40f5au, 0xc3a8dcffu, 0x453cae51u, 0x8e607df4u, 0x93654d4cu, 0x58399ee9u, 0xdeadec47u, 0x15f13fe2u, + 0xe4a78d37u, 0x2ffb5e92u, 0xa96f2c3cu, 0x6233ff99u, 0x7f36cf21u, 0xb46a1c84u, 0x32fe6e2au, 0xf9a2bd8fu, + 0x0b220dc1u, 0xc07ede64u, 0x46eaaccau, 0x8db67f6fu, 0x90b34fd7u, 0x5bef9c72u, 0xdd7beedcu, 0x16273d79u, + 0xe7718facu, 0x2c2d5c09u, 0xaab92ea7u, 0x61e5fd02u, 0x7ce0cdbau, 0xb7bc1e1fu, 0x31286cb1u, 0xfa74bf14u, + 0x1eb014d8u, 0xd5ecc77du, 0x5378b5d3u, 0x98246676u, 0x852156ceu, 0x4e7d856bu, 0xc8e9f7c5u, 0x03b52460u, + 0xf2e396b5u, 0x39bf4510u, 0xbf2b37beu, 0x7477e41bu, 0x6972d4a3u, 0xa22e0706u, 0x24ba75a8u, 0xefe6a60du, + 0x1d661643u, 0xd63ac5e6u, 0x50aeb748u, 0x9bf264edu, 0x86f75455u, 0x4dab87f0u, 0xcb3ff55eu, 0x006326fbu, + 0xf135942eu, 0x3a69478bu, 0xbcfd3525u, 0x77a1e680u, 0x6aa4d638u, 0xa1f8059du, 0x276c7733u, 0xec30a496u, + 0x191c11eeu, 0xd240c24bu, 0x54d4b0e5u, 0x9f886340u, 0x828d53f8u, 0x49d1805du, 0xcf45f2f3u, 0x04192156u, + 0xf54f9383u, 0x3e134026u, 0xb8873288u, 0x73dbe12du, 0x6eded195u, 0xa5820230u, 0x2316709eu, 0xe84aa33bu, + 0x1aca1375u, 0xd196c0d0u, 0x5702b27eu, 0x9c5e61dbu, 0x815b5163u, 0x4a0782c6u, 0xcc93f068u, 0x07cf23cdu, + 0xf6999118u, 0x3dc542bdu, 0xbb513013u, 0x700de3b6u, 0x6d08d30eu, 0xa65400abu, 0x20c07205u, 0xeb9ca1a0u, + 0x11e81eb4u, 0xdab4cd11u, 0x5c20bfbfu, 0x977c6c1au, 0x8a795ca2u, 0x41258f07u, 0xc7b1fda9u, 0x0ced2e0cu, + 0xfdbb9cd9u, 0x36e74f7cu, 0xb0733dd2u, 0x7b2fee77u, 0x662adecfu, 0xad760d6au, 0x2be27fc4u, 0xe0beac61u, + 0x123e1c2fu, 0xd962cf8au, 0x5ff6bd24u, 0x94aa6e81u, 0x89af5e39u, 0x42f38d9cu, 0xc467ff32u, 0x0f3b2c97u, + 0xfe6d9e42u, 0x35314de7u, 0xb3a53f49u, 0x78f9ececu, 0x65fcdc54u, 0xaea00ff1u, 0x28347d5fu, 0xe368aefau, + 0x16441b82u, 0xdd18c827u, 0x5b8cba89u, 0x90d0692cu, 0x8dd55994u, 0x46898a31u, 0xc01df89fu, 0x0b412b3au, + 0xfa1799efu, 0x314b4a4au, 0xb7df38e4u, 0x7c83eb41u, 0x6186dbf9u, 0xaada085cu, 0x2c4e7af2u, 0xe712a957u, + 0x15921919u, 0xdececabcu, 0x585ab812u, 0x93066bb7u, 0x8e035b0fu, 0x455f88aau, 0xc3cbfa04u, 0x089729a1u, + 0xf9c19b74u, 0x329d48d1u, 0xb4093a7fu, 0x7f55e9dau, 0x6250d962u, 0xa90c0ac7u, 0x2f987869u, 0xe4c4abccu +}; + +static const unsigned lodepng_crc32_table6[256] = { + 0x00000000u, 0xa6770bb4u, 0x979f1129u, 0x31e81a9du, 0xf44f2413u, 0x52382fa7u, 0x63d0353au, 0xc5a73e8eu, + 0x33ef4e67u, 0x959845d3u, 0xa4705f4eu, 0x020754fau, 0xc7a06a74u, 0x61d761c0u, 0x503f7b5du, 0xf64870e9u, + 0x67de9cceu, 0xc1a9977au, 0xf0418de7u, 0x56368653u, 0x9391b8ddu, 0x35e6b369u, 0x040ea9f4u, 0xa279a240u, + 0x5431d2a9u, 0xf246d91du, 0xc3aec380u, 0x65d9c834u, 0xa07ef6bau, 0x0609fd0eu, 0x37e1e793u, 0x9196ec27u, + 0xcfbd399cu, 0x69ca3228u, 0x582228b5u, 0xfe552301u, 0x3bf21d8fu, 0x9d85163bu, 0xac6d0ca6u, 0x0a1a0712u, + 0xfc5277fbu, 0x5a257c4fu, 0x6bcd66d2u, 0xcdba6d66u, 0x081d53e8u, 0xae6a585cu, 0x9f8242c1u, 0x39f54975u, + 0xa863a552u, 0x0e14aee6u, 0x3ffcb47bu, 0x998bbfcfu, 0x5c2c8141u, 0xfa5b8af5u, 0xcbb39068u, 0x6dc49bdcu, + 0x9b8ceb35u, 0x3dfbe081u, 0x0c13fa1cu, 0xaa64f1a8u, 0x6fc3cf26u, 0xc9b4c492u, 0xf85cde0fu, 0x5e2bd5bbu, + 0x440b7579u, 0xe27c7ecdu, 0xd3946450u, 0x75e36fe4u, 0xb044516au, 0x16335adeu, 0x27db4043u, 0x81ac4bf7u, + 0x77e43b1eu, 0xd19330aau, 0xe07b2a37u, 0x460c2183u, 0x83ab1f0du, 0x25dc14b9u, 0x14340e24u, 0xb2430590u, + 0x23d5e9b7u, 0x85a2e203u, 0xb44af89eu, 0x123df32au, 0xd79acda4u, 0x71edc610u, 0x4005dc8du, 0xe672d739u, + 0x103aa7d0u, 0xb64dac64u, 0x87a5b6f9u, 0x21d2bd4du, 0xe47583c3u, 0x42028877u, 0x73ea92eau, 0xd59d995eu, + 0x8bb64ce5u, 0x2dc14751u, 0x1c295dccu, 0xba5e5678u, 0x7ff968f6u, 0xd98e6342u, 0xe86679dfu, 0x4e11726bu, + 0xb8590282u, 0x1e2e0936u, 0x2fc613abu, 0x89b1181fu, 0x4c162691u, 0xea612d25u, 0xdb8937b8u, 0x7dfe3c0cu, + 0xec68d02bu, 0x4a1fdb9fu, 0x7bf7c102u, 0xdd80cab6u, 0x1827f438u, 0xbe50ff8cu, 0x8fb8e511u, 0x29cfeea5u, + 0xdf879e4cu, 0x79f095f8u, 0x48188f65u, 0xee6f84d1u, 0x2bc8ba5fu, 0x8dbfb1ebu, 0xbc57ab76u, 0x1a20a0c2u, + 0x8816eaf2u, 0x2e61e146u, 0x1f89fbdbu, 0xb9fef06fu, 0x7c59cee1u, 0xda2ec555u, 0xebc6dfc8u, 0x4db1d47cu, + 0xbbf9a495u, 0x1d8eaf21u, 0x2c66b5bcu, 0x8a11be08u, 0x4fb68086u, 0xe9c18b32u, 0xd82991afu, 0x7e5e9a1bu, + 0xefc8763cu, 0x49bf7d88u, 0x78576715u, 0xde206ca1u, 0x1b87522fu, 0xbdf0599bu, 0x8c184306u, 0x2a6f48b2u, + 0xdc27385bu, 0x7a5033efu, 0x4bb82972u, 0xedcf22c6u, 0x28681c48u, 0x8e1f17fcu, 0xbff70d61u, 0x198006d5u, + 0x47abd36eu, 0xe1dcd8dau, 0xd034c247u, 0x7643c9f3u, 0xb3e4f77du, 0x1593fcc9u, 0x247be654u, 0x820cede0u, + 0x74449d09u, 0xd23396bdu, 0xe3db8c20u, 0x45ac8794u, 0x800bb91au, 0x267cb2aeu, 0x1794a833u, 0xb1e3a387u, + 0x20754fa0u, 0x86024414u, 0xb7ea5e89u, 0x119d553du, 0xd43a6bb3u, 0x724d6007u, 0x43a57a9au, 0xe5d2712eu, + 0x139a01c7u, 0xb5ed0a73u, 0x840510eeu, 0x22721b5au, 0xe7d525d4u, 0x41a22e60u, 0x704a34fdu, 0xd63d3f49u, + 0xcc1d9f8bu, 0x6a6a943fu, 0x5b828ea2u, 0xfdf58516u, 0x3852bb98u, 0x9e25b02cu, 0xafcdaab1u, 0x09baa105u, + 0xfff2d1ecu, 0x5985da58u, 0x686dc0c5u, 0xce1acb71u, 0x0bbdf5ffu, 0xadcafe4bu, 0x9c22e4d6u, 0x3a55ef62u, + 0xabc30345u, 0x0db408f1u, 0x3c5c126cu, 0x9a2b19d8u, 0x5f8c2756u, 0xf9fb2ce2u, 0xc813367fu, 0x6e643dcbu, + 0x982c4d22u, 0x3e5b4696u, 0x0fb35c0bu, 0xa9c457bfu, 0x6c636931u, 0xca146285u, 0xfbfc7818u, 0x5d8b73acu, + 0x03a0a617u, 0xa5d7ada3u, 0x943fb73eu, 0x3248bc8au, 0xf7ef8204u, 0x519889b0u, 0x6070932du, 0xc6079899u, + 0x304fe870u, 0x9638e3c4u, 0xa7d0f959u, 0x01a7f2edu, 0xc400cc63u, 0x6277c7d7u, 0x539fdd4au, 0xf5e8d6feu, + 0x647e3ad9u, 0xc209316du, 0xf3e12bf0u, 0x55962044u, 0x90311ecau, 0x3646157eu, 0x07ae0fe3u, 0xa1d90457u, + 0x579174beu, 0xf1e67f0au, 0xc00e6597u, 0x66796e23u, 0xa3de50adu, 0x05a95b19u, 0x34414184u, 0x92364a30u +}; + +static const unsigned lodepng_crc32_table7[256] = { + 0x00000000u, 0xccaa009eu, 0x4225077du, 0x8e8f07e3u, 0x844a0efau, 0x48e00e64u, 0xc66f0987u, 0x0ac50919u, + 0xd3e51bb5u, 0x1f4f1b2bu, 0x91c01cc8u, 0x5d6a1c56u, 0x57af154fu, 0x9b0515d1u, 0x158a1232u, 0xd92012acu, + 0x7cbb312bu, 0xb01131b5u, 0x3e9e3656u, 0xf23436c8u, 0xf8f13fd1u, 0x345b3f4fu, 0xbad438acu, 0x767e3832u, + 0xaf5e2a9eu, 0x63f42a00u, 0xed7b2de3u, 0x21d12d7du, 0x2b142464u, 0xe7be24fau, 0x69312319u, 0xa59b2387u, + 0xf9766256u, 0x35dc62c8u, 0xbb53652bu, 0x77f965b5u, 0x7d3c6cacu, 0xb1966c32u, 0x3f196bd1u, 0xf3b36b4fu, + 0x2a9379e3u, 0xe639797du, 0x68b67e9eu, 0xa41c7e00u, 0xaed97719u, 0x62737787u, 0xecfc7064u, 0x205670fau, + 0x85cd537du, 0x496753e3u, 0xc7e85400u, 0x0b42549eu, 0x01875d87u, 0xcd2d5d19u, 0x43a25afau, 0x8f085a64u, + 0x562848c8u, 0x9a824856u, 0x140d4fb5u, 0xd8a74f2bu, 0xd2624632u, 0x1ec846acu, 0x9047414fu, 0x5ced41d1u, + 0x299dc2edu, 0xe537c273u, 0x6bb8c590u, 0xa712c50eu, 0xadd7cc17u, 0x617dcc89u, 0xeff2cb6au, 0x2358cbf4u, + 0xfa78d958u, 0x36d2d9c6u, 0xb85dde25u, 0x74f7debbu, 0x7e32d7a2u, 0xb298d73cu, 0x3c17d0dfu, 0xf0bdd041u, + 0x5526f3c6u, 0x998cf358u, 0x1703f4bbu, 0xdba9f425u, 0xd16cfd3cu, 0x1dc6fda2u, 0x9349fa41u, 0x5fe3fadfu, + 0x86c3e873u, 0x4a69e8edu, 0xc4e6ef0eu, 0x084cef90u, 0x0289e689u, 0xce23e617u, 0x40ace1f4u, 0x8c06e16au, + 0xd0eba0bbu, 0x1c41a025u, 0x92cea7c6u, 0x5e64a758u, 0x54a1ae41u, 0x980baedfu, 0x1684a93cu, 0xda2ea9a2u, + 0x030ebb0eu, 0xcfa4bb90u, 0x412bbc73u, 0x8d81bcedu, 0x8744b5f4u, 0x4beeb56au, 0xc561b289u, 0x09cbb217u, + 0xac509190u, 0x60fa910eu, 0xee7596edu, 0x22df9673u, 0x281a9f6au, 0xe4b09ff4u, 0x6a3f9817u, 0xa6959889u, + 0x7fb58a25u, 0xb31f8abbu, 0x3d908d58u, 0xf13a8dc6u, 0xfbff84dfu, 0x37558441u, 0xb9da83a2u, 0x7570833cu, + 0x533b85dau, 0x9f918544u, 0x111e82a7u, 0xddb48239u, 0xd7718b20u, 0x1bdb8bbeu, 0x95548c5du, 0x59fe8cc3u, + 0x80de9e6fu, 0x4c749ef1u, 0xc2fb9912u, 0x0e51998cu, 0x04949095u, 0xc83e900bu, 0x46b197e8u, 0x8a1b9776u, + 0x2f80b4f1u, 0xe32ab46fu, 0x6da5b38cu, 0xa10fb312u, 0xabcaba0bu, 0x6760ba95u, 0xe9efbd76u, 0x2545bde8u, + 0xfc65af44u, 0x30cfafdau, 0xbe40a839u, 0x72eaa8a7u, 0x782fa1beu, 0xb485a120u, 0x3a0aa6c3u, 0xf6a0a65du, + 0xaa4de78cu, 0x66e7e712u, 0xe868e0f1u, 0x24c2e06fu, 0x2e07e976u, 0xe2ade9e8u, 0x6c22ee0bu, 0xa088ee95u, + 0x79a8fc39u, 0xb502fca7u, 0x3b8dfb44u, 0xf727fbdau, 0xfde2f2c3u, 0x3148f25du, 0xbfc7f5beu, 0x736df520u, + 0xd6f6d6a7u, 0x1a5cd639u, 0x94d3d1dau, 0x5879d144u, 0x52bcd85du, 0x9e16d8c3u, 0x1099df20u, 0xdc33dfbeu, + 0x0513cd12u, 0xc9b9cd8cu, 0x4736ca6fu, 0x8b9ccaf1u, 0x8159c3e8u, 0x4df3c376u, 0xc37cc495u, 0x0fd6c40bu, + 0x7aa64737u, 0xb60c47a9u, 0x3883404au, 0xf42940d4u, 0xfeec49cdu, 0x32464953u, 0xbcc94eb0u, 0x70634e2eu, + 0xa9435c82u, 0x65e95c1cu, 0xeb665bffu, 0x27cc5b61u, 0x2d095278u, 0xe1a352e6u, 0x6f2c5505u, 0xa386559bu, + 0x061d761cu, 0xcab77682u, 0x44387161u, 0x889271ffu, 0x825778e6u, 0x4efd7878u, 0xc0727f9bu, 0x0cd87f05u, + 0xd5f86da9u, 0x19526d37u, 0x97dd6ad4u, 0x5b776a4au, 0x51b26353u, 0x9d1863cdu, 0x1397642eu, 0xdf3d64b0u, + 0x83d02561u, 0x4f7a25ffu, 0xc1f5221cu, 0x0d5f2282u, 0x079a2b9bu, 0xcb302b05u, 0x45bf2ce6u, 0x89152c78u, + 0x50353ed4u, 0x9c9f3e4au, 0x121039a9u, 0xdeba3937u, 0xd47f302eu, 0x18d530b0u, 0x965a3753u, 0x5af037cdu, + 0xff6b144au, 0x33c114d4u, 0xbd4e1337u, 0x71e413a9u, 0x7b211ab0u, 0xb78b1a2eu, 0x39041dcdu, 0xf5ae1d53u, + 0x2c8e0fffu, 0xe0240f61u, 0x6eab0882u, 0xa201081cu, 0xa8c40105u, 0x646e019bu, 0xeae10678u, 0x264b06e6u +}; + +/* Computes the cyclic redundancy check as used by PNG chunks*/ unsigned lodepng_crc32(const unsigned char * data, size_t length) { + /*Using the Slicing by Eight algorithm*/ unsigned r = 0xffffffffu; - size_t i; - for(i = 0; i < length; ++i) { - r = lodepng_crc32_table[(r ^ data[i]) & 0xffu] ^ (r >> 8u); + while(length >= 8) { + r = lodepng_crc32_table7[(data[0] ^ (r & 0xffu))] ^ + lodepng_crc32_table6[(data[1] ^ ((r >> 8) & 0xffu))] ^ + lodepng_crc32_table5[(data[2] ^ ((r >> 16) & 0xffu))] ^ + lodepng_crc32_table4[(data[3] ^ ((r >> 24) & 0xffu))] ^ + lodepng_crc32_table3[data[4]] ^ + lodepng_crc32_table2[data[5]] ^ + lodepng_crc32_table1[data[6]] ^ + lodepng_crc32_table0[data[7]]; + data += 8; + length -= 8; + } + while(length--) { + r = lodepng_crc32_table0[(r ^ *data++) & 0xffu] ^ (r >> 8); } return r ^ 0xffffffffu; } -#else /* !LODEPNG_NO_COMPILE_CRC */ +#else /* LODEPNG_COMPILE_CRC */ +/*in this case, the function is only declared here, and must be defined externally +so that it will be linked in. + +Example implementation that uses a much smaller lookup table for memory constrained cases: + +unsigned lodepng_crc32(const unsigned char* data, size_t length) { + unsigned r = 0xffffffffu; + static const unsigned table[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + while(length--) { + r = table[(r ^ *data) & 0xf] ^ (r >> 4); + r = table[(r ^ (*data >> 4)) & 0xf] ^ (r >> 4); + data++; + } + return r ^ 0xffffffffu; +} +*/ unsigned lodepng_crc32(const unsigned char * data, size_t length); -#endif /* !LODEPNG_NO_COMPILE_CRC */ +#endif /* LODEPNG_COMPILE_CRC */ /* ////////////////////////////////////////////////////////////////////////// */ /* / Reading and writing PNG color channel bits / */ @@ -2596,7 +2868,7 @@ static void setBitOfReversedStream(size_t * bitpointer, unsigned char * bitstrea unsigned lodepng_chunk_length(const unsigned char * chunk) { - return lodepng_read32bitInt(&chunk[0]); + return lodepng_read32bitInt(chunk); } void lodepng_chunk_type(char type[5], const unsigned char * chunk) @@ -2656,7 +2928,8 @@ void lodepng_chunk_generate_crc(unsigned char * chunk) unsigned char * lodepng_chunk_next(unsigned char * chunk, unsigned char * end) { - if(chunk >= end || end - chunk < 12) return end; /*too small to contain a chunk*/ + size_t available_size = (size_t)(end - chunk); + if(chunk >= end || available_size < 12) return end; /*too small to contain a chunk*/ if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ @@ -2664,17 +2937,16 @@ unsigned char * lodepng_chunk_next(unsigned char * chunk, unsigned char * end) } else { size_t total_chunk_length; - unsigned char * result; if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; - result = chunk + total_chunk_length; - if(result < chunk) return end; /*pointer overflow*/ - return result; + if(total_chunk_length > available_size) return end; /*outside of range*/ + return chunk + total_chunk_length; } } const unsigned char * lodepng_chunk_next_const(const unsigned char * chunk, const unsigned char * end) { - if(chunk >= end || end - chunk < 12) return end; /*too small to contain a chunk*/ + size_t available_size = (size_t)(end - chunk); + if(chunk >= end || available_size < 12) return end; /*too small to contain a chunk*/ if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ @@ -2682,11 +2954,9 @@ const unsigned char * lodepng_chunk_next_const(const unsigned char * chunk, cons } else { size_t total_chunk_length; - const unsigned char * result; if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; - result = chunk + total_chunk_length; - if(result < chunk) return end; /*pointer overflow*/ - return result; + if(total_chunk_length > available_size) return end; /*outside of range*/ + return chunk + total_chunk_length; } } @@ -2697,8 +2967,6 @@ unsigned char * lodepng_chunk_find(unsigned char * chunk, unsigned char * end, c if(lodepng_chunk_type_equals(chunk, type)) return chunk; chunk = lodepng_chunk_next(chunk, end); } - - return 0; /*Shouldn't reach this*/ } const unsigned char * lodepng_chunk_find_const(const unsigned char * chunk, const unsigned char * end, @@ -2709,8 +2977,6 @@ const unsigned char * lodepng_chunk_find_const(const unsigned char * chunk, cons if(lodepng_chunk_type_equals(chunk, type)) return chunk; chunk = lodepng_chunk_next_const(chunk, end); } - - return 0; /*Shouldn't reach this*/ } unsigned lodepng_chunk_append(unsigned char ** out, size_t * outsize, const unsigned char * chunk) @@ -2739,7 +3005,7 @@ the data is at chunk + 8. To finalize chunk, add the data, then use lodepng_chunk_generate_crc */ static unsigned lodepng_chunk_init(unsigned char ** chunk, ucvector * out, - unsigned length, const char * type) + size_t length, const char * type) { size_t new_length = out->size; if(lodepng_addofl(new_length, length, &new_length)) return 77; @@ -2748,7 +3014,7 @@ static unsigned lodepng_chunk_init(unsigned char ** chunk, *chunk = out->data + new_length - length - 12u; /*1: length*/ - lodepng_set32bitInt(*chunk, length); + lodepng_set32bitInt(*chunk, (unsigned)length); /*2: chunk name (4 letters)*/ lodepng_memcpy(*chunk + 4, type, 4); @@ -2758,7 +3024,7 @@ static unsigned lodepng_chunk_init(unsigned char ** chunk, /* like lodepng_chunk_create but with custom allocsize */ static unsigned lodepng_chunk_createv(ucvector * out, - unsigned length, const char * type, const unsigned char * data) + size_t length, const char * type, const unsigned char * data) { unsigned char * chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, length, type)); @@ -2773,7 +3039,7 @@ static unsigned lodepng_chunk_createv(ucvector * out, } unsigned lodepng_chunk_create(unsigned char ** out, size_t * outsize, - unsigned length, const char * type, const unsigned char * data) + size_t length, const char * type, const unsigned char * data) { ucvector v = ucvector_init(*out, *outsize); unsigned error = lodepng_chunk_createv(&v, length, type, data); @@ -3268,6 +3534,9 @@ void lodepng_info_init(LodePNGInfo * info) info->iccp_name = NULL; info->iccp_profile = NULL; + info->sbit_defined = 0; + info->sbit_r = info->sbit_g = info->sbit_b = info->sbit_a = 0; + LodePNGUnknownChunks_init(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } @@ -4014,7 +4283,7 @@ unsigned lodepng_compute_color_stats(LodePNGColorStats * stats, if(!numcolors_done) { for(i = 0; i < stats->numcolors; i++) { const unsigned char * color = &stats->palette[i * 4]; - error = color_tree_add(&tree, color[0], color[1], color[2], color[3], i); + error = color_tree_add(&tree, color[0], color[1], color[2], color[3], (unsigned)i); if(error) goto cleanup; } } @@ -4247,7 +4516,7 @@ static unsigned auto_choose_color(LodePNGColorMode * mode_out, if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize && mode_in->bitdepth == mode_out->bitdepth) { /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ - lodepng_color_mode_cleanup(mode_out); + lodepng_color_mode_cleanup(mode_out); /*clears palette, keeps the above set colortype and bitdepth fields as-is*/ lodepng_color_mode_copy(mode_out, mode_in); } } @@ -4269,16 +4538,15 @@ static unsigned auto_choose_color(LodePNGColorMode * mode_out, #endif /* #ifdef LODEPNG_COMPILE_ENCODER */ -/* -Paeth predictor, used by PNG filter type 4 -The parameters are of type short, but should come from unsigned chars, the shorts -are only needed to make the paeth calculation correct. -*/ -static unsigned char paethPredictor(short a, short b, short c) +/*Paeth predictor, used by PNG filter type 4*/ +static unsigned char paethPredictor(unsigned char a, unsigned char b, unsigned char c) { - short pa = LODEPNG_ABS(b - c); - short pb = LODEPNG_ABS(a - c); - short pc = LODEPNG_ABS(a + b - c - c); + /* the subtractions of unsigned char cast it to a signed type. + With gcc, short is faster than int, with clang int is as fast (as of april 2023)*/ + short pa = (b - c) < 0 ? -(b - c) : (b - c); + short pb = (a - c) < 0 ? -(a - c) : (a - c); + /* writing it out like this compiles to something faster than introducing a temp variable*/ + short pc = (a + b - c - c) < 0 ? -(a + b - c - c) : (a + b - c - c); /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */ if(pb < pa) { a = b; @@ -4424,10 +4692,12 @@ static unsigned unfilterScanline(unsigned char * recon, const unsigned char * sc case 0: for(i = 0; i != length; ++i) recon[i] = scanline[i]; break; - case 1: - for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; - for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; - break; + case 1: { + size_t j = 0; + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + recon[j]; + break; + } case 2: if(precon) { for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; @@ -4438,70 +4708,230 @@ static unsigned unfilterScanline(unsigned char * recon, const unsigned char * sc break; case 3: if(precon) { + size_t j = 0; for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u); - for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u); + /* Unroll independent paths of this predictor. A 6x and 8x version is also possible but that adds + too much code. Whether this speeds up anything depends on compiler and settings. */ + if(bytewidth >= 4) { + for(; i + 3 < length; i += 4, j += 4) { + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3]; + recon[i + 0] = s0 + ((r0 + p0) >> 1u); + recon[i + 1] = s1 + ((r1 + p1) >> 1u); + recon[i + 2] = s2 + ((r2 + p2) >> 1u); + recon[i + 3] = s3 + ((r3 + p3) >> 1u); + } + } + else if(bytewidth >= 3) { + for(; i + 2 < length; i += 3, j += 3) { + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2]; + recon[i + 0] = s0 + ((r0 + p0) >> 1u); + recon[i + 1] = s1 + ((r1 + p1) >> 1u); + recon[i + 2] = s2 + ((r2 + p2) >> 1u); + } + } + else if(bytewidth >= 2) { + for(; i + 1 < length; i += 2, j += 2) { + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1]; + recon[i + 0] = s0 + ((r0 + p0) >> 1u); + recon[i + 1] = s1 + ((r1 + p1) >> 1u); + } + } + for(; i != length; ++i, ++j) recon[i] = scanline[i] + ((recon[j] + precon[i]) >> 1u); } else { + size_t j = 0; for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; - for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u); + for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + (recon[j] >> 1u); } break; case 4: if(precon) { - for(i = 0; i != bytewidth; ++i) { - recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ - } - - /* Unroll independent paths of the paeth predictor. A 6x and 8x version would also be possible but that - adds too much code. Whether this actually speeds anything up at all depends on compiler and settings. */ - if(bytewidth >= 4) { - for(; i + 3 < length; i += 4) { - size_t j = i - bytewidth; - unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3]; - unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3]; - unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3]; - unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2], q3 = precon[j + 3]; - recon[i + 0] = s0 + paethPredictor(r0, p0, q0); - recon[i + 1] = s1 + paethPredictor(r1, p1, q1); - recon[i + 2] = s2 + paethPredictor(r2, p2, q2); - recon[i + 3] = s3 + paethPredictor(r3, p3, q3); + /* Unroll independent paths of this predictor. Whether this speeds up + anything depends on compiler and settings. */ + if(bytewidth == 8) { + unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0; + unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0; + unsigned char a6, b6 = 0, c6, d6 = 0, a7, b7 = 0, c7, d7 = 0; + for(i = 0; i + 7 < length; i += 8) { + c0 = b0; + c1 = b1; + c2 = b2; + c3 = b3; + c4 = b4; + c5 = b5; + c6 = b6; + c7 = b7; + b0 = precon[i + 0]; + b1 = precon[i + 1]; + b2 = precon[i + 2]; + b3 = precon[i + 3]; + b4 = precon[i + 4]; + b5 = precon[i + 5]; + b6 = precon[i + 6]; + b7 = precon[i + 7]; + a0 = d0; + a1 = d1; + a2 = d2; + a3 = d3; + a4 = d4; + a5 = d5; + a6 = d6; + a7 = d7; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + d3 = scanline[i + 3] + paethPredictor(a3, b3, c3); + d4 = scanline[i + 4] + paethPredictor(a4, b4, c4); + d5 = scanline[i + 5] + paethPredictor(a5, b5, c5); + d6 = scanline[i + 6] + paethPredictor(a6, b6, c6); + d7 = scanline[i + 7] + paethPredictor(a7, b7, c7); + recon[i + 0] = d0; + recon[i + 1] = d1; + recon[i + 2] = d2; + recon[i + 3] = d3; + recon[i + 4] = d4; + recon[i + 5] = d5; + recon[i + 6] = d6; + recon[i + 7] = d7; } } - else if(bytewidth >= 3) { - for(; i + 2 < length; i += 3) { - size_t j = i - bytewidth; - unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2]; - unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2]; - unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2]; - unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2]; - recon[i + 0] = s0 + paethPredictor(r0, p0, q0); - recon[i + 1] = s1 + paethPredictor(r1, p1, q1); - recon[i + 2] = s2 + paethPredictor(r2, p2, q2); + else if(bytewidth == 6) { + unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0; + unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0; + for(i = 0; i + 5 < length; i += 6) { + c0 = b0; + c1 = b1; + c2 = b2; + c3 = b3; + c4 = b4; + c5 = b5; + b0 = precon[i + 0]; + b1 = precon[i + 1]; + b2 = precon[i + 2]; + b3 = precon[i + 3]; + b4 = precon[i + 4]; + b5 = precon[i + 5]; + a0 = d0; + a1 = d1; + a2 = d2; + a3 = d3; + a4 = d4; + a5 = d5; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + d3 = scanline[i + 3] + paethPredictor(a3, b3, c3); + d4 = scanline[i + 4] + paethPredictor(a4, b4, c4); + d5 = scanline[i + 5] + paethPredictor(a5, b5, c5); + recon[i + 0] = d0; + recon[i + 1] = d1; + recon[i + 2] = d2; + recon[i + 3] = d3; + recon[i + 4] = d4; + recon[i + 5] = d5; } } - else if(bytewidth >= 2) { - for(; i + 1 < length; i += 2) { - size_t j = i - bytewidth; - unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1]; - unsigned char r0 = recon[j + 0], r1 = recon[j + 1]; - unsigned char p0 = precon[i + 0], p1 = precon[i + 1]; - unsigned char q0 = precon[j + 0], q1 = precon[j + 1]; - recon[i + 0] = s0 + paethPredictor(r0, p0, q0); - recon[i + 1] = s1 + paethPredictor(r1, p1, q1); + else if(bytewidth == 4) { + unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0; + for(i = 0; i + 3 < length; i += 4) { + c0 = b0; + c1 = b1; + c2 = b2; + c3 = b3; + b0 = precon[i + 0]; + b1 = precon[i + 1]; + b2 = precon[i + 2]; + b3 = precon[i + 3]; + a0 = d0; + a1 = d1; + a2 = d2; + a3 = d3; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + d3 = scanline[i + 3] + paethPredictor(a3, b3, c3); + recon[i + 0] = d0; + recon[i + 1] = d1; + recon[i + 2] = d2; + recon[i + 3] = d3; } } - + else if(bytewidth == 3) { + unsigned char a0, b0 = 0, c0, d0 = 0; + unsigned char a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0; + for(i = 0; i + 2 < length; i += 3) { + c0 = b0; + c1 = b1; + c2 = b2; + b0 = precon[i + 0]; + b1 = precon[i + 1]; + b2 = precon[i + 2]; + a0 = d0; + a1 = d1; + a2 = d2; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + recon[i + 0] = d0; + recon[i + 1] = d1; + recon[i + 2] = d2; + } + } + else if(bytewidth == 2) { + unsigned char a0, b0 = 0, c0, d0 = 0; + unsigned char a1, b1 = 0, c1, d1 = 0; + for(i = 0; i + 1 < length; i += 2) { + c0 = b0; + c1 = b1; + b0 = precon[i + 0]; + b1 = precon[i + 1]; + a0 = d0; + a1 = d1; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + recon[i + 0] = d0; + recon[i + 1] = d1; + } + } + else if(bytewidth == 1) { + unsigned char a, b = 0, c, d = 0; + for(i = 0; i != length; ++i) { + c = b; + b = precon[i]; + a = d; + d = scanline[i] + paethPredictor(a, b, c); + recon[i] = d; + } + } + else { + /* Normally not a possible case, but this would handle it correctly */ + for(i = 0; i != bytewidth; ++i) { + recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ + } + } + /* finish any remaining bytes */ for(; i != length; ++i) { recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); } } else { + size_t j = 0; for(i = 0; i != bytewidth; ++i) { recon[i] = scanline[i]; } - for(i = bytewidth; i < length; ++i) { + for(i = bytewidth; i != length; ++i, ++j) { /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ - recon[i] = (scanline[i] + recon[i - bytewidth]); + recon[i] = (scanline[i] + recon[j]); } } break; @@ -5035,10 +5465,55 @@ static unsigned readChunk_iCCP(LodePNGInfo * info, const LodePNGDecoderSettings length, &zlibsettings); /*error: ICC profile larger than decoder->max_icc_size*/ if(error && size > zlibsettings.max_output_size) error = 113; - info->iccp_profile_size = size; + info->iccp_profile_size = (unsigned)size; if(!error && !info->iccp_profile_size) error = 100; /*invalid ICC profile size*/ return error; } + +/*significant bits chunk (sBIT)*/ +static unsigned readChunk_sBIT(LodePNGInfo * info, const unsigned char * data, size_t chunkLength) +{ + unsigned bitdepth = (info->color.colortype == LCT_PALETTE) ? 8 : info->color.bitdepth; + if(info->color.colortype == LCT_GREY) { + /*error: this chunk must be 1 bytes for grayscale image*/ + if(chunkLength != 1) return 114; + if(data[0] == 0 || data[0] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = info->sbit_g = info->sbit_b = data[0]; /*setting g and b is not required, but sensible*/ + } + else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_PALETTE) { + /*error: this chunk must be 3 bytes for RGB and palette image*/ + if(chunkLength != 3) return 114; + if(data[0] == 0 || data[1] == 0 || data[2] == 0) return 115; + if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = data[0]; + info->sbit_g = data[1]; + info->sbit_b = data[2]; + } + else if(info->color.colortype == LCT_GREY_ALPHA) { + /*error: this chunk must be 2 byte for grayscale with alpha image*/ + if(chunkLength != 2) return 114; + if(data[0] == 0 || data[1] == 0) return 115; + if(data[0] > bitdepth || data[1] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = info->sbit_g = info->sbit_b = data[0]; /*setting g and b is not required, but sensible*/ + info->sbit_a = data[1]; + } + else if(info->color.colortype == LCT_RGBA) { + /*error: this chunk must be 4 bytes for grayscale image*/ + if(chunkLength != 4) return 114; + if(data[0] == 0 || data[1] == 0 || data[2] == 0 || data[3] == 0) return 115; + if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth || data[3] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = data[0]; + info->sbit_g = data[1]; + info->sbit_b = data[2]; + info->sbit_a = data[3]; + } + + return 0; /* OK */ +} #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ unsigned lodepng_inspect_chunk(LodePNGState * state, size_t pos, @@ -5054,7 +5529,7 @@ unsigned lodepng_inspect_chunk(LodePNGState * state, size_t pos, chunkLength = lodepng_chunk_length(chunk); if(chunkLength > 2147483647) return 63; data = lodepng_chunk_data_const(chunk); - if(data + chunkLength + 4 > in + insize) return 30; + if(chunkLength + 12 > insize - pos) return 30; if(lodepng_chunk_type_equals(chunk, "PLTE")) { error = readChunk_PLTE(&state->info_png.color, data, chunkLength); @@ -5092,6 +5567,9 @@ unsigned lodepng_inspect_chunk(LodePNGState * state, size_t pos, } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength); + } + else if(lodepng_chunk_type_equals(chunk, "sBIT")) { + error = readChunk_sBIT(&state->info_png, data, chunkLength); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } else { @@ -5112,7 +5590,7 @@ static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h, const unsigned char * in, size_t insize) { unsigned char IEND = 0; - const unsigned char * chunk; + const unsigned char * chunk; /*points to beginning of next chunk*/ unsigned char * idat; /*the data from idat chunks, zlib compressed*/ size_t idatsize = 0; unsigned char * scanlines = 0; @@ -5148,14 +5626,15 @@ static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h, while(!IEND && !state->error) { unsigned chunkLength; const unsigned char * data; /*the data in the chunk*/ + size_t pos = (size_t)(chunk - in); - /*error: size of the in buffer too small to contain next chunk*/ - if((size_t)((chunk - in) + 12) > insize || chunk < in) { + /*error: next chunk out of bounds of the in buffer*/ + if(chunk < in || pos + 12 > insize) { if(state->decoder.ignore_end) break; /*other errors may still happen though*/ CERROR_BREAK(state->error, 30); } - /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ + /*length of the data of the chunk, excluding the 12 bytes for length, chunk type and CRC*/ chunkLength = lodepng_chunk_length(chunk); /*error: chunk length larger than the max PNG chunk size*/ if(chunkLength > 2147483647) { @@ -5163,8 +5642,8 @@ static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h, CERROR_BREAK(state->error, 63); } - if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) { - CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ + if(pos + (size_t)chunkLength + 12 > insize || pos + (size_t)chunkLength + 12 < pos) { + CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk (or int overflow)*/ } data = lodepng_chunk_data_const(chunk); @@ -5251,9 +5730,13 @@ static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h, else if(lodepng_chunk_type_equals(chunk, "iCCP")) { state->error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength); if(state->error) break; + } + else if(lodepng_chunk_type_equals(chunk, "sBIT")) { + state->error = readChunk_sBIT(&state->info_png, data, chunkLength); + if(state->error) break; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } - else { /*it's not an implemented chunk type, so ignore it: skip over the data*/ + else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) { CERROR_BREAK(state->error, 69); @@ -5284,11 +5767,11 @@ static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h, /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. If the decompressed size does not match the prediction, the image must be corrupt.*/ if(state->info_png.interlace_method == 0) { - size_t bpp = lodepng_get_bpp(&state->info_png.color); + unsigned bpp = lodepng_get_bpp(&state->info_png.color); expected_size = lodepng_get_raw_size_idat(*w, *h, bpp); } else { - size_t bpp = lodepng_get_bpp(&state->info_png.color); + unsigned bpp = lodepng_get_bpp(&state->info_png.color); /*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/ expected_size = 0; expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, bpp); @@ -5307,7 +5790,7 @@ static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h, lodepng_free(idat); if(!state->error) { - lv_draw_buf_t * decoded = lv_draw_buf_create(*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); + lv_draw_buf_t * decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, *w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); if(decoded) { *out = (unsigned char*)decoded; outsize = decoded->data_size; @@ -5348,14 +5831,14 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h, return 56; /*unsupported color mode conversion*/ } - lv_draw_buf_t * new_buf = lv_draw_buf_create(*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); + lv_draw_buf_t * new_buf = lv_draw_buf_create_user(image_cache_draw_buf_handlers,*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); if(new_buf == NULL) { state->error = 83; /*alloc fail*/ } else { - state->error = lodepng_convert(new_buf->data, old_buf->data, + state->error = lodepng_convert(new_buf->data, old_buf->data, &state->info_raw, &state->info_png.color, *w, *h); - + if (state->error) { lv_draw_buf_destroy(new_buf); new_buf = NULL; @@ -5517,6 +6000,10 @@ static unsigned addChunk_PLTE(ucvector * out, const LodePNGColorMode * info) unsigned char * chunk; size_t i, j = 8; + if(info->palettesize == 0 || info->palettesize > 256) { + return 68; /*invalid palette size, it is only allowed to be 1-256*/ + } + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, info->palettesize * 3, "PLTE")); for(i = 0; i != info->palettesize; ++i) { @@ -5790,6 +6277,46 @@ static unsigned addChunk_iCCP(ucvector * out, const LodePNGInfo * info, LodePNGC return error; } +static unsigned addChunk_sBIT(ucvector * out, const LodePNGInfo * info) +{ + unsigned bitdepth = (info->color.colortype == LCT_PALETTE) ? 8 : info->color.bitdepth; + unsigned char * chunk = 0; + if(info->color.colortype == LCT_GREY) { + if(info->sbit_r == 0 || info->sbit_r > bitdepth) return 115; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 1, "sBIT")); + chunk[8] = info->sbit_r; + } + else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_PALETTE) { + if(info->sbit_r == 0 || info->sbit_g == 0 || info->sbit_b == 0) return 115; + if(info->sbit_r > bitdepth || info->sbit_g > bitdepth || info->sbit_b > bitdepth) return 115; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 3, "sBIT")); + chunk[8] = info->sbit_r; + chunk[9] = info->sbit_g; + chunk[10] = info->sbit_b; + } + else if(info->color.colortype == LCT_GREY_ALPHA) { + if(info->sbit_r == 0 || info->sbit_a == 0) return 115; + if(info->sbit_r > bitdepth || info->sbit_a > bitdepth) return 115; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "sBIT")); + chunk[8] = info->sbit_r; + chunk[9] = info->sbit_a; + } + else if(info->color.colortype == LCT_RGBA) { + if(info->sbit_r == 0 || info->sbit_g == 0 || info->sbit_b == 0 || info->sbit_a == 0 || + info->sbit_r > bitdepth || info->sbit_g > bitdepth || + info->sbit_b > bitdepth || info->sbit_a > bitdepth) { + return 115; + } + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "sBIT")); + chunk[8] = info->sbit_r; + chunk[9] = info->sbit_g; + chunk[10] = info->sbit_b; + chunk[11] = info->sbit_a; + } + if(chunk) lodepng_chunk_generate_crc(chunk); + return 0; +} + #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ static void filterScanline(unsigned char * out, const unsigned char * scanline, const unsigned char * prevline, @@ -5875,7 +6402,7 @@ static size_t ilog2i(size_t i) l = ilog2(i); /* approximate i*log2(i): l is integer logarithm, ((i - (1u << l)) << 1u) linearly approximates the missing fractional part multiplied by i */ - return i * l + ((i - (1u << l)) << 1u); + return i * l + ((i - (((size_t)1) << l)) << 1u); } static unsigned filter(unsigned char * out, const unsigned char * in, unsigned w, unsigned h, @@ -6200,7 +6727,7 @@ static unsigned preProcessScanlines(unsigned char ** out, size_t * outsize, cons adam7 = (unsigned char *)lodepng_malloc(passstart[7]); if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ - if(!error && adam7) { + if(!error) { unsigned i; Adam7_interlace(adam7, in, w, h, bpp); @@ -6273,8 +6800,10 @@ unsigned lodepng_encode(unsigned char ** out, size_t * outsize, ucvector outv = ucvector_init(NULL, 0); LodePNGInfo info; const LodePNGInfo * info_png = &state->info_png; + LodePNGColorMode auto_color; lodepng_info_init(&info); + lodepng_color_mode_init(&auto_color); /*provide some proper output values if error will happen*/ *out = 0; @@ -6284,6 +6813,10 @@ unsigned lodepng_encode(unsigned char ** out, size_t * outsize, /*check input values validity*/ if((info_png->color.colortype == LCT_PALETTE || state->encoder.force_palette) && (info_png->color.palettesize == 0 || info_png->color.palettesize > 256)) { + /*this error is returned even if auto_convert is enabled and thus encoder could + generate the palette by itself: while allowing this could be possible in theory, + it may complicate the code or edge cases, and always requiring to give a palette + when setting this color type is a simpler contract*/ state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ goto cleanup; } @@ -6304,6 +6837,7 @@ unsigned lodepng_encode(unsigned char ** out, size_t * outsize, lodepng_info_copy(&info, &state->info_png); if(state->encoder.auto_convert) { LodePNGColorStats stats; + unsigned allow_convert = 1; lodepng_color_stats_init(&stats); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(info_png->iccp_defined && @@ -6325,24 +6859,85 @@ unsigned lodepng_encode(unsigned char ** out, size_t * outsize, /*the background chunk's color must be taken into account as well*/ unsigned r = 0, g = 0, b = 0; LodePNGColorMode mode16 = lodepng_color_mode_make(LCT_RGB, 16); - lodepng_convert_rgb(&r, &g, &b, info_png->background_r, info_png->background_g, info_png->background_b, &mode16, - &info_png->color); + lodepng_convert_rgb(&r, &g, &b, + info_png->background_r, info_png->background_g, info_png->background_b, &mode16, &info_png->color); state->error = lodepng_color_stats_add(&stats, r, g, b, 65535); if(state->error) goto cleanup; } #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ - state->error = auto_choose_color(&info.color, &state->info_raw, &stats); + state->error = auto_choose_color(&auto_color, &state->info_raw, &stats); if(state->error) goto cleanup; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*also convert the background chunk*/ - if(info_png->background_defined) { - if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b, - info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) { - state->error = 104; - goto cleanup; + if(info_png->sbit_defined) { + /*if sbit is defined, due to strict requirements of which sbit values can be present for which color modes, + auto_convert can't be done in many cases. However, do support a few cases here. + TODO: more conversions may be possible, and it may also be possible to get a more appropriate color type out of + auto_choose_color if knowledge about sbit is used beforehand + */ + unsigned sbit_max = LODEPNG_MAX(LODEPNG_MAX(LODEPNG_MAX(info_png->sbit_r, info_png->sbit_g), + info_png->sbit_b), info_png->sbit_a); + unsigned equal = (!info_png->sbit_g || info_png->sbit_g == info_png->sbit_r) + && (!info_png->sbit_b || info_png->sbit_b == info_png->sbit_r) + && (!info_png->sbit_a || info_png->sbit_a == info_png->sbit_r); + allow_convert = 0; + if(info.color.colortype == LCT_PALETTE && + auto_color.colortype == LCT_PALETTE) { + /* input and output are palette, and in this case it may happen that palette data is + expected to be copied from info_raw into the info_png */ + allow_convert = 1; + } + /*going from 8-bit RGB to palette (or 16-bit as long as sbit_max <= 8) is possible + since both are 8-bit RGB for sBIT's purposes*/ + if(info.color.colortype == LCT_RGB && + auto_color.colortype == LCT_PALETTE && sbit_max <= 8) { + allow_convert = 1; + } + /*going from 8-bit RGBA to palette is also ok but only if sbit_a is exactly 8*/ + if(info.color.colortype == LCT_RGBA && auto_color.colortype == LCT_PALETTE && + info_png->sbit_a == 8 && sbit_max <= 8) { + allow_convert = 1; + } + /*going from 16-bit RGB(A) to 8-bit RGB(A) is ok if all sbit values are <= 8*/ + if((info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA) && info.color.bitdepth == 16 && + auto_color.colortype == info.color.colortype && auto_color.bitdepth == 8 && + sbit_max <= 8) { + allow_convert = 1; + } + /*going to less channels is ok if all bit values are equal (all possible values in sbit, + as well as the chosen bitdepth of the result). Due to how auto_convert works, + we already know that auto_color.colortype has less than or equal amount of channels than + info.colortype. Palette is not used here. This conversion is not allowed if + info_png->sbit_r < auto_color.bitdepth, because specifically for alpha, non-presence of + an sbit value heavily implies that alpha's bit depth is equal to the PNG bit depth (rather + than the bit depths set in the r, g and b sbit values, by how the PNG specification describes + handling tRNS chunk case with sBIT), so be conservative here about ignoring user input.*/ + if(info.color.colortype != LCT_PALETTE && auto_color.colortype != LCT_PALETTE && + equal && info_png->sbit_r == auto_color.bitdepth) { + allow_convert = 1; } } +#endif + if(state->encoder.force_palette) { + if(info.color.colortype != LCT_GREY && info.color.colortype != LCT_GREY_ALPHA && + (auto_color.colortype == LCT_GREY || auto_color.colortype == LCT_GREY_ALPHA)) { + /*user speficially forced a PLTE palette, so cannot convert to grayscale types because + the PNG specification only allows writing a suggested palette in PLTE for truecolor types*/ + allow_convert = 0; + } + } + if(allow_convert) { + lodepng_color_mode_copy(&info.color, &auto_color); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*also convert the background chunk*/ + if(info_png->background_defined) { + if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b, + info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) { + state->error = 104; + goto cleanup; + } + } #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + } } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(info_png->iccp_defined) { @@ -6414,6 +7009,10 @@ unsigned lodepng_encode(unsigned char ** out, size_t * outsize, state->error = addChunk_cHRM(&outv, &info); if(state->error) goto cleanup; } + if(info_png->sbit_defined) { + state->error = addChunk_sBIT(&outv, &info); + if(state->error) goto cleanup; + } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*PLTE*/ if(info.color.colortype == LCT_PALETTE) { @@ -6521,6 +7120,7 @@ unsigned lodepng_encode(unsigned char ** out, size_t * outsize, cleanup: lodepng_info_cleanup(&info); lodepng_free(data); + lodepng_color_mode_cleanup(&auto_color); /*instead of cleaning the vector up, give it to the output*/ *out = outv.data; @@ -6823,6 +7423,10 @@ const char * lodepng_error_text(unsigned code) unreasonable memory consumption when decoding due to impossibly large ICC profile*/ case 113: return "ICC profile unreasonably large"; + case 114: + return "sBIT chunk has wrong size for the color type of the image"; + case 115: + return "sBIT value out of range"; } return "unknown error code"; } @@ -6863,7 +7467,7 @@ unsigned decompress(std::vector & out, const unsigned char * in, size_t buffersize = 0; unsigned error = zlib_decompress(&buffer, &buffersize, 0, in, insize, &settings); if(buffer) { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); + out.insert(out.end(), buffer, &buffer[buffersize]); lodepng_free(buffer); } return error; @@ -6884,7 +7488,7 @@ unsigned compress(std::vector & out, const unsigned char * in, si size_t buffersize = 0; unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); if(buffer) { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); + out.insert(out.end(), buffer, &buffer[buffersize]); lodepng_free(buffer); } return error; @@ -6935,7 +7539,7 @@ unsigned decode(std::vector & out, unsigned & w, unsigned & h, co state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); - out.insert(out.end(), &buffer[0], &buffer[buffersize]); + out.insert(out.end(), buffer, &buffer[buffersize]); } lodepng_free(buffer); return error; @@ -6955,7 +7559,7 @@ unsigned decode(std::vector & out, unsigned & w, unsigned & h, unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); if(buffer && !error) { size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); - out.insert(out.end(), &buffer[0], &buffer[buffersize]); + out.insert(out.end(), buffer, &buffer[buffersize]); } lodepng_free(buffer); return error; @@ -6990,7 +7594,7 @@ unsigned encode(std::vector & out, const unsigned char * in, unsi size_t buffersize; unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); if(buffer) { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); + out.insert(out.end(), buffer, &buffer[buffersize]); lodepng_free(buffer); } return error; @@ -7012,7 +7616,7 @@ unsigned encode(std::vector & out, size_t buffersize; unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); if(buffer) { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); + out.insert(out.end(), buffer, &buffer[buffersize]); lodepng_free(buffer); } return error; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h index de9eec5ff..1ae349650 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h @@ -1,7 +1,7 @@ /* -LodePNG version 20201017 +LodePNG version 20230410 -Copyright (c) 2005-2020 Lode Vandevenne +Copyright (c) 2005-2023 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,10 +30,9 @@ freely, subject to the following restrictions: extern "C" { #endif -#include /*for size_t*/ - #include "../../../lvgl.h" #if LV_USE_LODEPNG +#include LV_STDDEF_INCLUDE /*for size_t*/ LV_ATTRIBUTE_EXTERN_DATA extern const char * LODEPNG_VERSION_STRING; /* @@ -41,43 +40,50 @@ The following #defines are used to create code sections. They can be disabled to disable code sections, which can give faster compile time and smaller binary. The "NO_COMPILE" defines are designed to be used to pass as defines to the compiler command to disable them without modifying this header, e.g. --DLODEPNG_NO_COMPILE_ZLIB for gcc. -In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to -allow implementing a custom lodepng_crc32. +-DLODEPNG_NO_COMPILE_ZLIB for gcc or clang. */ /*deflate & zlib. If disabled, you must specify alternative zlib functions in the custom_zlib field of the compress and decompress settings*/ #ifndef LODEPNG_NO_COMPILE_ZLIB + /*pass -DLODEPNG_NO_COMPILE_ZLIB to the compiler to disable this, or comment out LODEPNG_COMPILE_ZLIB below*/ #define LODEPNG_COMPILE_ZLIB #endif /*png encoder and png decoder*/ #ifndef LODEPNG_NO_COMPILE_PNG + /*pass -DLODEPNG_NO_COMPILE_PNG to the compiler to disable this, or comment out LODEPNG_COMPILE_PNG below*/ #define LODEPNG_COMPILE_PNG #endif /*deflate&zlib decoder and png decoder*/ #ifndef LODEPNG_NO_COMPILE_DECODER + /*pass -DLODEPNG_NO_COMPILE_DECODER to the compiler to disable this, or comment out LODEPNG_COMPILE_DECODER below*/ #define LODEPNG_COMPILE_DECODER #endif /*deflate&zlib encoder and png encoder*/ #ifndef LODEPNG_NO_COMPILE_ENCODER + /*pass -DLODEPNG_NO_COMPILE_ENCODER to the compiler to disable this, or comment out LODEPNG_COMPILE_ENCODER below*/ #define LODEPNG_COMPILE_ENCODER #endif /*the optional built in harddisk file loading and saving functions*/ #ifndef LODEPNG_NO_COMPILE_DISK + /*pass -DLODEPNG_NO_COMPILE_DISK to the compiler to disable this, or comment out LODEPNG_COMPILE_DISK below*/ #define LODEPNG_COMPILE_DISK #endif /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS + /*pass -DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS to the compiler to disable this, + or comment out LODEPNG_COMPILE_ANCILLARY_CHUNKS below*/ #define LODEPNG_COMPILE_ANCILLARY_CHUNKS #endif /*ability to convert error numerical codes to English text string*/ #ifndef LODEPNG_NO_COMPILE_ERROR_TEXT + /*pass -DLODEPNG_NO_COMPILE_ERROR_TEXT to the compiler to disable this, + or comment out LODEPNG_COMPILE_ERROR_TEXT below*/ #define LODEPNG_COMPILE_ERROR_TEXT #endif @@ -85,12 +91,27 @@ the custom_zlib field of the compress and decompress settings*/ you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your source files with custom allocators.*/ #ifndef LODEPNG_NO_COMPILE_ALLOCATORS + /*pass -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler to disable the built-in ones, + or comment out LODEPNG_COMPILE_ALLOCATORS below*/ #define LODEPNG_COMPILE_ALLOCATORS #endif +/*Disable built-in CRC function, in that case a custom implementation of +lodepng_crc32 must be defined externally so that it can be linked in. +The default built-in CRC code comes with 8KB of lookup tables, so for memory constrained environment you may want it +disabled and provide a much smaller implementation externally as said above. You can find such an example implementation +in a comment in the lodepng.c(pp) file in the 'else' case of the searchable LODEPNG_COMPILE_CRC section.*/ +#ifndef LODEPNG_NO_COMPILE_CRC + /*pass -DLODEPNG_NO_COMPILE_CRC to the compiler to disable the built-in one, + or comment out LODEPNG_COMPILE_CRC below*/ + #define LODEPNG_COMPILE_CRC +#endif + /*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ #ifdef __cplusplus #ifndef LODEPNG_NO_COMPILE_CPP + /*pass -DLODEPNG_NO_COMPILE_CPP to the compiler to disable C++ (not needed if a C-only compiler), + or comment out LODEPNG_COMPILE_CPP below*/ #define LODEPNG_COMPILE_CPP #endif #endif @@ -102,7 +123,7 @@ source files with custom allocators.*/ #ifdef LODEPNG_COMPILE_PNG /*The PNG color types (also used for raw image).*/ -typedef enum _LodePNGColorType { +typedef enum LodePNGColorType { LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ LCT_RGB = 2, /*RGB: 8,16 bit*/ LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ @@ -148,16 +169,24 @@ unsigned lodepng_decode24(unsigned char ** out, unsigned * w, unsigned * h, /* Load PNG from disk, from file with given name. Same as the other decode functions, but instead takes a filename as input. -*/ + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ unsigned lodepng_decode_file(unsigned char ** out, unsigned * w, unsigned * h, const char * filename, LodePNGColorType colortype, unsigned bitdepth); -/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ +/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ unsigned lodepng_decode32_file(unsigned char ** out, unsigned * w, unsigned * h, const char * filename); -/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ +/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ unsigned lodepng_decode24_file(unsigned char ** out, unsigned * w, unsigned * h, const char * filename); #endif /*LODEPNG_COMPILE_DISK*/ @@ -197,17 +226,26 @@ unsigned lodepng_encode24(unsigned char ** out, size_t * outsize, /* Converts raw pixel data into a PNG file on disk. Same as the other encode functions, but instead takes a filename as output. + NOTE: This overwrites existing files without warning! -*/ + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ unsigned lodepng_encode_file(const char * filename, const unsigned char * image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth); -/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ +/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ unsigned lodepng_encode32_file(const char * filename, const unsigned char * image, unsigned w, unsigned h); -/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ +/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ unsigned lodepng_encode24_file(const char * filename, const unsigned char * image, unsigned w, unsigned h); #endif /*LODEPNG_COMPILE_DISK*/ @@ -230,6 +268,9 @@ unsigned decode(std::vector & out, unsigned & w, unsigned & h, /* Converts PNG file from disk to raw pixel data in memory. Same as the other decode functions, but instead takes a filename as input. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. */ unsigned decode(std::vector & out, unsigned & w, unsigned & h, const std::string & filename, @@ -250,7 +291,11 @@ unsigned encode(std::vector & out, /* Converts 32-bit RGBA raw pixel data into a PNG file on disk. Same as the other encode functions, but instead takes a filename as output. + NOTE: This overwrites existing files without warning! + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. */ unsigned encode(const std::string & filename, const unsigned char * in, unsigned w, unsigned h, @@ -271,15 +316,15 @@ unsigned encode(const std::string & filename, #ifdef LODEPNG_COMPILE_DECODER /*Settings for zlib decompression*/ -typedef struct _LodePNGDecompressSettings LodePNGDecompressSettings; -struct _LodePNGDecompressSettings { +typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; +struct LodePNGDecompressSettings { /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/ /*Maximum decompressed size, beyond this the decoder may (and is encouraged to) stop decoding, return an error, output a data size > max_output_size and all the data up to that point. This is - not hard limit nor a guarantee, but can prevent excessive memory usage. This setting is + neither a hard limit nor a guarantee, but can prevent excessive memory usage. This setting is ignored by the PNG decoder, but is used by the deflate/zlib decoder and can be used by custom ones. Set to 0 to impose no limit (the default).*/ size_t max_output_size; @@ -308,8 +353,8 @@ void lodepng_decompress_settings_init(LodePNGDecompressSettings * settings); Settings for zlib compression. Tweaking these settings tweaks the balance between speed and compression ratio. */ -typedef struct _LodePNGCompressSettings LodePNGCompressSettings; -struct _LodePNGCompressSettings { /*deflate = compress*/ +typedef struct LodePNGCompressSettings LodePNGCompressSettings; +struct LodePNGCompressSettings { /*deflate = compress*/ /*LZ77 related settings*/ unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ @@ -342,7 +387,7 @@ Color mode of an image. Contains all information required to decode the pixel bits to RGBA colors. This information is the same as used in the PNG file format, and is used both for PNG and raw image data in LodePNG. */ -typedef struct _LodePNGColorMode { +typedef struct LodePNGColorMode { /*header (IHDR)*/ LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ @@ -357,8 +402,10 @@ typedef struct _LodePNGColorMode { The alpha channels must be set as well, set them to 255 for opaque images. - When decoding, by default you can ignore this palette, since LodePNG already - fills the palette colors in the pixels of the raw RGBA output. + When decoding, with the default settings you can ignore this palette, since + LodePNG already fills the palette colors in the pixels of the raw RGBA output, + but when decoding to the original PNG color mode it is needed to reconstruct + the colors. The palette is only supported for color type 3. */ @@ -422,7 +469,7 @@ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode * col #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*The information of a Time chunk in PNG.*/ -typedef struct _LodePNGTime { +typedef struct LodePNGTime { unsigned year; /*2 bytes used (0-65535)*/ unsigned month; /*1-12*/ unsigned day; /*1-31*/ @@ -433,7 +480,7 @@ typedef struct _LodePNGTime { #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*Information about the PNG image, except pixels, width and height.*/ -typedef struct _LodePNGInfo { +typedef struct LodePNGInfo { /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ unsigned compression_method;/*compression method of the original file. Always 0.*/ unsigned filter_method; /*filter method of the original file*/ @@ -448,10 +495,12 @@ typedef struct _LodePNGInfo { with values truncated to the bit depth in the unsigned integer. For grayscale and palette PNGs, the value is stored in background_r. The values - in background_g and background_b are then unused. + in background_g and background_b are then unused. The decoder will set them + equal to background_r, the encoder ignores them in this case. - So when decoding, you may get these in a different color mode than the one you requested - for the raw pixels. + When decoding, you may get these in a different color mode than the one you requested + for the raw pixels: the colortype and bitdepth defined by info_png.color, that is the + ones defined in the header of the PNG image, are used. When encoding with auto_convert, you must use the color model defined in info_png.color for these values. The encoder normally ignores info_png.color when auto_convert is on, but will @@ -518,7 +567,7 @@ typedef struct _LodePNGInfo { unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ /* - Color profile related chunks: gAMA, cHRM, sRGB, iCPP + Color profile related chunks: gAMA, cHRM, sRGB, iCPP, sBIT LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please @@ -581,6 +630,45 @@ typedef struct _LodePNGInfo { unsigned char * iccp_profile; unsigned iccp_profile_size; /* The size of iccp_profile in bytes */ + /* + sBIT chunk: significant bits. Optional metadata, only set this if needed. + + If defined, these values give the bit depth of the original data. Since PNG only stores 1, 2, 4, 8 or 16-bit + per channel data, the significant bits value can be used to indicate the original encoded data has another + sample depth, such as 10 or 12. + + Encoders using this value, when storing the pixel data, should use the most significant bits + of the data to store the original bits, and use a good sample depth scaling method such as + "left bit replication" to fill in the least significant bits, rather than fill zeroes. + + Decoders using this value, if able to work with data that's e.g. 10-bit or 12-bit, should right + shift the data to go back to the original bit depth, but decoders are also allowed to ignore + sbit and work e.g. with the 8-bit or 16-bit data from the PNG directly, since thanks + to the encoder contract, the values encoded in PNG are in valid range for the PNG bit depth. + + For grayscale images, sbit_g and sbit_b are not used, and for images that don't use color + type RGBA or grayscale+alpha, sbit_a is not used (it's not used even for palette images with + translucent palette values, or images with color key). The values that are used must be + greater than zero and smaller than or equal to the PNG bit depth. + + The color type from the header in the PNG image defines these used and unused fields: if + decoding with a color mode conversion, such as always decoding to RGBA, this metadata still + only uses the color type of the original PNG, and may e.g. lack the alpha channel info + if the PNG was RGB. When encoding with auto_convert (as well as without), also always the + color model defined in info_png.color determines this. + + NOTE: enabling sbit can hurt compression, because the encoder can then not always use + auto_convert to choose a more optimal color mode for the data, because the PNG format has + strict requirements for the allowed sbit values in combination with color modes. + For example, setting these fields to 10-bit will force the encoder to keep using a 16-bit per channel + color mode, even if the pixel data would in fact fit in a more efficient 8-bit mode. + */ + unsigned sbit_defined; /*is significant bits given? if not, the values below are unused*/ + unsigned sbit_r; /*red or gray component of significant bits*/ + unsigned sbit_g; /*green component of significant bits*/ + unsigned sbit_b; /*blue component of significant bits*/ + unsigned sbit_a; /*alpha component of significant bits*/ + /* End of color profile related chunks */ @@ -645,7 +733,7 @@ unsigned lodepng_convert(unsigned char * out, const unsigned char * in, Settings for the decoder. This contains settings for the PNG and the Zlib decoder, but not the Info settings from the Info structs. */ -typedef struct _LodePNGDecoderSettings { +typedef struct LodePNGDecoderSettings { LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ @@ -682,7 +770,7 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings * settings); #ifdef LODEPNG_COMPILE_ENCODER /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ -typedef enum _LodePNGFilterStrategy { +typedef enum LodePNGFilterStrategy { /*every filter at zero*/ LFS_ZERO = 0, /*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/ @@ -707,7 +795,7 @@ typedef enum _LodePNGFilterStrategy { /*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...), which helps decide which color model to use for encoding. Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ -typedef struct _LodePNGColorStats { +typedef struct LodePNGColorStats { unsigned colored; /*not grayscale*/ unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ @@ -734,7 +822,7 @@ unsigned lodepng_compute_color_stats(LodePNGColorStats * stats, const LodePNGColorMode * mode_in); /*Settings for the encoder.*/ -typedef struct _LodePNGEncoderSettings { +typedef struct LodePNGEncoderSettings { LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ @@ -754,7 +842,11 @@ typedef struct _LodePNGEncoderSettings { const unsigned char * predefined_filters; /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). - If colortype is 3, PLTE is _always_ created.*/ + If colortype is 3, PLTE is always created. If color type is explicitely set + to a grayscale type (1 or 4), this is not done and is ignored. If enabling this, + a palette must be present in the info_png. + NOTE: enabling this may worsen compression if auto_convert is used to choose + optimal color mode, because it cannot use grayscale color modes in this case*/ unsigned force_palette; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*add LodePNG identifier and version as a text chunk, for debugging*/ @@ -770,7 +862,7 @@ void lodepng_encoder_settings_init(LodePNGEncoderSettings * settings); #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) /*The settings, state and information for extended encoding and decoding.*/ -typedef struct _LodePNGState { +typedef struct LodePNGState { #ifdef LODEPNG_COMPILE_DECODER LodePNGDecoderSettings decoder; /*the decoding settings*/ #endif /*LODEPNG_COMPILE_DECODER*/ @@ -808,8 +900,8 @@ unsigned lodepng_inspect(unsigned * w, unsigned * h, #endif /*LODEPNG_COMPILE_DECODER*/ /* -Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it -read in the state. Returns error code on failure. +Reads one metadata chunk (other than IHDR, which is handled by lodepng_inspect) +of the PNG file and outputs what it read in the state. Returns error code on failure. Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const to find the desired chunk type, and if non null use lodepng_inspect_chunk (with chunk_pointer - start_of_file as pos). @@ -915,9 +1007,9 @@ unsigned lodepng_chunk_append(unsigned char ** out, size_t * outsize, const unsi Appends new chunk to out. The chunk to append is given by giving its length, type and data separately. The type is a 4-letter string. The out variable and outsize are updated to reflect the new reallocated buffer. -Return error code (0 if it went ok) +Returne error code (0 if it went ok) */ -unsigned lodepng_chunk_create(unsigned char ** out, size_t * outsize, unsigned length, +unsigned lodepng_chunk_create(unsigned char ** out, size_t * outsize, size_t length, const char * type, const unsigned char * data); @@ -985,6 +1077,9 @@ unsigned lodepng_deflate(unsigned char ** out, size_t * outsize, outsize: output parameter, size of the allocated out buffer filename: the path to the file to load return value: error code (0 means ok) + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and decode in-memory. */ unsigned lodepng_load_file(unsigned char ** out, size_t * outsize, const char * filename); @@ -995,6 +1090,9 @@ unsigned lodepng_deflate(unsigned char ** out, size_t * outsize, buffersize: size of the buffer to write filename: the path to the file to save to return value: error code (0 means ok) + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and encode in-memory */ unsigned lodepng_save_file(const unsigned char * buffer, size_t buffersize, const char * filename); #endif /*LODEPNG_COMPILE_DISK*/ @@ -1037,12 +1135,18 @@ unsigned encode(std::vector & out, /* Load a file from disk into an std::vector. return value: error code (0 means ok) + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and decode in-memory */ unsigned load_file(std::vector & buffer, const std::string & filename); /* Save the binary data in an std::vector to a file on disk. The file is overwritten without warning. + + NOTE: Wide-character filenames are not supported, you can use an external method + to handle such files and encode in-memory */ unsigned save_file(const std::vector & buffer, const std::string & filename); #endif /* LODEPNG_COMPILE_DISK */ @@ -1078,7 +1182,7 @@ TODO: [.] check compatibility with various compilers - done but needs to be redone for every newer version [X] converting color to 16-bit per channel types [X] support color profile chunk types (but never let them touch RGB values by default) -[ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST) +[ ] support all public PNG chunk types (almost done except sPLT and hIST) [ ] make sure encoder generates no chunks with size > (2^31)-1 [ ] partial decoding (stream processing) [X] let the "isFullyOpaque" function check color keys and transparent palettes too @@ -1188,7 +1292,7 @@ The following features are supported by the decoder: *) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image *) Adam7 interlace and deinterlace for any color type *) loading the image from harddisk or decoding it from a buffer from other sources than harddisk -*) support for alpha channels, including RGBA color modelete,translucent palettes and color keying +*) support for alpha channels, including RGBA color model, translucent palettes and color keying *) zlib decompression (inflate) *) zlib compression (deflate) *) CRC32 and ADLER32 checksums @@ -1211,18 +1315,16 @@ The following features are supported by the decoder: gAMA: RGB gamma correction iCCP: ICC color profile sRGB: rendering intent + sBIT: significant bits 1.2. features not supported --------------------------- -The following features are _not_ supported: +The following features are not (yet) supported: *) some features needed to make a conformant PNG-Editor might be still missing. *) partial loading/stream processing. All data must be available and is processed in one call. -*) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG: - sBIT - hIST - sPLT +*) The hIST and sPLT public chunks are not (yet) supported but treated as unknown chunks 2. C and C++ version @@ -1726,6 +1828,9 @@ try to fix it if the compiler is modern and standards compliant. This decoder example shows the most basic usage of LodePNG. More complex examples can be found on the LodePNG website. +NOTE: these examples do not support wide-character filenames, you can use an +external method to handle such files and encode or decode in-memory + 10.1. decoder C++ example ------------------------- @@ -1785,7 +1890,7 @@ state.decoder.remember_unknown_chunks: whether to read in unknown chunks state.info_raw.colortype: desired color type for decoded image state.info_raw.bitdepth: desired bit depth for decoded image state.info_raw....: more color settings, see struct LodePNGColorMode -state.info_png....: no settings for decoder but output, see struct LodePNGInfo +state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo For encoding: @@ -1823,6 +1928,12 @@ symbol. Not all changes are listed here, the commit history in github lists more: https://github.com/lvandeve/lodepng +*) 10 apr 2023: faster CRC32 implementation, but with larger lookup table. +*) 13 jun 2022: added support for the sBIT chunk. +*) 09 jan 2022: minor decoder speed improvements. +*) 27 jun 2021: added warnings that file reading/writing functions don't support + wide-character filenames (support for this is not planned, opening files is + not the core part of PNG decoding/decoding and is platform dependent). *) 17 okt 2020: prevent decoding too large text/icc chunks by default. *) 06 mar 2020: simplified some of the dynamic memory allocations. *) 12 jan 2020: (!) added 'end' argument to lodepng_chunk_next to allow correct @@ -1990,5 +2101,5 @@ Domain: gmail dot com. Account: lode dot vandevenne. -Copyright (c) 2005-2020 Lode Vandevenne +Copyright (c) 2005-2022 Lode Vandevenne */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lv_lodepng.c b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lv_lodepng.c index 34b3bef87..e5b55de2b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lv_lodepng.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lv_lodepng.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ +#include "../../draw/lv_image_decoder_private.h" #include "../../../lvgl.h" +#include "../../core/lv_global.h" #if LV_USE_LODEPNG #include "lv_lodepng.h" @@ -17,6 +19,10 @@ * DEFINES *********************/ +#define DECODER_NAME "LODEPNG" + +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -24,7 +30,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * src, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static void decoder_close(lv_image_decoder_t * dec, lv_image_decoder_dsc_t * dsc); static void convert_color_depth(uint8_t * img_p, uint32_t px_cnt); @@ -50,6 +56,8 @@ void lv_lodepng_init(void) lv_image_decoder_set_info_cb(dec, decoder_info); lv_image_decoder_set_open_cb(dec, decoder_open); lv_image_decoder_set_close_cb(dec, decoder_close); + + dec->name = DECODER_NAME; } void lv_lodepng_deinit(void) @@ -70,70 +78,51 @@ void lv_lodepng_deinit(void) /** * Get info about a PNG image * @param decoder pointer to the decoder where this function belongs - * @param src can be file name or pointer to a C array + * @param dsc image descriptor containing the source and type of the image and other info. * @param header image information is set in header parameter * @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info */ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { - (void) decoder; /*Unused*/ - lv_image_src_t src_type = lv_image_src_get_type(src); /*Get the source type*/ + LV_UNUSED(decoder); /*Unused*/ - /*If it's a PNG file...*/ - if(src_type == LV_IMAGE_SRC_FILE) { - const char * fn = src; - if(lv_strcmp(lv_fs_get_ext(fn), "png") == 0) { /*Check the extension*/ + lv_image_src_t src_type = dsc->src_type; /*Get the source type*/ + if(src_type == LV_IMAGE_SRC_FILE || src_type == LV_IMAGE_SRC_VARIABLE) { + uint32_t * size; + static const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; + uint8_t buf[24]; + + /*If it's a PNG file...*/ + if(src_type == LV_IMAGE_SRC_FILE) { /* Read the width and height from the file. They have a constant location: - * [16..23]: width - * [24..27]: height - */ - uint32_t size[2]; - lv_fs_file_t f; - lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) return LV_RESULT_INVALID; - - lv_fs_seek(&f, 16, LV_FS_SEEK_SET); - + * [16..19]: width + * [20..23]: height + */ uint32_t rn; - lv_fs_read(&f, &size, 8, &rn); - lv_fs_close(&f); + lv_fs_read(&dsc->file, buf, sizeof(buf), &rn); - if(rn != 8) return LV_RESULT_INVALID; + if(rn != sizeof(buf)) return LV_RESULT_INVALID; - /*Save the data in the header*/ - header->cf = LV_COLOR_FORMAT_ARGB8888; - /*The width and height are stored in Big endian format so convert them to little endian*/ - header->w = (int32_t)((size[0] & 0xff000000) >> 24) + ((size[0] & 0x00ff0000) >> 8); - header->h = (int32_t)((size[1] & 0xff000000) >> 24) + ((size[1] & 0x00ff0000) >> 8); + if(lv_memcmp(buf, magic, sizeof(magic)) != 0) return LV_RESULT_INVALID; - return LV_RESULT_OK; + size = (uint32_t *)&buf[16]; } - } - /*If it's a PNG file in a C array...*/ - else if(src_type == LV_IMAGE_SRC_VARIABLE) { - const lv_image_dsc_t * img_dsc = src; - const uint32_t data_size = img_dsc->data_size; - const uint32_t * size = ((uint32_t *)img_dsc->data) + 4; - const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; - if(data_size < sizeof(magic)) return LV_RESULT_INVALID; - if(memcmp(magic, img_dsc->data, sizeof(magic))) return LV_RESULT_INVALID; + /*If it's a PNG file in a C array...*/ + else { + const lv_image_dsc_t * img_dsc = dsc->src; + const uint32_t data_size = img_dsc->data_size; + size = ((uint32_t *)img_dsc->data) + 4; + if(data_size < sizeof(magic)) return LV_RESULT_INVALID; + if(lv_memcmp(img_dsc->data, magic, sizeof(magic)) != 0) return LV_RESULT_INVALID; + } + + /*Save the data in the header*/ header->cf = LV_COLOR_FORMAT_ARGB8888; - - if(img_dsc->header.w) { - header->w = img_dsc->header.w; /*Save the image width*/ - } - else { - header->w = (int32_t)((size[0] & 0xff000000) >> 24) + ((size[0] & 0x00ff0000) >> 8); - } - - if(img_dsc->header.h) { - header->h = img_dsc->header.h; /*Save the color height*/ - } - else { - header->h = (int32_t)((size[1] & 0xff000000) >> 24) + ((size[1] & 0x00ff0000) >> 8); - } + /*The width and height are stored in Big endian format so convert them to little endian*/ + header->w = (int32_t)((size[0] & 0xff000000) >> 24) + ((size[0] & 0x00ff0000) >> 8); + header->h = (int32_t)((size[1] & 0xff000000) >> 24) + ((size[1] & 0x00ff0000) >> 8); return LV_RESULT_OK; } @@ -181,7 +170,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(dsc->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)png_data); if(!decoded) { - LV_LOG_WARN("Error decoding PNG\n"); + LV_LOG_WARN("Error decoding PNG"); return LV_RESULT_INVALID; } @@ -199,9 +188,12 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d dsc->decoded = decoded; - if(dsc->args.no_cache) return LV_RES_OK; + if(dsc->args.no_cache) return LV_RESULT_OK; -#if LV_CACHE_DEF_SIZE > 0 + /*If the image cache is disabled, just return the decoded image*/ + if(!lv_image_cache_is_enabled()) return LV_RESULT_OK; + + /*Add the decoded image to the cache*/ lv_image_cache_data_t search_key; search_key.src_type = dsc->src_type; search_key.src = dsc->src; @@ -213,7 +205,6 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d return LV_RESULT_INVALID; } dsc->cache_entry = entry; -#endif return LV_RESULT_OK; /*If not returned earlier then it failed*/ } @@ -228,10 +219,8 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * { LV_UNUSED(decoder); - if(dsc->args.no_cache || LV_CACHE_DEF_SIZE == 0) - lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); - else - lv_cache_release(dsc->cache, dsc->cache_entry, NULL); + if(dsc->args.no_cache || + !lv_image_cache_is_enabled()) lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); } static lv_draw_buf_t * decode_png_data(const void * png_data, size_t png_data_size) diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h b/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h index 72080233e..ce763af13 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h @@ -76,7 +76,7 @@ extern "C" { metadata includes block's compressed size, and maximum bound of decompressed size. Each application is free to encode and pass such metadata in whichever way it wants. - lz4.h only handle blocks, it can not generate Frames. + lz4.h only handle blocks, it cannot generate Frames. Blocks are different from Frames (doc/lz4_Frame_format.md). Frames bundle both blocks and metadata in a specified manner. @@ -592,7 +592,7 @@ LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const c * Alternatively, the provided dictionaryStream may be NULL, * in which case any existing dictionary stream is unset. * - * If a dictionary is provided, it replaces any pre-existing stream history. + * If a dictionary is provided, it replaces any preexisting stream history. * The dictionary contents are the only history that can be referenced and * logically immediately precede the data compressed in the first subsequent * compression call. diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.c b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.c index 08f44b342..f4b5b5456 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "../../lvgl.h" +#include "../../core/lv_obj_class_private.h" +#include "lv_qrcode_private.h" #if LV_USE_QRCODE @@ -70,7 +71,7 @@ void lv_qrcode_set_size(lv_obj_t * obj, int32_t size) LV_LOG_INFO("set canvas buffer: %p, size = %d", (void *)new_buf, (int)size); /*Clear canvas buffer*/ - lv_canvas_fill_bg(obj, lv_color_white(), LV_OPA_COVER); + lv_draw_buf_clear(new_buf, NULL); if(old_buf != NULL) lv_draw_buf_destroy(old_buf); } @@ -100,10 +101,12 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le return LV_RESULT_INVALID; } - lv_canvas_set_palette(obj, 0, lv_color_to_32(qrcode->dark_color, 0xff)); - lv_canvas_set_palette(obj, 1, lv_color_to_32(qrcode->light_color, 0xff)); - lv_color_t c = lv_color_hex(1); - lv_canvas_fill_bg(obj, c, LV_OPA_COVER); + lv_draw_buf_clear(draw_buf, NULL); + lv_canvas_set_palette(obj, 0, lv_color_to_32(qrcode->light_color, LV_OPA_COVER)); + lv_canvas_set_palette(obj, 1, lv_color_to_32(qrcode->dark_color, LV_OPA_COVER)); + lv_image_cache_drop(draw_buf); + + lv_obj_invalidate(obj); if(data_len > qrcodegen_BUFFER_LEN_MAX) return LV_RESULT_INVALID; @@ -140,12 +143,16 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le return LV_RESULT_INVALID; } + /* Temporarily disable invalidation to improve the efficiency of lv_canvas_set_px */ + lv_display_enable_invalidation(lv_obj_get_display(obj), false); + int32_t obj_w = draw_buf->header.w; qr_size = qrcodegen_getSize(qr0); scale = obj_w / qr_size; int scaled = qr_size * scale; int margin = (obj_w - scaled) / 2; uint8_t * buf_u8 = (uint8_t *)draw_buf->data + 8; /*+8 skip the palette*/ + lv_color_t c = lv_color_hex(1); /* Copy the qr code canvas: * A simple `lv_canvas_set_px` would work but it's slow for so many pixels. @@ -163,15 +170,16 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le if(aligned == false && (x & 0x7) == 0) aligned = true; if(aligned == false) { - c = lv_color_hex(a ? 0 : 1); - lv_canvas_set_px(obj, x, y, c, LV_OPA_COVER); + if(a) { + lv_canvas_set_px(obj, x, y, c, LV_OPA_COVER); + } } else { if(!a) b |= (1 << (7 - p)); p++; if(p == 8) { uint32_t px = row_byte_cnt * y + (x >> 3); - buf_u8[px] = b; + buf_u8[px] = ~b; b = 0; p = 0; } @@ -184,7 +192,7 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le b |= (1 << (8 - p)) - 1; uint32_t px = row_byte_cnt * y + (x >> 3); - buf_u8[px] = b; + buf_u8[px] = ~b; } /*The Qr is probably scaled so simply to the repeated rows*/ @@ -195,6 +203,9 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le } } + /* invalidate the canvas to refresh it */ + lv_display_enable_invalidation(lv_obj_get_display(obj), true); + lv_free(qr0); lv_free(data_tmp); return LV_RESULT_OK; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.h b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.h index aed84fd7c..ba9b0e869 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.h @@ -1,5 +1,5 @@ /** - * @file lv_qrcode + * @file lv_qrcode.h * */ @@ -14,6 +14,11 @@ extern "C" { * INCLUDES *********************/ #include "../../lv_conf_internal.h" +#include "../../misc/lv_color.h" +#include "../../misc/lv_types.h" +#include "../../widgets/canvas/lv_canvas.h" +#include LV_STDBOOL_INCLUDE +#include LV_STDINT_INCLUDE #if LV_USE_QRCODE /********************* @@ -24,13 +29,6 @@ extern "C" { * TYPEDEFS **********************/ -/*Data of qrcode*/ -typedef struct { - lv_canvas_t canvas; - lv_color_t dark_color; - lv_color_t light_color; -} lv_qrcode_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_qrcode_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode_private.h b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode_private.h new file mode 100644 index 000000000..b912d6575 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_qrcode_private.h + * + */ + +#ifndef LV_QRCODE_PRIVATE_H +#define LV_QRCODE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../widgets/canvas/lv_canvas_private.h" +#include "lv_qrcode.h" + +#if LV_USE_QRCODE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of qrcode*/ +struct lv_qrcode_t { + lv_canvas_t canvas; + lv_color_t dark_color; + lv_color_t light_color; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_QRCODE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_QRCODE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.c b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.c index 8f71f4724..f501a248f 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.c @@ -21,11 +21,13 @@ * Software. */ +#include "qrcodegen.h" +#include "../../misc/lv_assert.h" + +#if LV_USE_QRCODE #include #include #include -#include "qrcodegen.h" -#include "../../misc/lv_assert.h" #ifndef QRCODEGEN_TEST #define testable static // Keep functions private @@ -1111,3 +1113,4 @@ int qrcodegen_version2size(int version) return ((version - 1) * 4 + 21); } +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h index 986bada58..950948684 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h @@ -23,6 +23,9 @@ #pragma once +#include "../../../lvgl.h" +#ifdef LV_USE_QRCODE + #include #include #include @@ -317,3 +320,5 @@ int qrcodegen_getMinFitVersion(enum qrcodegen_Ecc ecl, size_t dataLen); #ifdef __cplusplus } #endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.c b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.c index f595215f5..3c723ec0f 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.c @@ -9,7 +9,10 @@ #include "../../lvgl.h" #if LV_USE_RLOTTIE +#include "lv_rlottie_private.h" +#include "../../core/lv_obj_class_private.h" #include +#include /********************* * DEFINES @@ -120,7 +123,7 @@ static void lv_rlottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob rlottie->animation = lottie_animation_from_file(create_info.path); } if(rlottie->animation == NULL) { - LV_LOG_WARN("The aniamtion can't be opened"); + LV_LOG_WARN("The animation can't be opened"); return; } @@ -130,18 +133,18 @@ static void lv_rlottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob rlottie->scanline_width = create_info.width * LV_ARGB32 / 8; - size_t allocaled_buf_size = (create_info.width * create_info.height * LV_ARGB32 / 8); - rlottie->allocated_buf = lv_malloc(allocaled_buf_size); + size_t allocated_buf_size = (create_info.width * create_info.height * LV_ARGB32 / 8); + rlottie->allocated_buf = lv_malloc(allocated_buf_size); if(rlottie->allocated_buf != NULL) { - rlottie->allocated_buffer_size = allocaled_buf_size; - memset(rlottie->allocated_buf, 0, allocaled_buf_size); + rlottie->allocated_buffer_size = allocated_buf_size; + memset(rlottie->allocated_buf, 0, allocated_buf_size); } rlottie->imgdsc.header.cf = LV_COLOR_FORMAT_ARGB8888; rlottie->imgdsc.header.h = create_info.height; rlottie->imgdsc.header.w = create_info.width; rlottie->imgdsc.data = (void *)rlottie->allocated_buf; - rlottie->imgdsc.data_size = allocaled_buf_size; + rlottie->imgdsc.data_size = allocated_buf_size; lv_image_set_src(obj, &rlottie->imgdsc); @@ -186,7 +189,7 @@ static void lv_rlottie_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj static void next_frame_task_cb(lv_timer_t * t) { - lv_obj_t * obj = t->user_data; + lv_obj_t * obj = lv_timer_get_user_data(t); lv_rlottie_t * rlottie = (lv_rlottie_t *) obj; if((rlottie->play_ctrl & LV_RLOTTIE_CTRL_PAUSE) == LV_RLOTTIE_CTRL_PAUSE) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.h b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.h index f9ab93ff7..44bcf2ef4 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.h @@ -31,23 +31,6 @@ typedef enum { LV_RLOTTIE_CTRL_LOOP = 8, } lv_rlottie_ctrl_t; -/** definition in lottieanimation_capi.c */ -struct Lottie_Animation_S; -typedef struct { - lv_image_t img_ext; - struct Lottie_Animation_S * animation; - lv_timer_t * task; - lv_image_dsc_t imgdsc; - size_t total_frames; - size_t current_frame; - size_t framerate; - uint32_t * allocated_buf; - size_t allocated_buffer_size; - size_t scanline_width; - lv_rlottie_ctrl_t play_ctrl; - size_t dest_frame; -} lv_rlottie_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_rlottie_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie_private.h b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie_private.h new file mode 100644 index 000000000..91587bd6c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie_private.h @@ -0,0 +1,61 @@ +/** + * @file lv_rlottie_private.h + * + */ + +#ifndef LV_RLOTTIE_PRIVATE_H +#define LV_RLOTTIE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_rlottie.h" +#if LV_USE_RLOTTIE +#include "../../widgets/image/lv_image_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** definition in lottieanimation_capi.c */ +struct Lottie_Animation_S; + +struct lv_rlottie_t { + lv_image_t img_ext; + struct Lottie_Animation_S * animation; + lv_timer_t * task; + lv_image_dsc_t imgdsc; + size_t total_frames; + size_t current_frame; + size_t framerate; + uint32_t * allocated_buf; + size_t allocated_buffer_size; + size_t scanline_width; + lv_rlottie_ctrl_t play_ctrl; + size_t dest_frame; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_RLOTTIE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RLOTTIE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/config.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/config.h index abeed9415..baa258a4f 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/config.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/config.h @@ -5,11 +5,11 @@ #pragma once -#define THORVG_CAPI_BINDING_SUPPORT 1 - -#define THORVG_SVG_LOADER_SUPPORT 1 - #define THORVG_SW_RASTER_SUPPORT 1 -#define THORVG_VERSION_STRING "0.11.99" +#define THORVG_SVG_LOADER_SUPPORT LV_USE_LOTTIE + +#define THORVG_LOTTIE_LOADER_SUPPORT LV_USE_LOTTIE + +#define THORVG_VERSION_STRING "0.13.5" diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/allocators.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/allocators.h new file mode 100644 index 000000000..a943cf199 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/allocators.h @@ -0,0 +1,693 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" +#include "internal/meta.h" + +#include +#include + +#if RAPIDJSON_HAS_CXX11 +#include +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + + +/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY + \ingroup RAPIDJSON_CONFIG + \brief User-defined kDefaultChunkCapacity definition. + + User can define this as any \c size that is a power of 2. +*/ + +#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY +#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024) +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { + if (size) // behavior of malloc(0) is implementation defined. + return RAPIDJSON_MALLOC(size); + else + return NULL; // standardize to returning NULL. + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + (void)originalSize; + if (newSize == 0) { + RAPIDJSON_FREE(originalPtr); + return NULL; + } + return RAPIDJSON_REALLOC(originalPtr, newSize); + } + static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); } + + bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT { + return true; + } + bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT { + return false; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template +class MemoryPoolAllocator { + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + struct SharedData { + ChunkHeader *chunkHead; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + BaseAllocator* ownBaseAllocator; //!< base allocator created by this object. + size_t refcount; + bool ownBuffer; + }; + + static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData)); + static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader)); + + static inline ChunkHeader *GetChunkHead(SharedData *shared) + { + return reinterpret_cast(reinterpret_cast(shared) + SIZEOF_SHARED_DATA); + } + static inline uint8_t *GetChunkBuffer(SharedData *shared) + { + return reinterpret_cast(shared->chunkHead) + SIZEOF_CHUNK_HEADER; + } + + static const size_t kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity. + +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + static const bool kRefCounted = true; //!< Tell users that this allocator is reference counted on copy + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + explicit + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunk_capacity_(chunkSize), + baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()), + shared_(static_cast(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0)) + { + RAPIDJSON_ASSERT(baseAllocator_ != 0); + RAPIDJSON_ASSERT(shared_ != 0); + if (baseAllocator) { + shared_->ownBaseAllocator = 0; + } + else { + shared_->ownBaseAllocator = baseAllocator_; + } + shared_->chunkHead = GetChunkHead(shared_); + shared_->chunkHead->capacity = 0; + shared_->chunkHead->size = 0; + shared_->chunkHead->next = 0; + shared_->ownBuffer = true; + shared_->refcount = 1; + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunk_capacity_(chunkSize), + baseAllocator_(baseAllocator), + shared_(static_cast(AlignBuffer(buffer, size))) + { + RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER); + shared_->chunkHead = GetChunkHead(shared_); + shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER; + shared_->chunkHead->size = 0; + shared_->chunkHead->next = 0; + shared_->ownBaseAllocator = 0; + shared_->ownBuffer = false; + shared_->refcount = 1; + } + + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT : + chunk_capacity_(rhs.chunk_capacity_), + baseAllocator_(rhs.baseAllocator_), + shared_(rhs.shared_) + { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + ++shared_->refcount; + } + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT + { + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + ++rhs.shared_->refcount; + this->~MemoryPoolAllocator(); + baseAllocator_ = rhs.baseAllocator_; + chunk_capacity_ = rhs.chunk_capacity_; + shared_ = rhs.shared_; + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT : + chunk_capacity_(rhs.chunk_capacity_), + baseAllocator_(rhs.baseAllocator_), + shared_(rhs.shared_) + { + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + rhs.shared_ = 0; + } + MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT + { + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + this->~MemoryPoolAllocator(); + baseAllocator_ = rhs.baseAllocator_; + chunk_capacity_ = rhs.chunk_capacity_; + shared_ = rhs.shared_; + rhs.shared_ = 0; + return *this; + } +#endif + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT { + if (!shared_) { + // do nothing if moved + return; + } + if (shared_->refcount > 1) { + --shared_->refcount; + return; + } + Clear(); + BaseAllocator *a = shared_->ownBaseAllocator; + if (shared_->ownBuffer) { + baseAllocator_->Free(shared_); + } + RAPIDJSON_DELETE(a); + } + + //! Deallocates all memory chunks, excluding the first/user one. + void Clear() RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + for (;;) { + ChunkHeader* c = shared_->chunkHead; + if (!c->next) { + break; + } + shared_->chunkHead = c->next; + baseAllocator_->Free(c); + } + shared_->chunkHead->size = 0; + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + size_t capacity = 0; + for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + size_t size = 0; + for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Whether the allocator is shared. + /*! \return true or false. + */ + bool Shared() const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + return shared_->refcount > 1; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + if (!size) + return NULL; + + size = RAPIDJSON_ALIGN(size); + if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity)) + if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) + return NULL; + + void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size; + shared_->chunkHead->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + if (newSize == 0) + return NULL; + + originalSize = RAPIDJSON_ALIGN(originalSize); + newSize = RAPIDJSON_ALIGN(newSize); + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) { + size_t increment = static_cast(newSize - originalSize); + if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) { + shared_->chunkHead->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + if (void* newBuffer = Malloc(newSize)) { + if (originalSize) + std::memcpy(newBuffer, originalPtr, originalSize); + return newBuffer; + } + else + return NULL; + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; } // Do nothing + + //! Compare (equality) with another MemoryPoolAllocator + bool operator==(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT { + RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0); + RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0); + return shared_ == rhs.shared_; + } + //! Compare (inequality) with another MemoryPoolAllocator + bool operator!=(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT { + return !operator==(rhs); + } + +private: + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + \return true if success. + */ + bool AddChunk(size_t capacity) { + if (!baseAllocator_) + shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)(); + if (ChunkHeader* chunk = static_cast(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) { + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = shared_->chunkHead; + shared_->chunkHead = chunk; + return true; + } + else + return false; + } + + static inline void* AlignBuffer(void* buf, size_t &size) + { + RAPIDJSON_NOEXCEPT_ASSERT(buf != 0); + const uintptr_t mask = sizeof(void*) - 1; + const uintptr_t ubuf = reinterpret_cast(buf); + if (RAPIDJSON_UNLIKELY(ubuf & mask)) { + const uintptr_t abuf = (ubuf + mask) & ~mask; + RAPIDJSON_ASSERT(size >= abuf - ubuf); + buf = reinterpret_cast(abuf); + size -= abuf - ubuf; + } + return buf; + } + + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + SharedData *shared_; //!< The shared data of the allocator +}; + +namespace internal { + template + struct IsRefCounted : + public FalseType + { }; + template + struct IsRefCounted::Type> : + public TrueType + { }; +} + +template +inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n) +{ + RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits::max)() / sizeof(T) && new_n <= (std::numeric_limits::max)() / sizeof(T)); + return static_cast(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T))); +} + +template +inline T *Malloc(A& a, size_t n = 1) +{ + return Realloc(a, NULL, 0, n); +} + +template +inline void Free(A& a, T *p, size_t n = 1) +{ + static_cast(Realloc(a, p, n, 0)); +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited +#endif + +template +class StdAllocator : + public std::allocator +{ + typedef std::allocator allocator_type; +#if RAPIDJSON_HAS_CXX11 + typedef std::allocator_traits traits_type; +#else + typedef allocator_type traits_type; +#endif + +public: + typedef BaseAllocator BaseAllocatorType; + + StdAllocator() RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_() + { } + + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + + template + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(std::move(rhs)), + baseAllocator_(std::move(rhs.baseAllocator_)) + { } +#endif +#if RAPIDJSON_HAS_CXX11 + using propagate_on_container_move_assignment = std::true_type; + using propagate_on_container_swap = std::true_type; +#endif + + /* implicit */ + StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_(allocator) + { } + + ~StdAllocator() RAPIDJSON_NOEXCEPT + { } + + template + struct rebind { + typedef StdAllocator other; + }; + + typedef typename traits_type::size_type size_type; + typedef typename traits_type::difference_type difference_type; + + typedef typename traits_type::value_type value_type; + typedef typename traits_type::pointer pointer; + typedef typename traits_type::const_pointer const_pointer; + +#if RAPIDJSON_HAS_CXX11 + + typedef typename std::add_lvalue_reference::type &reference; + typedef typename std::add_lvalue_reference::type>::type &const_reference; + + pointer address(reference r) const RAPIDJSON_NOEXCEPT + { + return std::addressof(r); + } + const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT + { + return std::addressof(r); + } + + size_type max_size() const RAPIDJSON_NOEXCEPT + { + return traits_type::max_size(*this); + } + + template + void construct(pointer p, Args&&... args) + { + traits_type::construct(*this, p, std::forward(args)...); + } + void destroy(pointer p) + { + traits_type::destroy(*this, p); + } + +#else // !RAPIDJSON_HAS_CXX11 + + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + + pointer address(reference r) const RAPIDJSON_NOEXCEPT + { + return allocator_type::address(r); + } + const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT + { + return allocator_type::address(r); + } + + size_type max_size() const RAPIDJSON_NOEXCEPT + { + return allocator_type::max_size(); + } + + void construct(pointer p, const_reference r) + { + allocator_type::construct(p, r); + } + void destroy(pointer p) + { + allocator_type::destroy(p); + } + +#endif // !RAPIDJSON_HAS_CXX11 + + template + U* allocate(size_type n = 1, const void* = 0) + { + return RAPIDJSON_NAMESPACE::Malloc(baseAllocator_, n); + } + template + void deallocate(U* p, size_type n = 1) + { + RAPIDJSON_NAMESPACE::Free(baseAllocator_, p, n); + } + + pointer allocate(size_type n = 1, const void* = 0) + { + return allocate(n); + } + void deallocate(pointer p, size_type n = 1) + { + deallocate(p, n); + } + +#if RAPIDJSON_HAS_CXX11 + using is_always_equal = std::is_empty; +#endif + + template + bool operator==(const StdAllocator& rhs) const RAPIDJSON_NOEXCEPT + { + return baseAllocator_ == rhs.baseAllocator_; + } + template + bool operator!=(const StdAllocator& rhs) const RAPIDJSON_NOEXCEPT + { + return !operator==(rhs); + } + + //! rapidjson Allocator concept + static const bool kNeedFree = BaseAllocator::kNeedFree; + static const bool kRefCounted = internal::IsRefCounted::Value; + void* Malloc(size_t size) + { + return baseAllocator_.Malloc(size); + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) + { + return baseAllocator_.Realloc(originalPtr, originalSize, newSize); + } + static void Free(void *ptr) RAPIDJSON_NOEXCEPT + { + BaseAllocator::Free(ptr); + } + +private: + template + friend class StdAllocator; // access to StdAllocator.* + + BaseAllocator baseAllocator_; +}; + +#if !RAPIDJSON_HAS_CXX17 // std::allocator deprecated in C++17 +template +class StdAllocator : + public std::allocator +{ + typedef std::allocator allocator_type; + +public: + typedef BaseAllocator BaseAllocatorType; + + StdAllocator() RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_() + { } + + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + + template + StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT : + allocator_type(rhs), + baseAllocator_(rhs.baseAllocator_) + { } + + /* implicit */ + StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT : + allocator_type(), + baseAllocator_(baseAllocator) + { } + + ~StdAllocator() RAPIDJSON_NOEXCEPT + { } + + template + struct rebind { + typedef StdAllocator other; + }; + + typedef typename allocator_type::value_type value_type; + +private: + template + friend class StdAllocator; // access to StdAllocator.* + + BaseAllocator baseAllocator_; +}; +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/cursorstreamwrapper.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/cursorstreamwrapper.h new file mode 100644 index 000000000..fd6513db1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/cursorstreamwrapper.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ +#define RAPIDJSON_CURSORSTREAMWRAPPER_H_ + +#include "stream.h" + +#if defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4702) // unreachable code +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + + +//! Cursor stream wrapper for counting line and column number if error exists. +/*! + \tparam InputStream Any stream that implements Stream Concept +*/ +template > +class CursorStreamWrapper : public GenericStreamWrapper { +public: + typedef typename Encoding::Ch Ch; + + CursorStreamWrapper(InputStream& is): + GenericStreamWrapper(is), line_(1), col_(0) {} + + // counting line and column number + Ch Take() { + Ch ch = this->is_.Take(); + if(ch == '\n') { + line_ ++; + col_ = 0; + } else { + col_ ++; + } + return ch; + } + + //! Get the error line number, if error exists. + size_t GetLine() const { return line_; } + //! Get the error column number, if error exists. + size_t GetColumn() const { return col_; } + +private: + size_t line_; //!< Current Line + size_t col_; //!< Current Column +}; + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_POP +#endif + +#if defined(__GNUC__) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/document.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/document.h new file mode 100644 index 000000000..f18fbd5f5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/document.h @@ -0,0 +1,3043 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include "memorystream.h" +#include "encodedstream.h" +#include // placement new +#include +#ifdef __cpp_lib_three_way_comparison +#include +#endif + +RAPIDJSON_DIAG_PUSH +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(c++98-compat) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_OFF(effc++) +#endif // __GNUC__ + +#ifdef GetObject +// see https://github.com/Tencent/rapidjson/issues/1448 +// a former included windows.h might have defined a macro called GetObject, which affects +// GetObject defined here. This ensures the macro does not get applied +#pragma push_macro("GetObject") +#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED +#undef GetObject +#endif + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include // std::random_access_iterator_tag +#endif + +#if RAPIDJSON_USE_MEMBERSMAP +#include // std::multimap +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +// Forward declaration. +template +class GenericValue; + +template +class GenericDocument; + +/*! \def RAPIDJSON_DEFAULT_ALLOCATOR + \ingroup RAPIDJSON_CONFIG + \brief Allows to choose default allocator. + + User can define this to use CrtAllocator or MemoryPoolAllocator. +*/ +#ifndef RAPIDJSON_DEFAULT_ALLOCATOR +#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator> +#endif + +/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR + \ingroup RAPIDJSON_CONFIG + \brief Allows to choose default stack allocator for Document. + + User can define this to use CrtAllocator or MemoryPoolAllocator. +*/ +#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR +#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator +#endif + +/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY + \ingroup RAPIDJSON_CONFIG + \brief User defined kDefaultObjectCapacity value. + + User can define this as any natural number. +*/ +#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY +// number of objects that rapidjson::Value allocates memory for by default +#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16 +#endif + +/*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY + \ingroup RAPIDJSON_CONFIG + \brief User defined kDefaultArrayCapacity value. + + User can define this as any natural number. +*/ +#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY +// number of array elements that rapidjson::Value allocates memory for by default +#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16 +#endif + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template +class GenericMember { +public: + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT + : name(std::move(rhs.name)), + value(std::move(rhs.value)) + { + } + + //! Move assignment in C++11 + GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT { + return *this = static_cast(rhs); + } +#endif + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. Its name and value will become a null value after assignment. + */ + GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT { + if (RAPIDJSON_LIKELY(this != &rhs)) { + name = rhs.name; + value = rhs.value; + } + return *this; + } + + // swap() for std::sort() and other potential use in STL. + friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT { + a.name.Swap(b.name); + a.value.Swap(b.value); + } + +private: + //! Copy constructor is not permitted. + GenericMember(const GenericMember& rhs); +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template +class GenericMemberIterator { + + friend class GenericValue; + template friend class GenericMemberIterator; + + typedef GenericMember PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator NonConstIterator; + + /** \name std::iterator_traits support */ + //@{ + typedef ValueType value_type; + typedef ValueType * pointer; + typedef ValueType & reference; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; + //@} + + //! Pointer to (const) GenericMember + typedef pointer Pointer; + //! Reference to (const) GenericMember + typedef reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + template bool operator==(const GenericMemberIterator& that) const { return ptr_ == that.ptr_; } + template bool operator!=(const GenericMemberIterator& that) const { return ptr_ != that.ptr_; } + template bool operator<=(const GenericMemberIterator& that) const { return ptr_ <= that.ptr_; } + template bool operator>=(const GenericMemberIterator& that) const { return ptr_ >= that.ptr_; } + template bool operator< (const GenericMemberIterator& that) const { return ptr_ < that.ptr_; } + template bool operator> (const GenericMemberIterator& that) const { return ptr_ > that.ptr_; } + +#ifdef __cpp_lib_three_way_comparison + template std::strong_ordering operator<=>(const GenericMemberIterator& that) const { return ptr_ <=> that.ptr_; } +#endif + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template +class GenericMemberIterator; + +//! non-const GenericMemberIterator +template +class GenericMemberIterator { +public: + //! use plain pointer as iterator type + typedef GenericMember* Iterator; +}; +//! const GenericMemberIterator +template +class GenericMemberIterator { +public: + //! use plain const pointer as iterator type + typedef const GenericMember* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array +#ifndef __clang__ // -Wdocumentation + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + template + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer +#ifndef __clang__ // -Wdocumentation + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + explicit GenericStringRef(const CharType* str) + : s(str), length(NotNullStrLen(str)) {} + + //! Create constant string reference from pointer and length +#ifndef __clang__ // -Wdocumentation + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ +#endif + GenericStringRef(const CharType* str, SizeType len) + : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); } + + GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + SizeType NotNullStrLen(const CharType* str) { + RAPIDJSON_ASSERT(str != 0); + return internal::StrLen(str); + } + + /// Empty string - used when passing in a NULL pointer + static const Ch emptyString[]; + + //! Disallow construction from non-const array + template + GenericStringRef(CharType (&str)[N]) /* = delete */; + //! Copy assignment operator not permitted - immutable type + GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */; +}; + +template +const CharType GenericStringRef::emptyString[] = { CharType() }; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template +inline GenericStringRef StringRef(const CharType* str) { + return GenericStringRef(str); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template +inline GenericStringRef StringRef(const CharType* str, size_t length) { + return GenericStringRef(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template struct IsGenericValueImpl::Type, typename Void::Type> + : IsBaseOf, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template struct IsGenericValue : IsGenericValueImpl::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// TypeHelper + +namespace internal { + +template +struct TypeHelper {}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsBool(); } + static bool Get(const ValueType& v) { return v.GetBool(); } + static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } + static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static int Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; + +#ifdef _MSC_VER +RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int)); +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static long Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned)); +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned long Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; +#endif + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt64(); } + static int64_t Get(const ValueType& v) { return v.GetInt64(); } + static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } + static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint64(); } + static uint64_t Get(const ValueType& v) { return v.GetUint64(); } + static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } + static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsDouble(); } + static double Get(const ValueType& v) { return v.GetDouble(); } + static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } + static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsFloat(); } + static float Get(const ValueType& v) { return v.GetFloat(); } + static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } + static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } +}; + +template +struct TypeHelper { + typedef const typename ValueType::Ch* StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return v.GetString(); } + static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } + static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; + +#if RAPIDJSON_HAS_STDSTRING +template +struct TypeHelper > { + typedef std::basic_string StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } + static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; +#endif + +template +struct TypeHelper { + typedef typename ValueType::Array ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(ValueType& v) { return v.GetArray(); } + static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } + static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstArray ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(const ValueType& v) { return v.GetArray(); } +}; + +template +struct TypeHelper { + typedef typename ValueType::Object ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(ValueType& v) { return v.GetObject(); } + static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } + static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstObject ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(const ValueType& v) { return v.GetObject(); } +}; + +} // namespace internal + +// Forward declarations +template class GenericArray; +template class GenericObject; + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef GenericValue ValueType; //!< Value type of itself. + typedef GenericArray Array; + typedef GenericArray ConstArray; + typedef GenericObject Object; + typedef GenericObject ConstObject; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { + rhs.data_.f.flags = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Moving from a GenericDocument is not permitted. + template + GenericValue(GenericDocument&& rhs); + + //! Move assignment from a GenericDocument is not permitted. + template + GenericValue& operator=(GenericDocument&& rhs); +#endif + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { + static const uint16_t defaultFlags[] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType); + data_.f.flags = defaultFlags[type]; + + // Use ShortString to store empty string. + if (type == kStringType) + data_.ss.SetLength(0); + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) + \see CopyFrom() + */ + template + GenericValue(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { + switch (rhs.GetType()) { + case kObjectType: + DoCopyMembers(rhs, allocator, copyConstStrings); + break; + case kArrayType: { + SizeType count = rhs.data_.a.size; + GenericValue* le = reinterpret_cast(allocator.Malloc(count * sizeof(GenericValue))); + const GenericValue* re = rhs.GetElementsPointer(); + for (SizeType i = 0; i < count; i++) + new (&le[i]) GenericValue(re[i], allocator, copyConstStrings); + data_.f.flags = kArrayFlag; + data_.a.size = data_.a.capacity = count; + SetElementsPointer(le); + } + break; + case kStringType: + if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) { + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + } + else + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + break; + default: + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + break; + } + } + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472 +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_() { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); + data_.f.flags = b ? kTrueFlag : kFalseFlag; + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i; + data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u; + data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i64; + data_.f.flags = kNumberInt64Flag; + if (i64 >= 0) { + data_.f.flags |= kNumberUint64Flag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u64; + data_.f.flags = kNumberUint64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + data_.f.flags |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for float value. + explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast(f); data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Constructor for Array. + /*! + \param a An array obtained by \c GetArray(). + \note \c Array is always pass-by-value. + \note the source array is moved into this value and the source array becomes empty. + */ + GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { + a.value_.data_ = Data(); + a.value_.data_.f.flags = kArrayFlag; + } + + //! Constructor for Object. + /*! + \param o An object obtained by \c GetObject(). + \note \c Object is always pass-by-value. + \note the source object is moved into this value and the source object becomes empty. + */ + GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { + o.value_.data_ = Data(); + o.value_.data_.f.flags = kObjectFlag; + } + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release + // their Allocator if it's refcounted (e.g. MemoryPoolAllocator). + if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 && + internal::IsRefCounted::Value)) { + switch(data_.f.flags) { + case kArrayFlag: + { + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + Allocator::Free(e); + } + } + break; + + case kObjectFlag: + DoFreeMembers(); + break; + + case kCopyStringFlag: + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + Allocator::Free(const_cast(GetStringPointer())); + } + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + if (RAPIDJSON_LIKELY(this != &rhs)) { + // Can't destroy "this" before assigning "rhs", otherwise "rhs" + // could be used after free if it's an sub-Value of "this", + // hence the temporary dance. + GenericValue temp; + temp.RawAssign(rhs); + this->~GenericValue(); + RawAssign(temp); + } + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) + */ + template + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { + RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator, copyConstStrings); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.value, b.value); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Complexity is quadratic in Object's member number and linear for the rest (number of all values in the subtree and total lengths of all strings). + */ + template + bool operator==(const GenericValue& rhs) const { + typedef GenericValue RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + return false; + for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { + typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); + if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) { + double a = GetDouble(); // May convert from integer to double. + double b = rhs.GetDouble(); // Ditto + return a >= b && a <= b; // Prevent -Wfloat-equal + } + else + return data_.n.u64 == rhs.data_.n.u64; + + default: + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + +#ifndef __cpp_impl_three_way_comparison + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template + bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} +#endif + + //!@name Type + //@{ + + Type GetType() const { return static_cast(data_.f.flags & kTypeMask); } + bool IsNull() const { return data_.f.flags == kNullFlag; } + bool IsFalse() const { return data_.f.flags == kFalseFlag; } + bool IsTrue() const { return data_.f.flags == kTrueFlag; } + bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } + bool IsObject() const { return data_.f.flags == kObjectFlag; } + bool IsArray() const { return data_.f.flags == kArrayFlag; } + bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } + bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } + bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } + bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } + bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } + bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } + bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } + + // Checks whether a number can be losslessly converted to a double. + bool IsLosslessDouble() const { + if (!IsNumber()) return false; + if (IsUint64()) { + uint64_t u = GetUint64(); + volatile double d = static_cast(u); + return (d >= 0.0) + && (d < static_cast((std::numeric_limits::max)())) + && (u == static_cast(d)); + } + if (IsInt64()) { + int64_t i = GetInt64(); + volatile double d = static_cast(i); + return (d >= static_cast((std::numeric_limits::min)())) + && (d < static_cast((std::numeric_limits::max)())) + && (i == static_cast(d)); + } + return true; // double, int, uint are always lossless + } + + // Checks whether a number is a float (possible lossy). + bool IsFloat() const { + if ((data_.f.flags & kDoubleFlag) == 0) + return false; + double d = GetDouble(); + return d >= -3.4028234e38 && d <= 3.4028234e38; + } + // Checks whether a number can be losslessly converted to a float. + bool IsLosslessFloat() const { + if (!IsNumber()) return false; + double a = GetDouble(); + if (a < static_cast(-(std::numeric_limits::max)()) + || a > static_cast((std::numeric_limits::max)())) + return false; + double b = static_cast(static_cast(a)); + return a >= b && a <= b; // Prevent -Wfloat-equal + } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Get the capacity of object. + SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(GenericValue&)) operator[](T* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast(*this)[name]; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam SourceAllocator Allocator of the \c name value + + \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). + And it can also handle strings with embedded null characters. + + \note Linear time complexity. + */ + template + GenericValue& operator[](const GenericValue& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + +#if RAPIDJSON_HAS_CXX11 + // Use thread-local storage to prevent races between threads. + // Use static buffer and placement-new to prevent destruction, with + // alignas() to ensure proper alignment. + alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); +#elif defined(_MSC_VER) && _MSC_VER < 1900 + // There's no way to solve both thread locality and proper alignment + // simultaneously. + __declspec(thread) static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); +#elif defined(__GNUC__) || defined(__clang__) + // This will generate -Wexit-time-destructors in clang, but that's + // better than having under-alignment. + __thread static GenericValue buffer; + return buffer; +#else + // Don't know what compiler this is, so don't know how to ensure + // thread-locality. + static GenericValue buffer; + return buffer; +#endif + } + } + template + const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } + +#if RAPIDJSON_HAS_STDSTRING + //! Get a value from an object associated with name (string object). + GenericValue& operator[](const std::basic_string& name) { return (*this)[GenericValue(StringRef(name))]; } + const GenericValue& operator[](const std::basic_string& name) const { return (*this)[GenericValue(StringRef(name))]; } +#endif + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } + + //! Request the object to have enough capacity to store members. + /*! \param newCapacity The capacity that the object at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsObject()); + DoReserveMembers(newCapacity, allocator); + return *this; + } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + +#if RAPIDJSON_HAS_STDSTRING + //! Check whether a member exists in the object with string object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const std::basic_string& name) const { return FindMember(name) != MemberEnd(); } +#endif + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template + bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template + MemberIterator FindMember(const GenericValue& name) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + return DoFindMember(name); + } + template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } + +#if RAPIDJSON_HAS_STDSTRING + //! Find member by string object name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + */ + MemberIterator FindMember(const std::basic_string& name) { return FindMember(GenericValue(StringRef(name))); } + ConstMemberIterator FindMember(const std::basic_string& name) const { return FindMember(GenericValue(StringRef(name))); } +#endif + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + DoAddMember(name, value, allocator); + return *this; + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Add a string object as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, std::basic_string& value, Allocator& allocator) { + GenericValue v(value, allocator); + return AddMember(name, v, allocator); + } +#endif + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A string value as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(GenericValue& name, T value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + DoClearMembers(); + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) { return RemoveMember(GenericValue(StringRef(name))); } +#endif + + template + bool RemoveMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + return DoRemoveMember(m); + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note This function preserves the relative order of the remaining object + members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note This function preserves the relative order of the remaining object + members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(first >= MemberBegin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= MemberEnd()); + return DoEraseMembers(first, last); + } + + //! Erase a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Linear time complexity. + */ + bool EraseMember(const Ch* name) { + GenericValue n(StringRef(name)); + return EraseMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) { return EraseMember(GenericValue(StringRef(name))); } +#endif + + template + bool EraseMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + EraseMember(m); + return true; + } + else + return false; + } + + Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \pre IsArray() == true + \param index Zero-based index of element. + \see operator[](T*) + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return GetElementsPointer()[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + SetElementsPointer(reinterpret_cast(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + GetElementsPointer()[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + GetElementsPointer()[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(GetElementsPointer() != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(static_cast(pos), last, static_cast(End() - last) * sizeof(GenericValue)); + data_.a.size -= static_cast(last - first); + return pos; + } + + Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } + ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } + + //! Get the value as double type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the conversion is lossless. + */ + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((data_.f.flags & kInt64Flag) != 0) return static_cast(data_.n.i64); // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast(data_.n.u64); // uint64_t -> double (may lose precision) + } + + //! Get the value as float type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the conversion is lossless. + */ + float GetFloat() const { + return static_cast(GetDouble()); + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast(f)); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); } + + //! Get the length of string. + /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); } + + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); } + + //! Set this value as a string by copying from source string. + /*! \param s source string reference + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(StringRef(s), allocator); } +#endif + + //@} + + //!@name Array + //@{ + + //! Templated version for checking whether this value is type T. + /*! + \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string + */ + template + bool Is() const { return internal::TypeHelper::Is(*this); } + + template + T Get() const { return internal::TypeHelper::Get(*this); } + + template + T Get() { return internal::TypeHelper::Get(*this); } + + template + ValueType& Set(const T& data) { return internal::TypeHelper::Set(*this, data); } + + template + ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper::Set(*this, data, allocator); } + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. + if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) + return false; + if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + return false; + for (ConstValueIterator v = Begin(); v != End(); ++v) + if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); + + default: + RAPIDJSON_ASSERT(GetType() == kNumberType); + if (IsDouble()) return handler.Double(data_.n.d); + else if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else return handler.Uint64(data_.n.u64); + } + } + +private: + template friend class GenericValue; + template friend class GenericDocument; + + enum { + kBoolFlag = 0x0008, + kNumberFlag = 0x0010, + kIntFlag = 0x0020, + kUintFlag = 0x0040, + kInt64Flag = 0x0080, + kUint64Flag = 0x0100, + kDoubleFlag = 0x0200, + kStringFlag = 0x0400, + kCopyFlag = 0x0800, + kInlineStrFlag = 0x1000, + + // Initial flags of different types. + kNullFlag = kNullType, + // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types. + kTrueFlag = static_cast(kTrueType) | static_cast(kBoolFlag), + kFalseFlag = static_cast(kFalseType) | static_cast(kBoolFlag), + kNumberIntFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kIntFlag | kInt64Flag), + kNumberUintFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag), + kNumberInt64Flag = static_cast(kNumberType) | static_cast(kNumberFlag | kInt64Flag), + kNumberUint64Flag = static_cast(kNumberType) | static_cast(kNumberFlag | kUint64Flag), + kNumberDoubleFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kDoubleFlag), + kNumberAnyFlag = static_cast(kNumberType) | static_cast(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag), + kConstStringFlag = static_cast(kStringType) | static_cast(kStringFlag), + kCopyStringFlag = static_cast(kStringType) | static_cast(kStringFlag | kCopyFlag), + kShortStringFlag = static_cast(kStringType) | static_cast(kStringFlag | kCopyFlag | kInlineStrFlag), + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0x07 + }; + + static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY; + static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY; + + struct Flag { +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION + char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer +#elif RAPIDJSON_64BIT + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes +#else + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes +#endif + uint16_t flags; + }; + + struct String { + SizeType length; + SizeType hashcode; //!< reserved + const Ch* str; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, + // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(static_cast(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = static_cast(MaxSize - len); } + inline SizeType GetLength() const { return static_cast(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct ObjectData { + SizeType size; + SizeType capacity; + Member* members; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct ArrayData { + SizeType size; + SizeType capacity; + GenericValue* elements; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + ObjectData o; + ArrayData a; + Flag f; + }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION + + static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) { + return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str); + } + static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) { + return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length; + } + + RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } + RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } + RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } + RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } + RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } + RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } + +#if RAPIDJSON_USE_MEMBERSMAP + + struct MapTraits { + struct Less { + bool operator()(const Data& s1, const Data& s2) const { + SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2); + int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2)); + return cmp < 0 || (cmp == 0 && n1 < n2); + } + }; + typedef std::pair Pair; + typedef std::multimap > Map; + typedef typename Map::iterator Iterator; + }; + typedef typename MapTraits::Map Map; + typedef typename MapTraits::Less MapLess; + typedef typename MapTraits::Pair MapPair; + typedef typename MapTraits::Iterator MapIterator; + + // + // Layout of the members' map/array, re(al)located according to the needed capacity: + // + // {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]} + // + // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed) + // + + static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) { + return RAPIDJSON_ALIGN(sizeof(Map*)) + + RAPIDJSON_ALIGN(sizeof(SizeType)) + + RAPIDJSON_ALIGN(capacity * sizeof(Member)) + + capacity * sizeof(MapIterator); + } + + static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) { + return *reinterpret_cast(reinterpret_cast(&map) + + RAPIDJSON_ALIGN(sizeof(Map*))); + } + + static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) { + return reinterpret_cast(reinterpret_cast(&map) + + RAPIDJSON_ALIGN(sizeof(Map*)) + + RAPIDJSON_ALIGN(sizeof(SizeType))); + } + + static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) { + return reinterpret_cast(reinterpret_cast(&map) + + RAPIDJSON_ALIGN(sizeof(Map*)) + + RAPIDJSON_ALIGN(sizeof(SizeType)) + + RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member))); + } + + static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) { + RAPIDJSON_ASSERT(members != 0); + return *reinterpret_cast(reinterpret_cast(members) - + RAPIDJSON_ALIGN(sizeof(SizeType)) - + RAPIDJSON_ALIGN(sizeof(Map*))); + } + + // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting.. + RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) { +#if RAPIDJSON_HAS_CXX11 + MapIterator ret = std::move(rhs); +#else + MapIterator ret = rhs; +#endif + rhs.~MapIterator(); + return ret; + } + + Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) { + Map **newMap = static_cast(allocator.Malloc(GetMapLayoutSize(newCapacity))); + GetMapCapacity(*newMap) = newCapacity; + if (!oldMap) { + *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator); + } + else { + *newMap = *oldMap; + size_t count = (*oldMap)->size(); + std::memcpy(static_cast(GetMapMembers(*newMap)), + static_cast(GetMapMembers(*oldMap)), + count * sizeof(Member)); + MapIterator *oldIt = GetMapIterators(*oldMap), + *newIt = GetMapIterators(*newMap); + while (count--) { + new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count])); + } + Allocator::Free(oldMap); + } + return *newMap; + } + + RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) { + return GetMapMembers(DoReallocMap(0, capacity, allocator)); + } + + void DoReserveMembers(SizeType newCapacity, Allocator& allocator) { + ObjectData& o = data_.o; + if (newCapacity > o.capacity) { + Member* oldMembers = GetMembersPointer(); + Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0, + *&newMap = DoReallocMap(oldMap, newCapacity, allocator); + RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap)); + o.capacity = newCapacity; + } + } + + template + MemberIterator DoFindMember(const GenericValue& name) { + if (Member* members = GetMembersPointer()) { + Map* &map = GetMap(members); + MapIterator mit = map->find(reinterpret_cast(name.data_)); + if (mit != map->end()) { + return MemberIterator(&members[mit->second]); + } + } + return MemberEnd(); + } + + void DoClearMembers() { + if (Member* members = GetMembersPointer()) { + Map* &map = GetMap(members); + MapIterator* mit = GetMapIterators(map); + for (SizeType i = 0; i < data_.o.size; i++) { + map->erase(DropMapIterator(mit[i])); + members[i].~Member(); + } + data_.o.size = 0; + } + } + + void DoFreeMembers() { + if (Member* members = GetMembersPointer()) { + GetMap(members)->~Map(); + for (SizeType i = 0; i < data_.o.size; i++) { + members[i].~Member(); + } + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + Map** map = &GetMap(members); + Allocator::Free(*map); + Allocator::Free(map); + } + } + } + +#else // !RAPIDJSON_USE_MEMBERSMAP + + RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) { + return Malloc(allocator, capacity); + } + + void DoReserveMembers(SizeType newCapacity, Allocator& allocator) { + ObjectData& o = data_.o; + if (newCapacity > o.capacity) { + Member* newMembers = Realloc(allocator, GetMembersPointer(), o.capacity, newCapacity); + RAPIDJSON_SETPOINTER(Member, o.members, newMembers); + o.capacity = newCapacity; + } + } + + template + MemberIterator DoFindMember(const GenericValue& name) { + MemberIterator member = MemberBegin(); + for ( ; member != MemberEnd(); ++member) + if (name.StringEqual(member->name)) + break; + return member; + } + + void DoClearMembers() { + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + void DoFreeMembers() { + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(GetMembersPointer()); + } + +#endif // !RAPIDJSON_USE_MEMBERSMAP + + void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + ObjectData& o = data_.o; + if (o.size >= o.capacity) + DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator); + Member* members = GetMembersPointer(); + Member* m = members + o.size; + m->name.RawAssign(name); + m->value.RawAssign(value); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(members); + MapIterator* mit = GetMapIterators(map); + new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size))); +#endif + ++o.size; + } + + MemberIterator DoRemoveMember(MemberIterator m) { + ObjectData& o = data_.o; + Member* members = GetMembersPointer(); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(members); + MapIterator* mit = GetMapIterators(map); + SizeType mpos = static_cast(&*m - members); + map->erase(DropMapIterator(mit[mpos])); +#endif + MemberIterator last(members + (o.size - 1)); + if (o.size > 1 && m != last) { +#if RAPIDJSON_USE_MEMBERSMAP + new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members])); + mit[mpos]->second = mpos; +#endif + *m = *last; // Move the last one to this place + } + else { + m->~Member(); // Only one left, just destroy + } + --o.size; + return m; + } + + MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) { + ObjectData& o = data_.o; + MemberIterator beg = MemberBegin(), + pos = beg + (first - beg), + end = MemberEnd(); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(GetMembersPointer()); + MapIterator* mit = GetMapIterators(map); +#endif + for (MemberIterator itr = pos; itr != last; ++itr) { +#if RAPIDJSON_USE_MEMBERSMAP + map->erase(DropMapIterator(mit[itr - beg])); +#endif + itr->~Member(); + } +#if RAPIDJSON_USE_MEMBERSMAP + if (first != last) { + // Move remaining members/iterators + MemberIterator next = pos + (last - first); + for (MemberIterator itr = pos; next != end; ++itr, ++next) { + std::memcpy(static_cast(&*itr), &*next, sizeof(Member)); + SizeType mpos = static_cast(itr - beg); + new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg])); + mit[mpos]->second = mpos; + } + } +#else + std::memmove(static_cast(&*pos), &*last, + static_cast(end - last) * sizeof(Member)); +#endif + o.size -= static_cast(last - first); + return pos; + } + + template + void DoCopyMembers(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings) { + RAPIDJSON_ASSERT(rhs.GetType() == kObjectType); + + data_.f.flags = kObjectFlag; + SizeType count = rhs.data_.o.size; + Member* lm = DoAllocMembers(count, allocator); + const typename GenericValue::Member* rm = rhs.GetMembersPointer(); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(lm); + MapIterator* mit = GetMapIterators(map); +#endif + for (SizeType i = 0; i < count; i++) { + new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings); + new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings); +#if RAPIDJSON_USE_MEMBERSMAP + new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i))); +#endif + } + data_.o.size = data_.o.capacity = count; + SetMembersPointer(lm); + } + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + data_.f.flags = kArrayFlag; + if (count) { + GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); + SetElementsPointer(e); + std::memcpy(static_cast(e), values, count * sizeof(GenericValue)); + } + else + SetElementsPointer(0); + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + data_.f.flags = kObjectFlag; + if (count) { + Member* m = DoAllocMembers(count, allocator); + SetMembersPointer(m); + std::memcpy(static_cast(m), members, count * sizeof(Member)); +#if RAPIDJSON_USE_MEMBERSMAP + Map* &map = GetMap(m); + MapIterator* mit = GetMapIterators(map); + for (SizeType i = 0; i < count; i++) { + new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i))); + } +#endif + } + else + SetMembersPointer(0); + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + data_.f.flags = kConstStringFlag; + SetStringPointer(s); + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = 0; + if (ShortString::Usable(s.length)) { + data_.f.flags = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + data_.f.flags = kCopyStringFlag; + data_.s.length = s.length; + str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); + SetStringPointer(str); + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + // data_.f.flags = rhs.data_.f.flags; + rhs.data_.f.flags = kNullFlag; + } + + template + bool StringEqual(const GenericValue& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template +class GenericDocument : public GenericValue { +public: + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef StackAllocator StackAllocatorType; //!< StackAllocator type from template parameter. + + //! Constructor + /*! Creates an empty document of specified type. + \param type Mandatory type of object to create. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + GenericValue(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + } + + //! Constructor + /*! Creates an empty document which type is Null. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(std::move(rhs.stack_)), + parseResult_(rhs.parseResult_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + } +#endif + + ~GenericDocument() { + // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType() + // runs last and may access its elements or members which would be freed + // with an allocator like MemoryPoolAllocator (CrtAllocator does not + // free its data when destroyed, but MemoryPoolAllocator does). + if (ownAllocator_) { + ValueType::SetNull(); + } + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + { + // The cast to ValueType is necessary here, because otherwise it would + // attempt to call GenericValue's templated assignment operator. + ValueType::operator=(std::forward(rhs)); + + // Calling the destructor here would prematurely call stack_'s destructor + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = std::move(rhs.stack_); + parseResult_ = rhs.parseResult_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + + return *this; + } +#endif + + //! Exchange the contents of this document with those of another. + /*! + \param rhs Another document. + \note Constant complexity. + \see GenericValue::Swap + */ + GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { + ValueType::Swap(rhs); + stack_.Swap(rhs.stack_); + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(parseResult_, rhs.parseResult_); + return *this; + } + + // Allow Swap with ValueType. + // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names. + using ValueType::Swap; + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.doc, b.doc); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Populate this document by a generator which produces SAX events. + /*! \tparam Generator A functor with bool f(Handler) prototype. + \param g Generator functor which sends SAX events to the parameter. + \return The document itself for fluent API. + */ + template + GenericDocument& Populate(Generator& g) { + ClearStackOnExit scope(*this); + if (g(*this)) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + GenericReader reader( + stack_.HasAllocator() ? &stack_.GetAllocator() : 0); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + MemoryStream ms(reinterpret_cast(str), length * sizeof(typename SourceEncoding::Ch)); + EncodedInputStream is(ms); + ParseStream(is); + return *this; + } + + template + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + template + GenericDocument& Parse(const std::basic_string& str) { + // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) + return Parse(str.c_str()); + } + + template + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str.c_str()); + } + + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str); + } +#endif // RAPIDJSON_HAS_STDSTRING + + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occurred in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //! Implicit conversion to get the last parse result +#ifndef __clang // -Wdocumentation + /*! \return \ref ParseResult of the last parse operation + + \code + Document doc; + ParseResult ok = doc.Parse(json); + if (!ok) + printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); + \endcode + */ +#endif + operator ParseResult() const { return parseResult_; } + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + // template friend class GenericReader; // for parsing + template friend class GenericValue; // for deep copying + +public: + // Implementation of Handler + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } + + bool RawNumber(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit copying + GenericDocument(const GenericDocument&); + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + void Destroy() { + RAPIDJSON_DELETE(ownAllocator_); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument > Document; + + +//! Helper class for accessing Value of array type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetArray(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericArray { +public: + typedef GenericArray ConstArray; + typedef GenericArray Array; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef ValueType* ValueIterator; // This may be const or non-const iterator + typedef const ValueT* ConstValueIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + + template + friend class GenericValue; + + GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} + GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } + ~GenericArray() {} + + operator ValueType&() const { return value_; } + SizeType Size() const { return value_.Size(); } + SizeType Capacity() const { return value_.Capacity(); } + bool Empty() const { return value_.Empty(); } + void Clear() const { value_.Clear(); } + ValueType& operator[](SizeType index) const { return value_[index]; } + ValueIterator Begin() const { return value_.Begin(); } + ValueIterator End() const { return value_.End(); } + GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } + GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + GenericArray PopBack() const { value_.PopBack(); return *this; } + ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + ValueIterator begin() const { return value_.Begin(); } + ValueIterator end() const { return value_.End(); } +#endif + +private: + GenericArray(); + GenericArray(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +//! Helper class for accessing Value of object type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetObject(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericObject { +public: + typedef GenericObject ConstObject; + typedef GenericObject Object; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef GenericMemberIterator MemberIterator; // This may be const or non-const iterator + typedef GenericMemberIterator ConstMemberIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename ValueType::Ch Ch; + + template + friend class GenericValue; + + GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} + GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } + ~GenericObject() {} + + operator ValueType&() const { return value_; } + SizeType MemberCount() const { return value_.MemberCount(); } + SizeType MemberCapacity() const { return value_.MemberCapacity(); } + bool ObjectEmpty() const { return value_.ObjectEmpty(); } + template ValueType& operator[](T* name) const { return value_[name]; } + template ValueType& operator[](const GenericValue& name) const { return value_[name]; } +#if RAPIDJSON_HAS_STDSTRING + ValueType& operator[](const std::basic_string& name) const { return value_[name]; } +#endif + MemberIterator MemberBegin() const { return value_.MemberBegin(); } + MemberIterator MemberEnd() const { return value_.MemberEnd(); } + GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; } + bool HasMember(const Ch* name) const { return value_.HasMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } +#endif + template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } + MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } + template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } +#if RAPIDJSON_HAS_STDSTRING + MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } +#endif + GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_STDSTRING + GenericObject AddMember(ValueType& name, std::basic_string& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + void RemoveAllMembers() { value_.RemoveAllMembers(); } + bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) const { return value_.RemoveMember(name); } +#endif + template bool RemoveMember(const GenericValue& name) const { return value_.RemoveMember(name); } + MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } + MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } + bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) const { return EraseMember(ValueType(StringRef(name))); } +#endif + template bool EraseMember(const GenericValue& name) const { return value_.EraseMember(name); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + MemberIterator begin() const { return value_.MemberBegin(); } + MemberIterator end() const { return value_.MemberEnd(); } +#endif + +private: + GenericObject(); + GenericObject(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED +#pragma pop_macro("GetObject") +#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED +#endif + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodedstream.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodedstream.h new file mode 100644 index 000000000..309499dc6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodedstream.h @@ -0,0 +1,299 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "stream.h" +#include "memorystream.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Specialized for UTF8 MemoryStream. +template <> +class EncodedInputStream, MemoryStream> { +public: + typedef UTF8<>::Ch Ch; + + EncodedInputStream(MemoryStream& is) : is_(is) { + if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); + } + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) {} + void Flush() {} + Ch* PutBegin() { return 0; } + size_t PutEnd(Ch*) { return 0; } + + MemoryStream& is_; + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = reinterpret_cast(is_->Peek4()); + if (!c) + return; + + unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam OutputByteStream type of output byte stream to be wrapped. +*/ +template +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodings.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodings.h new file mode 100644 index 000000000..5ee169e10 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/encodings.h @@ -0,0 +1,716 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#if defined(_MSC_VER) && !defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(overflow) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + PutUnsafe(os, static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { +#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) +#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) + typename InputStream::Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = static_cast(c); + return true; + } + + unsigned char type = GetRange(static_cast(c)); + if (type >= 32) { + *codepoint = 0; + } else { + *codepoint = (0xFFu >> type) & static_cast(c); + } + bool result = true; + switch (type) { + case 2: RAPIDJSON_TAIL(); return result; + case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; + case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; + case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + default: return false; + } +#undef RAPIDJSON_COPY +#undef RAPIDJSON_TRANS +#undef RAPIDJSON_TAIL + } + + template + static bool Validate(InputStream& is, OutputStream& os) { +#define RAPIDJSON_COPY() os.Put(c = is.Take()) +#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) + Ch c; + RAPIDJSON_COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange(static_cast(c))) { + case 2: RAPIDJSON_TAIL(); return result; + case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; + case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; + case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; + default: return false; + } +#undef RAPIDJSON_COPY +#undef RAPIDJSON_TRANS +#undef RAPIDJSON_TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + typename InputByteStream::Ch c = Take(is); + if (static_cast(c) != 0xEFu) return c; + c = is.Take(); + if (static_cast(c) != 0xBBu) return c; + c = is.Take(); + if (static_cast(c) != 0xBFu) return c; + c = is.Take(); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xEFu)); + os.Put(static_cast(0xBBu)); + os.Put(static_cast(0xBFu)); + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast((v >> 10) | 0xD800)); + os.Put(static_cast((v & 0x3FF) | 0xDC00)); + } + } + + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + PutUnsafe(os, static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + PutUnsafe(os, static_cast((v >> 10) | 0xD800)); + PutUnsafe(os, static_cast((v & 0x3FF) | 0xDC00)); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + typename InputStream::Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = static_cast(c); + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (static_cast(c) & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (static_cast(c) & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + typename InputStream::Ch c; + os.Put(static_cast(c = is.Take())); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template +struct UTF16LE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(static_cast(c) & 0xFFu)); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + } +}; + +//! UTF-16 big endian encoding. +template +struct UTF16BE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + os.Put(static_cast(static_cast(c) & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, codepoint); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian encoding. +template +struct UTF32LE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 24; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 24) & 0xFFu)); + } +}; + +//! UTF-32 big endian encoding. +template +struct UTF32BE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 24; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((c >> 24) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast(c & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast(codepoint & 0xFF)); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + PutUnsafe(os, static_cast(codepoint & 0xFF)); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + uint8_t c = static_cast(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + uint8_t c = static_cast(is.Take()); + os.Put(static_cast(c)); + return c <= 0x7F; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + uint8_t c = static_cast(Take(is)); + return static_cast(c); + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputStream and AutoUTFOutputStream, which provides GetType(). +*/ +template +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + + template + static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template + static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; + (*f[os.GetType()])(os, codepoint); + } + + template + static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template + static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template + static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + template + static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::EncodeUnsafe(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template + static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +// Forward declaration. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c); + +//! Specialization of Transcoder with same source and target encoding. +template +struct Transcoder { + template + static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__)) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/en.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/en.h new file mode 100644 index 000000000..c87b04eb1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/en.h @@ -0,0 +1,176 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_EN_H_ +#define RAPIDJSON_ERROR_EN_H_ + +#include "error.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(covered-switch-default) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +//! Maps error code of validation into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param validateErrorCode Error code obtained from validator. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode validateErrorCode) { + switch (validateErrorCode) { + case kValidateErrors: return RAPIDJSON_ERROR_STRING("One or more validation errors have occurred"); + case kValidateErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kValidateErrorMultipleOf: return RAPIDJSON_ERROR_STRING("Number '%actual' is not a multiple of the 'multipleOf' value '%expected'."); + case kValidateErrorMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than the 'maximum' value '%expected'."); + case kValidateErrorExclusiveMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than or equal to the 'exclusiveMaximum' value '%expected'."); + case kValidateErrorMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than the 'minimum' value '%expected'."); + case kValidateErrorExclusiveMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than or equal to the 'exclusiveMinimum' value '%expected'."); + + case kValidateErrorMaxLength: return RAPIDJSON_ERROR_STRING("String '%actual' is longer than the 'maxLength' value '%expected'."); + case kValidateErrorMinLength: return RAPIDJSON_ERROR_STRING("String '%actual' is shorter than the 'minLength' value '%expected'."); + case kValidateErrorPattern: return RAPIDJSON_ERROR_STRING("String '%actual' does not match the 'pattern' regular expression."); + + case kValidateErrorMaxItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is longer than the 'maxItems' value '%expected'."); + case kValidateErrorMinItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is shorter than the 'minItems' value '%expected'."); + case kValidateErrorUniqueItems: return RAPIDJSON_ERROR_STRING("Array has duplicate items at indices '%duplicates' but 'uniqueItems' is true."); + case kValidateErrorAdditionalItems: return RAPIDJSON_ERROR_STRING("Array has an additional item at index '%disallowed' that is not allowed by the schema."); + + case kValidateErrorMaxProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is more than 'maxProperties' value '%expected'."); + case kValidateErrorMinProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is less than 'minProperties' value '%expected'."); + case kValidateErrorRequired: return RAPIDJSON_ERROR_STRING("Object is missing the following members required by the schema: '%missing'."); + case kValidateErrorAdditionalProperties: return RAPIDJSON_ERROR_STRING("Object has an additional member '%disallowed' that is not allowed by the schema."); + case kValidateErrorPatternProperties: return RAPIDJSON_ERROR_STRING("Object has 'patternProperties' that are not allowed by the schema."); + case kValidateErrorDependencies: return RAPIDJSON_ERROR_STRING("Object has missing property or schema dependencies, refer to following errors."); + + case kValidateErrorEnum: return RAPIDJSON_ERROR_STRING("Property has a value that is not one of its allowed enumerated values."); + case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'."); + + case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors."); + case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf', indices '%matches'."); + case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors."); + case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors."); + case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'."); + + case kValidateErrorReadOnly: return RAPIDJSON_ERROR_STRING("Property is read-only but has been provided when validation is for writing."); + case kValidateErrorWriteOnly: return RAPIDJSON_ERROR_STRING("Property is write-only but has been provided when validation is for reading."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +//! Maps error code of schema document compilation into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param schemaErrorCode Error code obtained from compiling the schema document. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ + inline const RAPIDJSON_ERROR_CHARTYPE* GetSchemaError_En(SchemaErrorCode schemaErrorCode) { + switch (schemaErrorCode) { + case kSchemaErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kSchemaErrorStartUnknown: return RAPIDJSON_ERROR_STRING("Pointer '%value' to start of schema does not resolve to a location in the document."); + case kSchemaErrorRefPlainName: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' must be a JSON pointer."); + case kSchemaErrorRefInvalid: return RAPIDJSON_ERROR_STRING("$ref must not be an empty string."); + case kSchemaErrorRefPointerInvalid: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' is not a valid JSON pointer at offset '%offset'."); + case kSchemaErrorRefUnknown: return RAPIDJSON_ERROR_STRING("$ref '%value' does not resolve to a location in the target document."); + case kSchemaErrorRefCyclical: return RAPIDJSON_ERROR_STRING("$ref '%value' is cyclical."); + case kSchemaErrorRefNoRemoteProvider: return RAPIDJSON_ERROR_STRING("$ref is remote but there is no remote provider."); + case kSchemaErrorRefNoRemoteSchema: return RAPIDJSON_ERROR_STRING("$ref '%value' is remote but the remote provider did not return a schema."); + case kSchemaErrorRegexInvalid: return RAPIDJSON_ERROR_STRING("Invalid regular expression '%value' in 'pattern' or 'patternProperties'."); + case kSchemaErrorSpecUnknown: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not recognized."); + case kSchemaErrorSpecUnsupported: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not supported."); + case kSchemaErrorSpecIllegal: return RAPIDJSON_ERROR_STRING("Both JSON schema draft and OpenAPI version found in document."); + case kSchemaErrorReadOnlyAndWriteOnly: return RAPIDJSON_ERROR_STRING("Property must not be both 'readOnly' and 'writeOnly'."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } + } + +//! Maps error code of pointer parse into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param pointerParseErrorCode Error code obtained from pointer parse. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetPointerParseError_En(PointerParseErrorCode pointerParseErrorCode) { + switch (pointerParseErrorCode) { + case kPointerParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kPointerParseErrorTokenMustBeginWithSolidus: return RAPIDJSON_ERROR_STRING("A token must begin with a '/'."); + case kPointerParseErrorInvalidEscape: return RAPIDJSON_ERROR_STRING("Invalid escape."); + case kPointerParseErrorInvalidPercentEncoding: return RAPIDJSON_ERROR_STRING("Invalid percent encoding in URI fragment."); + case kPointerParseErrorCharacterMustPercentEncode: return RAPIDJSON_ERROR_STRING("A character must be percent encoded in a URI fragment."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/error.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/error.h new file mode 100644 index 000000000..cae345db3 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/error/error.h @@ -0,0 +1,285 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_ERROR_H_ +#define RAPIDJSON_ERROR_ERROR_H_ + +#include "../rapidjson.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literal to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { + //!! Unspecified boolean type + typedef bool (ParseResult::*BooleanType)() const; +public: + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Explicit conversion to \c bool, returns \c true, iff !\ref IsError(). + operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + bool operator!=(const ParseResult& that) const { return !(*this == that); } + bool operator!=(ParseErrorCode code) const { return !(*this == code); } + friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +/////////////////////////////////////////////////////////////////////////////// +// ValidateErrorCode + +//! Error codes when validating. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericSchemaValidator +*/ +enum ValidateErrorCode { + kValidateErrors = -1, //!< Top level error code when kValidateContinueOnErrorsFlag set. + kValidateErrorNone = 0, //!< No error. + + kValidateErrorMultipleOf, //!< Number is not a multiple of the 'multipleOf' value. + kValidateErrorMaximum, //!< Number is greater than the 'maximum' value. + kValidateErrorExclusiveMaximum, //!< Number is greater than or equal to the 'maximum' value. + kValidateErrorMinimum, //!< Number is less than the 'minimum' value. + kValidateErrorExclusiveMinimum, //!< Number is less than or equal to the 'minimum' value. + + kValidateErrorMaxLength, //!< String is longer than the 'maxLength' value. + kValidateErrorMinLength, //!< String is longer than the 'maxLength' value. + kValidateErrorPattern, //!< String does not match the 'pattern' regular expression. + + kValidateErrorMaxItems, //!< Array is longer than the 'maxItems' value. + kValidateErrorMinItems, //!< Array is shorter than the 'minItems' value. + kValidateErrorUniqueItems, //!< Array has duplicate items but 'uniqueItems' is true. + kValidateErrorAdditionalItems, //!< Array has additional items that are not allowed by the schema. + + kValidateErrorMaxProperties, //!< Object has more members than 'maxProperties' value. + kValidateErrorMinProperties, //!< Object has less members than 'minProperties' value. + kValidateErrorRequired, //!< Object is missing one or more members required by the schema. + kValidateErrorAdditionalProperties, //!< Object has additional members that are not allowed by the schema. + kValidateErrorPatternProperties, //!< See other errors. + kValidateErrorDependencies, //!< Object has missing property or schema dependencies. + + kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values. + kValidateErrorType, //!< Property has a type that is not allowed by the schema. + + kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'. + kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'. + kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'. + kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'. + kValidateErrorNot, //!< Property matched the sub-schema specified by 'not'. + + kValidateErrorReadOnly, //!< Property is read-only but has been provided when validation is for writing + kValidateErrorWriteOnly //!< Property is write-only but has been provided when validation is for reading +}; + +//! Function pointer type of GetValidateError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetValidateError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetValidateErrorFunc GetValidateError = GetValidateError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetValidateError(validator.GetInvalidSchemaCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode); + +/////////////////////////////////////////////////////////////////////////////// +// SchemaErrorCode + +//! Error codes when validating. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericSchemaValidator +*/ +enum SchemaErrorCode { + kSchemaErrorNone = 0, //!< No error. + + kSchemaErrorStartUnknown, //!< Pointer to start of schema does not resolve to a location in the document + kSchemaErrorRefPlainName, //!< $ref fragment must be a JSON pointer + kSchemaErrorRefInvalid, //!< $ref must not be an empty string + kSchemaErrorRefPointerInvalid, //!< $ref fragment is not a valid JSON pointer at offset + kSchemaErrorRefUnknown, //!< $ref does not resolve to a location in the target document + kSchemaErrorRefCyclical, //!< $ref is cyclical + kSchemaErrorRefNoRemoteProvider, //!< $ref is remote but there is no remote provider + kSchemaErrorRefNoRemoteSchema, //!< $ref is remote but the remote provider did not return a schema + kSchemaErrorRegexInvalid, //!< Invalid regular expression in 'pattern' or 'patternProperties' + kSchemaErrorSpecUnknown, //!< JSON schema draft or OpenAPI version is not recognized + kSchemaErrorSpecUnsupported, //!< JSON schema draft or OpenAPI version is not supported + kSchemaErrorSpecIllegal, //!< Both JSON schema draft and OpenAPI version found in document + kSchemaErrorReadOnlyAndWriteOnly //!< Property must not be both 'readOnly' and 'writeOnly' +}; + +//! Function pointer type of GetSchemaError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetSchemaError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetSchemaErrorFunc GetSchemaError = GetSchemaError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetSchemaError(validator.GetInvalidSchemaCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetSchemaErrorFunc)(SchemaErrorCode); + +/////////////////////////////////////////////////////////////////////////////// +// PointerParseErrorCode + +//! Error code of JSON pointer parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode +*/ +enum PointerParseErrorCode { + kPointerParseErrorNone = 0, //!< The parse is successful + + kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' + kPointerParseErrorInvalidEscape, //!< Invalid escape + kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment + kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment +}; + +//! Function pointer type of GetPointerParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetPointerParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetPointerParseErrorFunc GetPointerParseError = GetPointerParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetPointerParseError(pointer.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetPointerParseErrorFunc)(PointerParseErrorCode); + + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filereadstream.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filereadstream.h new file mode 100644 index 000000000..3daff0927 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filereadstream.h @@ -0,0 +1,99 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = std::fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + std::FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filewritestream.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filewritestream.h new file mode 100644 index 000000000..8a78ef7f0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/filewritestream.h @@ -0,0 +1,104 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of C file stream for output using fwrite(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + size_t result = std::fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); + if (result < static_cast(current_ - buffer_)) { + // failure deliberately ignored at this time + // added to avoid warn_unused_result build errors + } + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + std::FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/fwd.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/fwd.h new file mode 100644 index 000000000..07358d8cc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/fwd.h @@ -0,0 +1,151 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FWD_H_ +#define RAPIDJSON_FWD_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +// encodings.h + +template struct UTF8; +template struct UTF16; +template struct UTF16BE; +template struct UTF16LE; +template struct UTF32; +template struct UTF32BE; +template struct UTF32LE; +template struct ASCII; +template struct AutoUTF; + +template +struct Transcoder; + +// allocators.h + +class CrtAllocator; + +template +class MemoryPoolAllocator; + +// stream.h + +template +struct GenericStringStream; + +typedef GenericStringStream > StringStream; + +template +struct GenericInsituStringStream; + +typedef GenericInsituStringStream > InsituStringStream; + +// stringbuffer.h + +template +class GenericStringBuffer; + +typedef GenericStringBuffer, CrtAllocator> StringBuffer; + +// filereadstream.h + +class FileReadStream; + +// filewritestream.h + +class FileWriteStream; + +// memorybuffer.h + +template +struct GenericMemoryBuffer; + +typedef GenericMemoryBuffer MemoryBuffer; + +// memorystream.h + +struct MemoryStream; + +// reader.h + +template +struct BaseReaderHandler; + +template +class GenericReader; + +typedef GenericReader, UTF8, CrtAllocator> Reader; + +// writer.h + +template +class Writer; + +// prettywriter.h + +template +class PrettyWriter; + +// document.h + +template +class GenericMember; + +template +class GenericMemberIterator; + +template +struct GenericStringRef; + +template +class GenericValue; + +typedef GenericValue, MemoryPoolAllocator > Value; + +template +class GenericDocument; + +typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; + +// pointer.h + +template +class GenericPointer; + +typedef GenericPointer Pointer; + +// schema.h + +template +class IGenericRemoteSchemaDocumentProvider; + +template +class GenericSchemaDocument; + +typedef GenericSchemaDocument SchemaDocument; +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +template < + typename SchemaDocumentType, + typename OutputHandler, + typename StateAllocator> +class GenericSchemaValidator; + +typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/biginteger.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/biginteger.h new file mode 100644 index 000000000..09d0387fe --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/biginteger.h @@ -0,0 +1,297 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_BIGINTEGER_H_ +#define RAPIDJSON_BIGINTEGER_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64) +#include // for _umul128 +#if !defined(_ARM64EC_) +#pragma intrinsic(_umul128) +#else +#pragma comment(lib,"softintrin") +#endif +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class BigInteger { +public: + typedef uint64_t Type; + + BigInteger(const BigInteger& rhs) : count_(rhs.count_) { + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + + explicit BigInteger(uint64_t u) : count_(1) { + digits_[0] = u; + } + + template + BigInteger(const Ch* decimals, size_t length) : count_(1) { + RAPIDJSON_ASSERT(length > 0); + digits_[0] = 0; + size_t i = 0; + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 + while (length >= kMaxDigitPerIteration) { + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); + length -= kMaxDigitPerIteration; + i += kMaxDigitPerIteration; + } + + if (length > 0) + AppendDecimal64(decimals + i, decimals + i + length); + } + + BigInteger& operator=(const BigInteger &rhs) + { + if (this != &rhs) { + count_ = rhs.count_; + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + return *this; + } + + BigInteger& operator=(uint64_t u) { + digits_[0] = u; + count_ = 1; + return *this; + } + + BigInteger& operator+=(uint64_t u) { + Type backup = digits_[0]; + digits_[0] += u; + for (size_t i = 0; i < count_ - 1; i++) { + if (digits_[i] >= backup) + return *this; // no carry + backup = digits_[i + 1]; + digits_[i + 1] += 1; + } + + // Last carry + if (digits_[count_ - 1] < backup) + PushBack(1); + + return *this; + } + + BigInteger& operator*=(uint64_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + uint64_t hi; + digits_[i] = MulAdd64(digits_[i], u, k, &hi); + k = hi; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator*=(uint32_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + const uint64_t c = digits_[i] >> 32; + const uint64_t d = digits_[i] & 0xFFFFFFFF; + const uint64_t uc = u * c; + const uint64_t ud = u * d; + const uint64_t p0 = ud + k; + const uint64_t p1 = uc + (p0 >> 32); + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); + k = p1 >> 32; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator<<=(size_t shift) { + if (IsZero() || shift == 0) return *this; + + size_t offset = shift / kTypeBit; + size_t interShift = shift % kTypeBit; + RAPIDJSON_ASSERT(count_ + offset <= kCapacity); + + if (interShift == 0) { + std::memmove(digits_ + offset, digits_, count_ * sizeof(Type)); + count_ += offset; + } + else { + digits_[count_] = 0; + for (size_t i = count_; i > 0; i--) + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); + digits_[offset] = digits_[0] << interShift; + count_ += offset; + if (digits_[count_]) + count_++; + } + + std::memset(digits_, 0, offset * sizeof(Type)); + + return *this; + } + + bool operator==(const BigInteger& rhs) const { + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; + } + + bool operator==(const Type rhs) const { + return count_ == 1 && digits_[0] == rhs; + } + + BigInteger& MultiplyPow5(unsigned exp) { + static const uint32_t kPow5[12] = { + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + if (exp == 0) return *this; + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 + for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 + if (exp > 0) *this *= kPow5[exp - 1]; + return *this; + } + + // Compute absolute difference of this and rhs. + // Assume this != rhs + bool Difference(const BigInteger& rhs, BigInteger* out) const { + int cmp = Compare(rhs); + RAPIDJSON_ASSERT(cmp != 0); + const BigInteger *a, *b; // Makes a > b + bool ret; + if (cmp < 0) { a = &rhs; b = this; ret = true; } + else { a = this; b = &rhs; ret = false; } + + Type borrow = 0; + for (size_t i = 0; i < a->count_; i++) { + Type d = a->digits_[i] - borrow; + if (i < b->count_) + d -= b->digits_[i]; + borrow = (d > a->digits_[i]) ? 1 : 0; + out->digits_[i] = d; + if (d != 0) + out->count_ = i + 1; + } + + return ret; + } + + int Compare(const BigInteger& rhs) const { + if (count_ != rhs.count_) + return count_ < rhs.count_ ? -1 : 1; + + for (size_t i = count_; i-- > 0;) + if (digits_[i] != rhs.digits_[i]) + return digits_[i] < rhs.digits_[i] ? -1 : 1; + + return 0; + } + + size_t GetCount() const { return count_; } + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } + bool IsZero() const { return count_ == 1 && digits_[0] == 0; } + +private: + template + void AppendDecimal64(const Ch* begin, const Ch* end) { + uint64_t u = ParseUint64(begin, end); + if (IsZero()) + *this = u; + else { + unsigned exp = static_cast(end - begin); + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u + } + } + + void PushBack(Type digit) { + RAPIDJSON_ASSERT(count_ < kCapacity); + digits_[count_++] = digit; + } + + template + static uint64_t ParseUint64(const Ch* begin, const Ch* end) { + uint64_t r = 0; + for (const Ch* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9')); + r = r * 10u + static_cast(*p - Ch('0')); + } + return r; + } + + // Assume a * b + k < 2^128 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t low = _umul128(a, b, outHigh) + k; + if (low < k) + (*outHigh)++; + return low; +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(a) * static_cast(b); + p += k; + *outHigh = static_cast(p >> 64); + return static_cast(p); +#else + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; + x1 += (x0 >> 32); // can't give carry + x1 += x2; + if (x1 < x2) + x3 += (static_cast(1) << 32); + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); + uint64_t hi = x3 + (x1 >> 32); + + lo += k; + if (lo < k) + hi++; + *outHigh = hi; + return lo; +#endif + } + + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 + static const size_t kCapacity = kBitCount / sizeof(Type); + static const size_t kTypeBit = sizeof(Type) * 8; + + Type digits_[kCapacity]; + size_t count_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/clzll.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/clzll.h new file mode 100644 index 000000000..8fc5118aa --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/clzll.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_CLZLL_H_ +#define RAPIDJSON_CLZLL_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && !defined(UNDER_CE) +#include +#if defined(_WIN64) +#pragma intrinsic(_BitScanReverse64) +#else +#pragma intrinsic(_BitScanReverse) +#endif +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline uint32_t clzll(uint64_t x) { + // Passing 0 to __builtin_clzll is UB in GCC and results in an + // infinite loop in the software implementation. + RAPIDJSON_ASSERT(x != 0); + +#if defined(_MSC_VER) && !defined(UNDER_CE) + unsigned long r = 0; +#if defined(_WIN64) + _BitScanReverse64(&r, x); +#else + // Scan the high 32 bits. + if (_BitScanReverse(&r, static_cast(x >> 32))) + return 63 - (r + 32); + + // Scan the low 32 bits. + _BitScanReverse(&r, static_cast(x & 0xFFFFFFFF)); +#endif // _WIN64 + + return 63 - r; +#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) + // __builtin_clzll wrapper + return static_cast(__builtin_clzll(x)); +#else + // naive version + uint32_t r = 0; + while (!(x & (static_cast(1) << 63))) { + x <<= 1; + ++r; + } + + return r; +#endif // _MSC_VER +} + +#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_CLZLL_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/diyfp.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/diyfp.h new file mode 100644 index 000000000..1f60fb60c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/diyfp.h @@ -0,0 +1,261 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DIYFP_H_ +#define RAPIDJSON_DIYFP_H_ + +#include "../rapidjson.h" +#include "clzll.h" +#include + +#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER) +#include +#if !defined(_ARM64EC_) +#pragma intrinsic(_umul128) +#else +#pragma comment(lib,"softintrin") +#endif +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +struct DiyFp { + DiyFp() : f(), e() {} + + DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} + + explicit DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(f) * static_cast(rhs.f); + uint64_t h = static_cast(p >> 64); + uint64_t l = static_cast(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { + int s = static_cast(clzll(f)); + return DiyFp(f << s, e - s); + } + + DiyFp NormalizeBoundary() const { + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + double ToDouble() const { + union { + double d; + uint64_t u64; + }u; + RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask); + if (e < kDpDenormalExponent) { + // Underflow. + return 0.0; + } + if (e >= kDpMaxExponent) { + // Overflow. + return std::numeric_limits::infinity(); + } + const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : + static_cast(e + kDpExponentBias); + u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); + return u.d; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMaxExponent = 0x7FF - kDpExponentBias; + static const int kDpMinExponent = -kDpExponentBias; + static const int kDpDenormalExponent = -kDpExponentBias + 1; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPowerByIndex(size_t index) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + RAPIDJSON_ASSERT(index < 87); + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline DiyFp GetCachedPower(int e, int* K) { + + //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast(dk); + if (dk - k > 0.0) + k++; + + unsigned index = static_cast((k >> 3) + 1); + *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table + + return GetCachedPowerByIndex(index); +} + +inline DiyFp GetCachedPower10(int exp, int *outExp) { + RAPIDJSON_ASSERT(exp >= -348); + unsigned index = static_cast(exp + 348) / 8u; + *outExp = -348 + static_cast(index) * 8; + return GetCachedPowerByIndex(index); +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +RAPIDJSON_DIAG_OFF(padded) +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DIYFP_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/dtoa.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/dtoa.h new file mode 100644 index 000000000..91c5756d9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/dtoa.h @@ -0,0 +1,249 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#include "itoa.h" // GetDigitsLut() +#include "diyfp.h" +#include "ieee754.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 +#endif + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline int CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + // Will not reach 10 digits in DigitGen() + //if (n < 1000000000) return 9; + //return 10; + return 9; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL, + 1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL, + 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL, + 10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL, + 10000000000000000000ULL }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + int kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + *len = 0; + + while (kappa > 0) { + uint32_t d = 0; + switch (kappa) { + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default:; + } + if (d || *len) + buffer[(*len)++] = static_cast('0' + static_cast(d)); + kappa--; + uint64_t tmp = (static_cast(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, kPow10[kappa] << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + int index = -kappa; + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 20 ? kPow10[index] : 0)); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast('0' + static_cast(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast('0' + static_cast(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (0 <= k && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); + buffer[kk] = '.'; + if (0 > k + maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[kk + 2]; // Reserve one zero + } + else + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], static_cast(length)); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + if (length - kk > maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = maxDecimalPlaces + 1; i > 2; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[3]; // Reserve one zero + } + else + return &buffer[length + offset]; + } + else if (kk < -maxDecimalPlaces) { + // Truncate to zero + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { + RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); + Double d(value); + if (d.IsZero()) { + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K, maxDecimalPlaces); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DTOA_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/ieee754.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/ieee754.h new file mode 100644 index 000000000..f887d1b27 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/ieee754.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_IEEE754_ +#define RAPIDJSON_IEEE754_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class Double { +public: + Double() {} + Double(double d) : d_(d) {} + Double(uint64_t u) : u_(u) {} + + double Value() const { return d_; } + uint64_t Uint64Value() const { return u_; } + + double NextPositiveDouble() const { + RAPIDJSON_ASSERT(!Sign()); + return Double(u_ + 1).Value(); + } + + bool Sign() const { return (u_ & kSignMask) != 0; } + uint64_t Significand() const { return u_ & kSignificandMask; } + int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } + + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } + bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } + + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } + + static int EffectiveSignificandSize(int order) { + if (order >= -1021) + return 53; + else if (order <= -1074) + return 0; + else + return order + 1074; + } + +private: + static const int kSignificandSize = 52; + static const int kExponentBias = 0x3FF; + static const int kDenormalExponent = 1 - kExponentBias; + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + union { + double d_; + uint64_t u_; + }; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_IEEE754_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/itoa.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/itoa.h new file mode 100644 index 000000000..9fe8c932f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/itoa.h @@ -0,0 +1,308 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast('0' + static_cast(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + uint32_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u32toa(u, buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast('0' + static_cast(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast('0' + static_cast(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + RAPIDJSON_ASSERT(buffer != 0); + uint64_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u64toa(u, buffer); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ITOA_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/meta.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/meta.h new file mode 100644 index 000000000..76a1d5be4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/meta.h @@ -0,0 +1,186 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#include "../rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include +#endif + +//@cond RAPIDJSON_INTERNAL +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType TrueType; +typedef BoolType FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; +template struct SelectIfCond : SelectIfImpl::template Apply {}; +template struct SelectIf : SelectIfCond {}; + +template struct AndExprCond : FalseType {}; +template <> struct AndExprCond : TrueType {}; +template struct OrExprCond : TrueType {}; +template <> struct OrExprCond : FalseType {}; + +template struct BoolExpr : SelectIf::Type {}; +template struct NotExpr : SelectIf::Type {}; +template struct AndExpr : AndExprCond::Type {}; +template struct OrExpr : OrExprCond::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template struct AddConst { typedef const T Type; }; +template struct MaybeAddConst : SelectIfCond {}; +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template struct IsSame : FalseType {}; +template struct IsSame : TrueType {}; + +template struct IsConst : FalseType {}; +template struct IsConst : TrueType {}; + +template +struct IsMoreConst + : AndExpr::Type, typename RemoveConst::Type>, + BoolType::Value >= IsConst::Value> >::Type {}; + +template struct IsPointer : FalseType {}; +template struct IsPointer : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template struct IsBaseOf + : BoolType< ::std::is_base_of::value> {}; + +#else // simplified version adopted from Boost + +template struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template struct IsBaseOf + : OrExpr, BoolExpr > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template struct EnableIfCond { typedef T Type; }; +template struct EnableIfCond { /* empty */ }; + +template struct DisableIfCond { typedef T Type; }; +template struct DisableIfCond { /* empty */ }; + +template +struct EnableIf : EnableIfCond {}; + +template +struct DisableIf : DisableIfCond {}; + +// SFINAE helpers +struct SfinaeTag {}; +template struct RemoveSfinaeTag; +template struct RemoveSfinaeTag { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type + +} // namespace internal +RAPIDJSON_NAMESPACE_END +//@endcond + +#if defined(_MSC_VER) && !defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/pow10.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/pow10.h new file mode 100644 index 000000000..04ee1f6b4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/pow10.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_POW10_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/regex.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/regex.h new file mode 100644 index 000000000..e37126109 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/regex.h @@ -0,0 +1,739 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_REGEX_H_ +#define RAPIDJSON_INTERNAL_REGEX_H_ + +#include "../allocators.h" +#include "../stream.h" +#include "stack.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifndef RAPIDJSON_REGEX_VERBOSE +#define RAPIDJSON_REGEX_VERBOSE 0 +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// DecodedStream + +template +class DecodedStream { +public: + DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } + unsigned Peek() { return codepoint_; } + unsigned Take() { + unsigned c = codepoint_; + if (c) // No further decoding when '\0' + Decode(); + return c; + } + +private: + void Decode() { + if (!Encoding::Decode(ss_, &codepoint_)) + codepoint_ = 0; + } + + SourceStream& ss_; + unsigned codepoint_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericRegex + +static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 +static const SizeType kRegexInvalidRange = ~SizeType(0); + +template +class GenericRegexSearch; + +//! Regular expression engine with subset of ECMAscript grammar. +/*! + Supported regular expression syntax: + - \c ab Concatenation + - \c a|b Alternation + - \c a? Zero or one + - \c a* Zero or more + - \c a+ One or more + - \c a{3} Exactly 3 times + - \c a{3,} At least 3 times + - \c a{3,5} 3 to 5 times + - \c (ab) Grouping + - \c ^a At the beginning + - \c a$ At the end + - \c . Any character + - \c [abc] Character classes + - \c [a-c] Character class range + - \c [a-z0-9_] Character class combination + - \c [^abc] Negated character classes + - \c [^a-c] Negated character class range + - \c [\b] Backspace (U+0008) + - \c \\| \\\\ ... Escape characters + - \c \\f Form feed (U+000C) + - \c \\n Line feed (U+000A) + - \c \\r Carriage return (U+000D) + - \c \\t Tab (U+0009) + - \c \\v Vertical tab (U+000B) + + \note This is a Thompson NFA engine, implemented with reference to + Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", + https://swtch.com/~rsc/regexp/regexp1.html +*/ +template +class GenericRegex { +public: + typedef Encoding EncodingType; + typedef typename Encoding::Ch Ch; + template friend class GenericRegexSearch; + + GenericRegex(const Ch* source, Allocator* allocator = 0) : + ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_), + states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), + anchorBegin_(), anchorEnd_() + { + GenericStringStream ss(source); + DecodedStream, Encoding> ds(ss); + Parse(ds); + } + + ~GenericRegex() + { + RAPIDJSON_DELETE(ownAllocator_); + } + + bool IsValid() const { + return root_ != kRegexInvalidState; + } + +private: + enum Operator { + kZeroOrOne, + kZeroOrMore, + kOneOrMore, + kConcatenation, + kAlternation, + kLeftParenthesis + }; + + static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' + static const unsigned kRangeCharacterClass = 0xFFFFFFFE; + static const unsigned kRangeNegationFlag = 0x80000000; + + struct Range { + unsigned start; // + unsigned end; + SizeType next; + }; + + struct State { + SizeType out; //!< Equals to kInvalid for matching state + SizeType out1; //!< Equals to non-kInvalid for split + SizeType rangeStart; + unsigned codepoint; + }; + + struct Frag { + Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} + SizeType start; + SizeType out; //!< link-list of all output states + SizeType minIndex; + }; + + State& GetState(SizeType index) { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + const State& GetState(SizeType index) const { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + Range& GetRange(SizeType index) { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + const Range& GetRange(SizeType index) const { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + template + void Parse(DecodedStream& ds) { + Stack operandStack(allocator_, 256); // Frag + Stack operatorStack(allocator_, 256); // Operator + Stack atomCountStack(allocator_, 256); // unsigned (Atom per parenthesis) + + *atomCountStack.template Push() = 0; + + unsigned codepoint; + while (ds.Peek() != 0) { + switch (codepoint = ds.Take()) { + case '^': + anchorBegin_ = true; + break; + + case '$': + anchorEnd_ = true; + break; + + case '|': + while (!operatorStack.Empty() && *operatorStack.template Top() < kAlternation) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + *operatorStack.template Push() = kAlternation; + *atomCountStack.template Top() = 0; + break; + + case '(': + *operatorStack.template Push() = kLeftParenthesis; + *atomCountStack.template Push() = 0; + break; + + case ')': + while (!operatorStack.Empty() && *operatorStack.template Top() != kLeftParenthesis) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + if (operatorStack.Empty()) + return; + operatorStack.template Pop(1); + atomCountStack.template Pop(1); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '?': + if (!Eval(operandStack, kZeroOrOne)) + return; + break; + + case '*': + if (!Eval(operandStack, kZeroOrMore)) + return; + break; + + case '+': + if (!Eval(operandStack, kOneOrMore)) + return; + break; + + case '{': + { + unsigned n, m; + if (!ParseUnsigned(ds, &n)) + return; + + if (ds.Peek() == ',') { + ds.Take(); + if (ds.Peek() == '}') + m = kInfinityQuantifier; + else if (!ParseUnsigned(ds, &m) || m < n) + return; + } + else + m = n; + + if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') + return; + ds.Take(); + } + break; + + case '.': + PushOperand(operandStack, kAnyCharacterClass); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '[': + { + SizeType range; + if (!ParseRange(ds, &range)) + return; + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); + GetState(s).rangeStart = range; + *operandStack.template Push() = Frag(s, s, s); + } + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '\\': // Escape character + if (!CharacterEscape(ds, &codepoint)) + return; // Unsupported escape character + // fall through to default + RAPIDJSON_DELIBERATE_FALLTHROUGH; + + default: // Pattern character + PushOperand(operandStack, codepoint); + ImplicitConcatenation(atomCountStack, operatorStack); + } + } + + while (!operatorStack.Empty()) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + + // Link the operand to matching state. + if (operandStack.GetSize() == sizeof(Frag)) { + Frag* e = operandStack.template Pop(1); + Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); + root_ = e->start; + +#if RAPIDJSON_REGEX_VERBOSE + printf("root: %d\n", root_); + for (SizeType i = 0; i < stateCount_ ; i++) { + State& s = GetState(i); + printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); + } + printf("\n"); +#endif + } + } + + SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { + State* s = states_.template Push(); + s->out = out; + s->out1 = out1; + s->codepoint = codepoint; + s->rangeStart = kRegexInvalidRange; + return stateCount_++; + } + + void PushOperand(Stack& operandStack, unsigned codepoint) { + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); + *operandStack.template Push() = Frag(s, s, s); + } + + void ImplicitConcatenation(Stack& atomCountStack, Stack& operatorStack) { + if (*atomCountStack.template Top()) + *operatorStack.template Push() = kConcatenation; + (*atomCountStack.template Top())++; + } + + SizeType Append(SizeType l1, SizeType l2) { + SizeType old = l1; + while (GetState(l1).out != kRegexInvalidState) + l1 = GetState(l1).out; + GetState(l1).out = l2; + return old; + } + + void Patch(SizeType l, SizeType s) { + for (SizeType next; l != kRegexInvalidState; l = next) { + next = GetState(l).out; + GetState(l).out = s; + } + } + + bool Eval(Stack& operandStack, Operator op) { + switch (op) { + case kConcatenation: + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); + { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + Patch(e1.out, e2.start); + *operandStack.template Push() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); + } + return true; + + case kAlternation: + if (operandStack.GetSize() >= sizeof(Frag) * 2) { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + SizeType s = NewState(e1.start, e2.start, 0); + *operandStack.template Push() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); + return true; + } + return false; + + case kZeroOrOne: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + *operandStack.template Push() = Frag(s, Append(e.out, s), e.minIndex); + return true; + } + return false; + + case kZeroOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(s, s, e.minIndex); + return true; + } + return false; + + case kOneOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(e.start, s, e.minIndex); + return true; + } + return false; + + default: + // syntax error (e.g. unclosed kLeftParenthesis) + return false; + } + } + + bool EvalQuantifier(Stack& operandStack, unsigned n, unsigned m) { + RAPIDJSON_ASSERT(n <= m); + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); + + if (n == 0) { + if (m == 0) // a{0} not support + return false; + else if (m == kInfinityQuantifier) + Eval(operandStack, kZeroOrMore); // a{0,} -> a* + else { + Eval(operandStack, kZeroOrOne); // a{0,5} -> a? + for (unsigned i = 0; i < m - 1; i++) + CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? + for (unsigned i = 0; i < m - 1; i++) + Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? + } + return true; + } + + for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a + CloneTopOperand(operandStack); + + if (m == kInfinityQuantifier) + Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ + else if (m > n) { + CloneTopOperand(operandStack); // a{3,5} -> a a a a + Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? + for (unsigned i = n; i < m - 1; i++) + CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? + for (unsigned i = n; i < m; i++) + Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? + } + + for (unsigned i = 0; i < n - 1; i++) + Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? + + return true; + } + + static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } + + void CloneTopOperand(Stack& operandStack) { + const Frag src = *operandStack.template Top(); // Copy constructor to prevent invalidation + SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) + State* s = states_.template Push(count); + memcpy(s, &GetState(src.minIndex), count * sizeof(State)); + for (SizeType j = 0; j < count; j++) { + if (s[j].out != kRegexInvalidState) + s[j].out += count; + if (s[j].out1 != kRegexInvalidState) + s[j].out1 += count; + } + *operandStack.template Push() = Frag(src.start + count, src.out + count, src.minIndex + count); + stateCount_ += count; + } + + template + bool ParseUnsigned(DecodedStream& ds, unsigned* u) { + unsigned r = 0; + if (ds.Peek() < '0' || ds.Peek() > '9') + return false; + while (ds.Peek() >= '0' && ds.Peek() <= '9') { + if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 + return false; // overflow + r = r * 10 + (ds.Take() - '0'); + } + *u = r; + return true; + } + + template + bool ParseRange(DecodedStream& ds, SizeType* range) { + bool isBegin = true; + bool negate = false; + int step = 0; + SizeType start = kRegexInvalidRange; + SizeType current = kRegexInvalidRange; + unsigned codepoint; + while ((codepoint = ds.Take()) != 0) { + if (isBegin) { + isBegin = false; + if (codepoint == '^') { + negate = true; + continue; + } + } + + switch (codepoint) { + case ']': + if (start == kRegexInvalidRange) + return false; // Error: nothing inside [] + if (step == 2) { // Add trailing '-' + SizeType r = NewRange('-'); + RAPIDJSON_ASSERT(current != kRegexInvalidRange); + GetRange(current).next = r; + } + if (negate) + GetRange(start).start |= kRangeNegationFlag; + *range = start; + return true; + + case '\\': + if (ds.Peek() == 'b') { + ds.Take(); + codepoint = 0x0008; // Escape backspace character + } + else if (!CharacterEscape(ds, &codepoint)) + return false; + // fall through to default + RAPIDJSON_DELIBERATE_FALLTHROUGH; + + default: + switch (step) { + case 1: + if (codepoint == '-') { + step++; + break; + } + // fall through to step 0 for other characters + RAPIDJSON_DELIBERATE_FALLTHROUGH; + + case 0: + { + SizeType r = NewRange(codepoint); + if (current != kRegexInvalidRange) + GetRange(current).next = r; + if (start == kRegexInvalidRange) + start = r; + current = r; + } + step = 1; + break; + + default: + RAPIDJSON_ASSERT(step == 2); + GetRange(current).end = codepoint; + step = 0; + } + } + } + return false; + } + + SizeType NewRange(unsigned codepoint) { + Range* r = ranges_.template Push(); + r->start = r->end = codepoint; + r->next = kRegexInvalidRange; + return rangeCount_++; + } + + template + bool CharacterEscape(DecodedStream& ds, unsigned* escapedCodepoint) { + unsigned codepoint; + switch (codepoint = ds.Take()) { + case '^': + case '$': + case '|': + case '(': + case ')': + case '?': + case '*': + case '+': + case '.': + case '[': + case ']': + case '{': + case '}': + case '\\': + *escapedCodepoint = codepoint; return true; + case 'f': *escapedCodepoint = 0x000C; return true; + case 'n': *escapedCodepoint = 0x000A; return true; + case 'r': *escapedCodepoint = 0x000D; return true; + case 't': *escapedCodepoint = 0x0009; return true; + case 'v': *escapedCodepoint = 0x000B; return true; + default: + return false; // Unsupported escape character + } + } + + Allocator* ownAllocator_; + Allocator* allocator_; + Stack states_; + Stack ranges_; + SizeType root_; + SizeType stateCount_; + SizeType rangeCount_; + + static const unsigned kInfinityQuantifier = ~0u; + + // For SearchWithAnchoring() + bool anchorBegin_; + bool anchorEnd_; +}; + +template +class GenericRegexSearch { +public: + typedef typename RegexType::EncodingType Encoding; + typedef typename Encoding::Ch Ch; + + GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : + regex_(regex), allocator_(allocator), ownAllocator_(0), + state0_(allocator, 0), state1_(allocator, 0), stateSet_() + { + RAPIDJSON_ASSERT(regex_.IsValid()); + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + stateSet_ = static_cast(allocator_->Malloc(GetStateSetSize())); + state0_.template Reserve(regex_.stateCount_); + state1_.template Reserve(regex_.stateCount_); + } + + ~GenericRegexSearch() { + Allocator::Free(stateSet_); + RAPIDJSON_DELETE(ownAllocator_); + } + + template + bool Match(InputStream& is) { + return SearchWithAnchoring(is, true, true); + } + + bool Match(const Ch* s) { + GenericStringStream is(s); + return Match(is); + } + + template + bool Search(InputStream& is) { + return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_); + } + + bool Search(const Ch* s) { + GenericStringStream is(s); + return Search(is); + } + +private: + typedef typename RegexType::State State; + typedef typename RegexType::Range Range; + + template + bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) { + DecodedStream ds(is); + + state0_.Clear(); + Stack *current = &state0_, *next = &state1_; + const size_t stateSetSize = GetStateSetSize(); + std::memset(stateSet_, 0, stateSetSize); + + bool matched = AddState(*current, regex_.root_); + unsigned codepoint; + while (!current->Empty() && (codepoint = ds.Take()) != 0) { + std::memset(stateSet_, 0, stateSetSize); + next->Clear(); + matched = false; + for (const SizeType* s = current->template Bottom(); s != current->template End(); ++s) { + const State& sr = regex_.GetState(*s); + if (sr.codepoint == codepoint || + sr.codepoint == RegexType::kAnyCharacterClass || + (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) + { + matched = AddState(*next, sr.out) || matched; + if (!anchorEnd && matched) + return true; + } + if (!anchorBegin) + AddState(*next, regex_.root_); + } + internal::Swap(current, next); + } + + return matched; + } + + size_t GetStateSetSize() const { + return (regex_.stateCount_ + 31) / 32 * 4; + } + + // Return whether the added states is a match state + bool AddState(Stack& l, SizeType index) { + RAPIDJSON_ASSERT(index != kRegexInvalidState); + + const State& s = regex_.GetState(index); + if (s.out1 != kRegexInvalidState) { // Split + bool matched = AddState(l, s.out); + return AddState(l, s.out1) || matched; + } + else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) { + stateSet_[index >> 5] |= (1u << (index & 31)); + *l.template PushUnsafe() = index; + } + return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. + } + + bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { + bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0; + while (rangeIndex != kRegexInvalidRange) { + const Range& r = regex_.GetRange(rangeIndex); + if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end) + return yes; + rangeIndex = r.next; + } + return !yes; + } + + const RegexType& regex_; + Allocator* allocator_; + Allocator* ownAllocator_; + Stack state0_; + Stack state1_; + uint32_t* stateSet_; +}; + +typedef GenericRegex > Regex; +typedef GenericRegexSearch RegexSearch; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/stack.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/stack.h new file mode 100644 index 000000000..ceead4490 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/stack.h @@ -0,0 +1,232 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +#include "../allocators.h" +#include "swap.h" +#include + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack(Stack&& rhs) + : allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(rhs.stack_), + stackTop_(rhs.stackTop_), + stackEnd_(rhs.stackEnd_), + initialCapacity_(rhs.initialCapacity_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } +#endif + + ~Stack() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack& operator=(Stack&& rhs) { + if (&rhs != this) + { + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = rhs.stack_; + stackTop_ = rhs.stackTop_; + stackEnd_ = rhs.stackEnd_; + initialCapacity_ = rhs.initialCapacity_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } + return *this; + } +#endif + + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(stack_, rhs.stack_); + internal::Swap(stackTop_, rhs.stackTop_); + internal::Swap(stackEnd_, rhs.stackEnd_); + internal::Swap(initialCapacity_, rhs.initialCapacity_); + } + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc) + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { + // Expand the stack if needed + if (RAPIDJSON_UNLIKELY(static_cast(sizeof(T) * count) > (stackEnd_ - stackTop_))) + Expand(count); + } + + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + Reserve(count); + return PushUnsafe(count); + } + + template + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { + RAPIDJSON_ASSERT(stackTop_); + RAPIDJSON_ASSERT(static_cast(sizeof(T) * count) <= (stackEnd_ - stackTop_)); + T* ret = reinterpret_cast(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast(stackTop_); + } + + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + const T* Top() const { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + T* End() { return reinterpret_cast(stackTop_); } + + template + const T* End() const { return reinterpret_cast(stackTop_); } + + template + T* Bottom() { return reinterpret_cast(stack_); } + + template + const T* Bottom() const { return reinterpret_cast(stack_); } + + bool HasAllocator() const { + return allocator_ != 0; + } + + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } + +private: + template + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + newCapacity = initialCapacity_; + } else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + void Destroy() { + Allocator::Free(stack_); + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator_; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STACK_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strfunc.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strfunc.h new file mode 100644 index 000000000..1a88f49bb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strfunc.h @@ -0,0 +1,83 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +#include "../stream.h" +#include + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template +inline SizeType StrLen(const Ch* s) { + RAPIDJSON_ASSERT(s != 0); + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +template <> +inline SizeType StrLen(const char* s) { + return SizeType(std::strlen(s)); +} + +template <> +inline SizeType StrLen(const wchar_t* s) { + return SizeType(std::wcslen(s)); +} + +//! Custom strcmpn() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s1 Null-terminated input string. + \param s2 Null-terminated input string. + \return 0 if equal +*/ +template +inline int StrCmp(const Ch* s1, const Ch* s2) { + RAPIDJSON_ASSERT(s1 != 0); + RAPIDJSON_ASSERT(s2 != 0); + while(*s1 && (*s1 == *s2)) { s1++; s2++; } + return static_cast(*s1) < static_cast(*s2) ? -1 : static_cast(*s1) > static_cast(*s2); +} + +//! Returns number of code points in a encoded string. +template +bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { + RAPIDJSON_ASSERT(s != 0); + RAPIDJSON_ASSERT(outCount != 0); + GenericStringStream is(s); + const typename Encoding::Ch* end = s + length; + SizeType count = 0; + while (is.src_ < end) { + unsigned codepoint; + if (!Encoding::Decode(is, &codepoint)) + return false; + count++; + } + *outCount = count; + return true; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strtod.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strtod.h new file mode 100644 index 000000000..62a42c69d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/strtod.h @@ -0,0 +1,293 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRTOD_ +#define RAPIDJSON_STRTOD_ + +#include "ieee754.h" +#include "biginteger.h" +#include "diyfp.h" +#include "pow10.h" +#include +#include + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline double FastPath(double significand, int exp) { + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); +} + +inline double StrtodNormalPrecision(double d, int p) { + if (p < -308) { + // Prevent expSum < -308, making Pow10(p) = 0 + d = FastPath(d, -308); + d = FastPath(d, p + 308); + } + else + d = FastPath(d, p); + return d; +} + +template +inline T Min3(T a, T b, T c) { + T m = a; + if (m > b) m = b; + if (m > c) m = c; + return m; +} + +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { + const Double db(b); + const uint64_t bInt = db.IntegerSignificand(); + const int bExp = db.IntegerExponent(); + const int hExp = bExp - 1; + + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; + + // Adjust for decimal exponent + if (dExp >= 0) { + dS_Exp2 += dExp; + dS_Exp5 += dExp; + } + else { + bS_Exp2 -= dExp; + bS_Exp5 -= dExp; + hS_Exp2 -= dExp; + hS_Exp5 -= dExp; + } + + // Adjust for binary exponent + if (bExp >= 0) + bS_Exp2 += bExp; + else { + dS_Exp2 -= bExp; + hS_Exp2 -= bExp; + } + + // Adjust for half ulp exponent + if (hExp >= 0) + hS_Exp2 += hExp; + else { + dS_Exp2 -= hExp; + bS_Exp2 -= hExp; + } + + // Remove common power of two factor from all three scaled values + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); + dS_Exp2 -= common_Exp2; + bS_Exp2 -= common_Exp2; + hS_Exp2 -= common_Exp2; + + BigInteger dS = d; + dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); + + BigInteger bS(bInt); + bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); + + BigInteger hS(1); + hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); + + BigInteger delta(0); + dS.Difference(bS, &delta); + + return delta.Compare(hS); +} + +inline bool StrtodFast(double d, int p, double* result) { + // Use fast path for string-to-double conversion if possible + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (p > 22 && p < 22 + 16) { + // Fast Path Cases In Disguise + d *= internal::Pow10(p - 22); + p = 22; + } + + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 + *result = FastPath(d, p); + return true; + } + else + return false; +} + +// Compute an approximation and see if it is within 1/2 ULP +template +inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result) { + uint64_t significand = 0; + int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 + for (; i < dLen; i++) { + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5'))) + break; + significand = significand * 10u + static_cast(decimals[i] - Ch('0')); + } + + if (i < dLen && decimals[i] >= Ch('5')) // Rounding + significand++; + + int remaining = dLen - i; + const int kUlpShift = 3; + const int kUlp = 1 << kUlpShift; + int64_t error = (remaining == 0) ? 0 : kUlp / 2; + + DiyFp v(significand, 0); + v = v.Normalize(); + error <<= -v.e; + + dExp += remaining; + + int actualExp; + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); + if (actualExp != dExp) { + static const DiyFp kPow10[] = { + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60), // 10^1 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57), // 10^2 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54), // 10^3 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50), // 10^4 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47), // 10^5 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44), // 10^6 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40) // 10^7 + }; + int adjustment = dExp - actualExp; + RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8); + v = v * kPow10[adjustment - 1]; + if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit + error += kUlp / 2; + } + + v = v * cachedPower; + + error += kUlp + (error == 0 ? 0 : 1); + + const int oldExp = v.e; + v = v.Normalize(); + error <<= oldExp - v.e; + + const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + int precisionSize = 64 - effectiveSignificandSize; + if (precisionSize + kUlpShift >= 64) { + int scaleExp = (precisionSize + kUlpShift) - 63; + v.f >>= scaleExp; + v.e += scaleExp; + error = (error >> scaleExp) + 1 + kUlp; + precisionSize -= scaleExp; + } + + DiyFp rounded(v.f >> precisionSize, v.e + precisionSize); + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; + if (precisionBits >= halfWay + static_cast(error)) { + rounded.f++; + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) + rounded.f >>= 1; + rounded.e++; + } + } + + *result = rounded.ToDouble(); + + return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); +} + +template +inline double StrtodBigInteger(double approx, const Ch* decimals, int dLen, int dExp) { + RAPIDJSON_ASSERT(dLen >= 0); + const BigInteger dInt(decimals, static_cast(dLen)); + Double a(approx); + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); + if (cmp < 0) + return a.Value(); // within half ULP + else if (cmp == 0) { + // Round towards even + if (a.Significand() & 1) + return a.NextPositiveDouble(); + else + return a.Value(); + } + else // adjustment + return a.NextPositiveDouble(); +} + +template +inline double StrtodFullPrecision(double d, int p, const Ch* decimals, size_t length, size_t decimalPosition, int exp) { + RAPIDJSON_ASSERT(d >= 0.0); + RAPIDJSON_ASSERT(length >= 1); + + double result = 0.0; + if (StrtodFast(d, p, &result)) + return result; + + RAPIDJSON_ASSERT(length <= INT_MAX); + int dLen = static_cast(length); + + RAPIDJSON_ASSERT(length >= decimalPosition); + RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX); + int dExpAdjust = static_cast(length - decimalPosition); + + RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust); + int dExp = exp - dExpAdjust; + + // Make sure length+dExp does not overflow + RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen); + + // Trim leading zeros + while (dLen > 0 && *decimals == '0') { + dLen--; + decimals++; + } + + // Trim trailing zeros + while (dLen > 0 && decimals[dLen - 1] == '0') { + dLen--; + dExp++; + } + + if (dLen == 0) { // Buffer only contains zeros. + return 0.0; + } + + // Trim right-most digits + const int kMaxDecimalDigit = 767 + 1; + if (dLen > kMaxDecimalDigit) { + dExp += dLen - kMaxDecimalDigit; + dLen = kMaxDecimalDigit; + } + + // If too small, underflow to zero. + // Any x <= 10^-324 is interpreted as zero. + if (dLen + dExp <= -324) + return 0.0; + + // If too large, overflow to infinity. + // Any x >= 10^309 is interpreted as +infinity. + if (dLen + dExp > 309) + return std::numeric_limits::infinity(); + + if (StrtodDiyFp(decimals, dLen, dExp, &result)) + return result; + + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison + return StrtodBigInteger(result, decimals, dLen, dExp); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRTOD_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/swap.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/swap.h new file mode 100644 index 000000000..2cf92f93a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/internal/swap.h @@ -0,0 +1,46 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_SWAP_H_ +#define RAPIDJSON_INTERNAL_SWAP_H_ + +#include "../rapidjson.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom swap() to avoid dependency on C++ header +/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. + \note This has the same semantics as std::swap(). +*/ +template +inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { + T tmp = a; + a = b; + b = tmp; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/istreamwrapper.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/istreamwrapper.h new file mode 100644 index 000000000..23dd83e96 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/istreamwrapper.h @@ -0,0 +1,128 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ +#define RAPIDJSON_ISTREAMWRAPPER_H_ + +#include "stream.h" +#include +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::istringstream + - \c std::stringstream + - \c std::wistringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wifstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_istream. +*/ + +template +class BasicIStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + + //! Constructor. + /*! + \param stream stream opened for read. + */ + BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + Read(); + } + + //! Constructor. + /*! + \param stream stream opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; + } + +private: + BasicIStreamWrapper(); + BasicIStreamWrapper(const BasicIStreamWrapper&); + BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); + + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = bufferSize_; + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (!stream_.read(buffer_, static_cast(bufferSize_))) { + readCount_ = static_cast(stream_.gcount()); + *(bufferLast_ = buffer_ + readCount_) = '\0'; + eof_ = true; + } + } + } + + StreamType &stream_; + Ch peekBuffer_[4], *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +typedef BasicIStreamWrapper IStreamWrapper; +typedef BasicIStreamWrapper WIStreamWrapper; + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorybuffer.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorybuffer.h new file mode 100644 index 000000000..14aad6863 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorybuffer.h @@ -0,0 +1,70 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorystream.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorystream.h new file mode 100644 index 000000000..1bc393f28 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/memorystream.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "stream.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } + Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/inttypes.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/inttypes.h new file mode 100644 index 000000000..1620402e0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,316 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// miloyip: VC supports inttypes.h since VC2013 +#if _MSC_VER >= 1800 +#include +#else + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_VER >= 1800 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/stdint.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/stdint.h new file mode 100644 index 000000000..1c266ecfe --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/stdint.h @@ -0,0 +1,300 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we have to wrap include with 'extern "C++" {}' +// or compiler would give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if defined(__cplusplus) && !defined(_M_ARM) +extern "C" { +#endif +# include +#if defined(__cplusplus) && !defined(_M_ARM) +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/ostreamwrapper.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/ostreamwrapper.h new file mode 100644 index 000000000..bfd4d6dab --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/ostreamwrapper.h @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ +#define RAPIDJSON_OSTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::ostringstream + - \c std::stringstream + - \c std::wpstringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wofstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_ostream. +*/ + +template +class BasicOStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} + + void Put(Ch c) { + stream_.put(c); + } + + void Flush() { + stream_.flush(); + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + BasicOStreamWrapper(const BasicOStreamWrapper&); + BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); + + StreamType& stream_; +}; + +typedef BasicOStreamWrapper OStreamWrapper; +typedef BasicOStreamWrapper WOStreamWrapper; + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/pointer.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/pointer.h new file mode 100644 index 000000000..d0d762d2a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/pointer.h @@ -0,0 +1,1470 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POINTER_H_ +#define RAPIDJSON_POINTER_H_ + +#include "document.h" +#include "uri.h" +#include "internal/itoa.h" +#include "error/error.h" // PointerParseErrorCode + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token + +/////////////////////////////////////////////////////////////////////////////// +// GenericPointer + +//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. +/*! + This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" + (https://tools.ietf.org/html/rfc6901). + + A JSON pointer is for identifying a specific value in a JSON document + (GenericDocument). It can simplify coding of DOM tree manipulation, because it + can access multiple-level depth of DOM tree with single API call. + + After it parses a string representation (e.g. "/foo/0" or URI fragment + representation (e.g. "#/foo/0") into its internal representation (tokens), + it can be used to resolve a specific value in multiple documents, or sub-tree + of documents. + + Contrary to GenericValue, Pointer can be copy constructed and copy assigned. + Apart from assignment, a Pointer cannot be modified after construction. + + Although Pointer is very convenient, please aware that constructing Pointer + involves parsing and dynamic memory allocation. A special constructor with user- + supplied tokens eliminates these. + + GenericPointer depends on GenericDocument and GenericValue. + + \tparam ValueType The value type of the DOM tree. E.g. GenericValue > + \tparam Allocator The allocator type for allocating memory for internal representation. + + \note GenericPointer uses same encoding of ValueType. + However, Allocator of GenericPointer is independent of Allocator of Value. +*/ +template +class GenericPointer { +public: + typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value + typedef typename ValueType::Ch Ch; //!< Character type from Value + typedef GenericUri UriType; + + + //! A token is the basic units of internal representation. + /*! + A JSON pointer string representation "/foo/123" is parsed to two tokens: + "foo" and 123. 123 will be represented in both numeric form and string form. + They are resolved according to the actual value type (object or array). + + For token that are not numbers, or the numeric value is out of bound + (greater than limits of SizeType), they are only treated as string form + (i.e. the token's index will be equal to kPointerInvalidIndex). + + This struct is public so that user can create a Pointer without parsing and + allocation, using a special constructor. + */ + struct Token { + const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. + SizeType length; //!< Length of the name. + SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. + }; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor. + GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A null-terminated, string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + */ + explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, internal::StrLen(source)); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + explicit GenericPointer(const std::basic_string& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source.c_str(), source.size()); + } +#endif + + //! Constructor that parses a string or URI fragment representation, with length of the source string. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param length Length of source. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Slightly faster than the overload without length. + */ + GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, length); + } + + //! Constructor with user-supplied tokens. + /*! + This constructor let user supplies const array of tokens. + This prevents the parsing process and eliminates allocation. + This is preferred for memory constrained environments. + + \param tokens An constant array of tokens representing the JSON pointer. + \param tokenCount Number of tokens. + + \b Example + \code + #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } + #define INDEX(i) { #i, sizeof(#i) - 1, i } + + static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; + static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); + // Equivalent to static const Pointer p("/foo/123"); + + #undef NAME + #undef INDEX + \endcode + */ + GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Destructor. + ~GenericPointer() { + if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. + Allocator::Free(tokens_); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator. + GenericPointer& operator=(const GenericPointer& rhs) { + if (this != &rhs) { + // Do not delete ownAllocator + if (nameBuffer_) + Allocator::Free(tokens_); + + tokenCount_ = rhs.tokenCount_; + parseErrorOffset_ = rhs.parseErrorOffset_; + parseErrorCode_ = rhs.parseErrorCode_; + + if (rhs.nameBuffer_) + CopyFromRaw(rhs); // Normally parsed tokens. + else { + tokens_ = rhs.tokens_; // User supplied const tokens. + nameBuffer_ = 0; + } + } + return *this; + } + + //! Swap the content of this pointer with another. + /*! + \param other The pointer to swap with. + \note Constant complexity. + */ + GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, other.allocator_); + internal::Swap(ownAllocator_, other.ownAllocator_); + internal::Swap(nameBuffer_, other.nameBuffer_); + internal::Swap(tokens_, other.tokens_); + internal::Swap(tokenCount_, other.tokenCount_); + internal::Swap(parseErrorOffset_, other.parseErrorOffset_); + internal::Swap(parseErrorCode_, other.parseErrorCode_); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.pointer, b.pointer); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //@} + + //!@name Append token + //@{ + + //! Append a token and return a new Pointer + /*! + \param token Token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Token& token, Allocator* allocator = 0) const { + GenericPointer r; + r.allocator_ = allocator; + Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); + std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); + r.tokens_[tokenCount_].name = p; + r.tokens_[tokenCount_].length = token.length; + r.tokens_[tokenCount_].index = token.index; + return r; + } + + //! Append a name token with length, and return a new Pointer + /*! + \param name Name to be appended. + \param length Length of name. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { + Token token = { name, length, kPointerInvalidIndex }; + return Append(token, allocator); + } + + //! Append a name token without length, and return a new Pointer + /*! + \param name Name (const Ch*) to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >), (GenericPointer)) + Append(T* name, Allocator* allocator = 0) const { + return Append(name, internal::StrLen(name), allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Append a name token, and return a new Pointer + /*! + \param name Name to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const std::basic_string& name, Allocator* allocator = 0) const { + return Append(name.c_str(), static_cast(name.size()), allocator); + } +#endif + + //! Append a index token, and return a new Pointer + /*! + \param index Index to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(SizeType index, Allocator* allocator = 0) const { + char buffer[21]; + char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); + SizeType length = static_cast(end - buffer); + buffer[length] = '\0'; + + if (sizeof(Ch) == 1) { + Token token = { reinterpret_cast(buffer), length, index }; + return Append(token, allocator); + } + else { + Ch name[21]; + for (size_t i = 0; i <= length; i++) + name[i] = static_cast(buffer[i]); + Token token = { name, length, index }; + return Append(token, allocator); + } + } + + //! Append a token by value, and return a new Pointer + /*! + \param token token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { + if (token.IsString()) + return Append(token.GetString(), token.GetStringLength(), allocator); + else { + RAPIDJSON_ASSERT(token.IsUint64()); + RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); + return Append(static_cast(token.GetUint64()), allocator); + } + } + + //!@name Handling Parse Error + //@{ + + //! Check whether this is a valid pointer. + bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } + + //! Get the parsing error offset in code unit. + size_t GetParseErrorOffset() const { return parseErrorOffset_; } + + //! Get the parsing error code. + PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } + + //@} + + //! Get the allocator of this pointer. + Allocator& GetAllocator() { return *allocator_; } + + //!@name Tokens + //@{ + + //! Get the token array (const version only). + const Token* GetTokens() const { return tokens_; } + + //! Get the number of tokens. + size_t GetTokenCount() const { return tokenCount_; } + + //@} + + //!@name Equality/inequality operators + //@{ + + //! Equality operator. + /*! + \note When any pointers are invalid, always returns false. + */ + bool operator==(const GenericPointer& rhs) const { + if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) + return false; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index || + tokens_[i].length != rhs.tokens_[i].length || + (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) + { + return false; + } + } + + return true; + } + + //! Inequality operator. + /*! + \note When any pointers are invalid, always returns true. + */ + bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } + + //! Less than operator. + /*! + \note Invalid pointers are always greater than valid ones. + */ + bool operator<(const GenericPointer& rhs) const { + if (!IsValid()) + return false; + if (!rhs.IsValid()) + return true; + + if (tokenCount_ != rhs.tokenCount_) + return tokenCount_ < rhs.tokenCount_; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index) + return tokens_[i].index < rhs.tokens_[i].index; + + if (tokens_[i].length != rhs.tokens_[i].length) + return tokens_[i].length < rhs.tokens_[i].length; + + if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length)) + return cmp < 0; + } + + return false; + } + + //@} + + //!@name Stringify + //@{ + + //! Stringify the pointer into string representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + return Stringify(os); + } + + //! Stringify the pointer into URI fragment representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool StringifyUriFragment(OutputStream& os) const { + return Stringify(os); + } + + //@} + + //!@name Create value + //@{ + + //! Create a value in a subtree. + /*! + If the value is not exist, it creates all parent values and a JSON Null value. + So it always succeed and return the newly created or existing value. + + Remind that it may change types of parents according to tokens, so it + potentially removes previously stored values. For example, if a document + was an array, and "/foo" is used to create a value, then the document + will be changed to an object, and all existing array elements are lost. + + \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created (a JSON Null value), or already exists value. + */ + ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + bool exist = true; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + if (v->IsArray() && t->name[0] == '-' && t->length == 1) { + v->PushBack(ValueType().Move(), allocator); + v = &((*v)[v->Size() - 1]); + exist = false; + } + else { + if (t->index == kPointerInvalidIndex) { // must be object name + if (!v->IsObject()) + v->SetObject(); // Change to Object + } + else { // object name or array index + if (!v->IsArray() && !v->IsObject()) + v->SetArray(); // Change to Array + } + + if (v->IsArray()) { + if (t->index >= v->Size()) { + v->Reserve(t->index + 1, allocator); + while (t->index >= v->Size()) + v->PushBack(ValueType().Move(), allocator); + exist = false; + } + v = &((*v)[t->index]); + } + else { + typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) { + v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); + m = v->MemberEnd(); + v = &(--m)->value; // Assumes AddMember() appends at the end + exist = false; + } + else + v = &m->value; + } + } + } + + if (alreadyExist) + *alreadyExist = exist; + + return *v; + } + + //! Creates a value in a document. + /*! + \param document A document to be resolved. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created, or already exists value. + */ + template + ValueType& Create(GenericDocument& document, bool* alreadyExist = 0) const { + return Create(document, document.GetAllocator(), alreadyExist); + } + + //@} + + //!@name Compute URI + //@{ + + //! Compute the in-scope URI for a subtree. + // For use with JSON pointers into JSON schema documents. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param rootUri Root URI + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \param allocator Allocator for Uris + \return Uri if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a URI cannot be resolved: + 1. A value in the path is neither an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { + static const Ch kIdString[] = { 'i', 'd', '\0' }; + static const ValueType kIdValue(kIdString, 2); + UriType base = UriType(rootUri, allocator); + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + // See if we have an id, and if so resolve with the current base + typename ValueType::MemberIterator m = v->FindMember(kIdValue); + if (m != v->MemberEnd() && (m->value).IsString()) { + UriType here = UriType(m->value, allocator).Resolve(base, allocator); + base = here; + } + m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return UriType(allocator); + } + return base; + } + + UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { + return GetUri(const_cast(root), rootUri, unresolvedTokenIndex, allocator); + } + + + //!@name Query value + //@{ + + //! Query a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \return Pointer to the value if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a value cannot be resolved: + 1. A value in the path is neither an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return 0; + } + return v; + } + + //! Query a const value in a const subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Pointer to the value if it can be resolved. Otherwise null. + */ + const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { + return Get(const_cast(root), unresolvedTokenIndex); + } + + //@} + + //!@name Query a value with default + //@{ + + //! Query a value in a subtree with default value. + /*! + Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. + So that this function always succeed. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param defaultValue Default value to be cloned if the value was not exists. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + ValueType& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); + } + + //! Query a value in a subtree with default null-terminated string. + ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + ValueType& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a subtree with default std::basic_string. + ValueType& GetWithDefault(ValueType& root, const std::basic_string& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + ValueType& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } +#endif + + //! Query a value in a subtree with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { + return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); + } + + //! Query a value in a document with default value. + template + ValueType& GetWithDefault(GenericDocument& document, const ValueType& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //! Query a value in a document with default null-terminated string. + template + ValueType& GetWithDefault(GenericDocument& document, const Ch* defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a document with default std::basic_string. + template + ValueType& GetWithDefault(GenericDocument& document, const std::basic_string& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } +#endif + + //! Query a value in a document with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(GenericDocument& document, T defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //@} + + //!@name Set a value + //@{ + + //! Set a value in a subtree, with move semantics. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be set. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = value; + } + + //! Set a value in a subtree, with copy semantics. + ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).CopyFrom(value, allocator); + } + + //! Set a null-terminated string in a subtree. + ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Set a std::basic_string in a subtree. + ValueType& Set(ValueType& root, const std::basic_string& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } +#endif + + //! Set a primitive value in a subtree. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value).Move(); + } + + //! Set a value in a document, with move semantics. + template + ValueType& Set(GenericDocument& document, ValueType& value) const { + return Create(document) = value; + } + + //! Set a value in a document, with copy semantics. + template + ValueType& Set(GenericDocument& document, const ValueType& value) const { + return Create(document).CopyFrom(value, document.GetAllocator()); + } + + //! Set a null-terminated string in a document. + template + ValueType& Set(GenericDocument& document, const Ch* value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Sets a std::basic_string in a document. + template + ValueType& Set(GenericDocument& document, const std::basic_string& value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } +#endif + + //! Set a primitive value in a document. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(GenericDocument& document, T value) const { + return Create(document) = value; + } + + //@} + + //!@name Swap a value + //@{ + + //! Swap a value with a value in a subtree. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be swapped. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).Swap(value); + } + + //! Swap a value with a value in a document. + template + ValueType& Swap(GenericDocument& document, ValueType& value) const { + return Create(document).Swap(value); + } + + //@} + + //! Erase a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Whether the resolved value is found and erased. + + \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. + */ + bool Erase(ValueType& root) const { + RAPIDJSON_ASSERT(IsValid()); + if (tokenCount_ == 0) // Cannot erase the root + return false; + + ValueType* v = &root; + const Token* last = tokens_ + (tokenCount_ - 1); + for (const Token *t = tokens_; t != last; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); + if (m == v->MemberEnd()) + return false; + v = &m->value; + } + break; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + return false; + v = &((*v)[t->index]); + break; + default: + return false; + } + } + + switch (v->GetType()) { + case kObjectType: + return v->EraseMember(GenericStringRef(last->name, last->length)); + case kArrayType: + if (last->index == kPointerInvalidIndex || last->index >= v->Size()) + return false; + v->Erase(v->Begin() + last->index); + return true; + default: + return false; + } + } + +private: + //! Clone the content from rhs to this. + /*! + \param rhs Source pointer. + \param extraToken Extra tokens to be allocated. + \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. + \return Start of non-occupied name buffer, for storing extra names. + */ + Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { + if (!allocator_) // allocator is independently owned. + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens + for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) + nameBufferSize += t->length; + + tokenCount_ = rhs.tokenCount_ + extraToken; + tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); + nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + if (rhs.tokenCount_ > 0) { + std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); + } + if (nameBufferSize > 0) { + std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); + } + + // Adjust pointers to name buffer + std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; + for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) + t->name += diff; + + return nameBuffer_ + nameBufferSize; + } + + //! Check whether a character should be percent-encoded. + /*! + According to RFC 3986 2.3 Unreserved Characters. + \param c The character (code unit) to be tested. + */ + bool NeedPercentEncode(Ch c) const { + return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); + } + + //! Parse a JSON String or its URI fragment representation into tokens. +#ifndef __clang__ // -Wdocumentation + /*! + \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. + \param length Length of the source string. + \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. + */ +#endif + void Parse(const Ch* source, size_t length) { + RAPIDJSON_ASSERT(source != NULL); + RAPIDJSON_ASSERT(nameBuffer_ == 0); + RAPIDJSON_ASSERT(tokens_ == 0); + + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + // Count number of '/' as tokenCount + tokenCount_ = 0; + for (const Ch* s = source; s != source + length; s++) + if (*s == '/') + tokenCount_++; + + Token* token = tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); + Ch* name = nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + size_t i = 0; + + // Detect if it is a URI fragment + bool uriFragment = false; + if (source[i] == '#') { + uriFragment = true; + i++; + } + + if (i != length && source[i] != '/') { + parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; + goto error; + } + + while (i < length) { + RAPIDJSON_ASSERT(source[i] == '/'); + i++; // consumes '/' + + token->name = name; + bool isNumber = true; + + while (i < length && source[i] != '/') { + Ch c = source[i]; + if (uriFragment) { + // Decoding percent-encoding for URI fragment + if (c == '%') { + PercentDecodeStream is(&source[i], source + length); + GenericInsituStringStream os(name); + Ch* begin = os.PutBegin(); + if (!Transcoder, EncodingType>().Validate(is, os) || !is.IsValid()) { + parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; + goto error; + } + size_t len = os.PutEnd(begin); + i += is.Tell() - 1; + if (len == 1) + c = *name; + else { + name += len; + isNumber = false; + i++; + continue; + } + } + else if (NeedPercentEncode(c)) { + parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; + goto error; + } + } + + i++; + + // Escaping "~0" -> '~', "~1" -> '/' + if (c == '~') { + if (i < length) { + c = source[i]; + if (c == '0') c = '~'; + else if (c == '1') c = '/'; + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + i++; + } + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + } + + // First check for index: all of characters are digit + if (c < '0' || c > '9') + isNumber = false; + + *name++ = c; + } + token->length = static_cast(name - token->name); + if (token->length == 0) + isNumber = false; + *name++ = '\0'; // Null terminator + + // Second check for index: more than one digit cannot have leading zero + if (isNumber && token->length > 1 && token->name[0] == '0') + isNumber = false; + + // String to SizeType conversion + SizeType n = 0; + if (isNumber) { + for (size_t j = 0; j < token->length; j++) { + SizeType m = n * 10 + static_cast(token->name[j] - '0'); + if (m < n) { // overflow detection + isNumber = false; + break; + } + n = m; + } + } + + token->index = isNumber ? n : kPointerInvalidIndex; + token++; + } + + RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer + parseErrorCode_ = kPointerParseErrorNone; + return; + + error: + Allocator::Free(tokens_); + nameBuffer_ = 0; + tokens_ = 0; + tokenCount_ = 0; + parseErrorOffset_ = i; + return; + } + + //! Stringify to string or URI fragment representation. + /*! + \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. + \tparam OutputStream type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + RAPIDJSON_ASSERT(IsValid()); + + if (uriFragment) + os.Put('#'); + + for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + os.Put('/'); + for (size_t j = 0; j < t->length; j++) { + Ch c = t->name[j]; + if (c == '~') { + os.Put('~'); + os.Put('0'); + } + else if (c == '/') { + os.Put('~'); + os.Put('1'); + } + else if (uriFragment && NeedPercentEncode(c)) { + // Transcode to UTF8 sequence + GenericStringStream source(&t->name[j]); + PercentEncodeStream target(os); + if (!Transcoder >().Validate(source, target)) + return false; + j += source.Tell() - 1; + } + else + os.Put(c); + } + } + return true; + } + + //! A helper stream for decoding a percent-encoded sequence into code unit. + /*! + This stream decodes %XY triplet into code unit (0-255). + If it encounters invalid characters, it sets output code unit as 0 and + mark invalid, and to be checked by IsValid(). + */ + class PercentDecodeStream { + public: + typedef typename ValueType::Ch Ch; + + //! Constructor + /*! + \param source Start of the stream + \param end Past-the-end of the stream. + */ + PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} + + Ch Take() { + if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet + valid_ = false; + return 0; + } + src_++; + Ch c = 0; + for (int j = 0; j < 2; j++) { + c = static_cast(c << 4); + Ch h = *src_; + if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); + else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); + else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); + else { + valid_ = false; + return 0; + } + src_++; + } + return c; + } + + size_t Tell() const { return static_cast(src_ - head_); } + bool IsValid() const { return valid_; } + + private: + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. + const Ch* end_; //!< Past-the-end position. + bool valid_; //!< Whether the parsing is valid. + }; + + //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. + template + class PercentEncodeStream { + public: + PercentEncodeStream(OutputStream& os) : os_(os) {} + void Put(char c) { // UTF-8 must be byte + unsigned char u = static_cast(c); + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + os_.Put('%'); + os_.Put(static_cast(hexDigits[u >> 4])); + os_.Put(static_cast(hexDigits[u & 15])); + } + private: + OutputStream& os_; + }; + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Pointer. + Ch* nameBuffer_; //!< A buffer containing all names in tokens. + Token* tokens_; //!< A list of tokens. + size_t tokenCount_; //!< Number of tokens in tokens_. + size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. + PointerParseErrorCode parseErrorCode_; //!< Parsing error code. +}; + +//! GenericPointer for Value (UTF-8, default allocator). +typedef GenericPointer Pointer; + +//!@name Helper functions for GenericPointer +//@{ + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer& pointer, typename T::AllocatorType& a) { + return pointer.Create(root, a); +} + +template +typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Create(root, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer& pointer) { + return pointer.Create(document); +} + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Create(document); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType* GetValueByPointer(T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, T2 defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const std::basic_string& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, T2 defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const std::basic_string& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const GenericPointer& pointer, T2 value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* value) { + return pointer.Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const std::basic_string& value) { + return pointer.Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const GenericPointer& pointer, T2 value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string& value) { + return GenericPointer(source, N - 1).Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Swap(root, value, a); +} + +template +typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Swap(root, value, a); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Swap(document, value); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Swap(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +bool EraseValueByPointer(T& root, const GenericPointer& pointer) { + return pointer.Erase(root); +} + +template +bool EraseValueByPointer(T& root, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Erase(root); +} + +//@} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_POINTER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/prettywriter.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/prettywriter.h new file mode 100644 index 000000000..cea596ef5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/prettywriter.h @@ -0,0 +1,277 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Combination of PrettyWriter format flags. +/*! \see PrettyWriter::SetFormatOptions + */ +enum PrettyFormatOptions { + kFormatDefault = 0, //!< Default pretty formatting. + kFormatSingleLineArray = 1 //!< Format arrays on a single line. +}; + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of output os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class PrettyWriter : public Writer { +public: + typedef Writer Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + + + explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + PrettyWriter(PrettyWriter&& rhs) : + Base(std::forward(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {} +#endif + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + //! Set pretty writer formatting options. + /*! \param options Formatting options. + */ + PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { + formatOptions_ = options; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + PrettyPrefix(kNumberType); + return Base::EndValue(Base::WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + PrettyPrefix(kStringType); + return Base::EndValue(Base::WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); // currently inside an Array, not Object + RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value + + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::EndValue(Base::WriteEndObject()); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::EndValue(Base::WriteEndArray()); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. + */ + bool RawValue(const Ch* json, size_t length, Type type) { + RAPIDJSON_ASSERT(json != 0); + PrettyPrefix(type); + return Base::EndValue(Base::WriteRawValue(json, length)); + } + +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + if (formatOptions_ & kFormatSingleLineArray) + Base::os_->Put(' '); + } + + if (!(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, static_cast(indentChar_), count); + } + + Ch indentChar_; + unsigned indentCharCount_; + PrettyFormatOptions formatOptions_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/rapidjson.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/rapidjson.h new file mode 100644 index 000000000..89de83861 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/rapidjson.h @@ -0,0 +1,741 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overridden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include // malloc(), realloc(), free(), size_t +#include // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_VERSION_STRING +// +// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. +// + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x + +// token concatenation +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y +//!@endcond + +/*! \def RAPIDJSON_MAJOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Major version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_MINOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Minor version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_PATCH_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Patch version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_VERSION_STRING + \ingroup RAPIDJSON_CONFIG + \brief Version of RapidJSON in ".." string format. +*/ +#define RAPIDJSON_MAJOR_VERSION 1 +#define RAPIDJSON_MINOR_VERSION 1 +#define RAPIDJSON_PATCH_VERSION 0 +#define RAPIDJSON_VERSION_STRING \ + RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NAMESPACE_(BEGIN|END) +/*! \def RAPIDJSON_NAMESPACE + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace + + In order to avoid symbol clashes and/or "One Definition Rule" errors + between multiple inclusions of (different versions of) RapidJSON in + a single binary, users can customize the name of the main RapidJSON + namespace. + + In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE + to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple + levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref + RAPIDJSON_NAMESPACE_END need to be defined as well: + + \code + // in some .cpp file + #define RAPIDJSON_NAMESPACE my::rapidjson + #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { + #define RAPIDJSON_NAMESPACE_END } } + #include "rapidjson/..." + \endcode + + \see rapidjson + */ +/*! \def RAPIDJSON_NAMESPACE_BEGIN + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (opening expression) + \see RAPIDJSON_NAMESPACE +*/ +/*! \def RAPIDJSON_NAMESPACE_END + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (closing expression) + \see RAPIDJSON_NAMESPACE +*/ +#ifndef RAPIDJSON_NAMESPACE +#define RAPIDJSON_NAMESPACE rapidjson +#endif +#ifndef RAPIDJSON_NAMESPACE_BEGIN +#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { +#endif +#ifndef RAPIDJSON_NAMESPACE_END +#define RAPIDJSON_NAMESPACE_END } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// __cplusplus macro + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#if defined(_MSC_VER) +#define RAPIDJSON_CPLUSPLUS _MSVC_LANG +#else +#define RAPIDJSON_CPLUSPLUS __cplusplus +#endif + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#endif // !defined(RAPIDJSON_HAS_STDSTRING) + +#if RAPIDJSON_HAS_STDSTRING +#include +#endif // RAPIDJSON_HAS_STDSTRING + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_USE_MEMBERSMAP + +/*! \def RAPIDJSON_USE_MEMBERSMAP + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for object members handling in a \c std::multimap + + By defining this preprocessor symbol to \c 1, \ref rapidjson::GenericValue object + members are stored in a \c std::multimap for faster lookup and deletion times, a + trade off with a slightly slower insertion time and a small object allocat(or)ed + memory overhead. + + \hideinitializer +*/ +#ifndef RAPIDJSON_USE_MEMBERSMAP +#define RAPIDJSON_USE_MEMBERSMAP 0 // not by default +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include +#include +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. The default is 8 bytes. + User can customize by defining the RAPIDJSON_ALIGN function macro. +*/ +#ifndef RAPIDJSON_ALIGN +#define RAPIDJSON_ALIGN(x) (((x) + static_cast(7u)) & ~static_cast(7u)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_48BITPOINTER_OPTIMIZATION + +//! Use only lower 48-bit address for some pointers. +/*! + \ingroup RAPIDJSON_CONFIG + + This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. + The higher 16-bit can be used for storing other data. + \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. +*/ +#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 +#else +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 +#endif +#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION + +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 +#if RAPIDJSON_64BIT != 1 +#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 +#endif +#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast((reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast(reinterpret_cast(x)))) +#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast(reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) +#else +#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) +#define RAPIDJSON_GETPOINTER(type, p) (p) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2/Neon optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel + or ARM compatible processors. + + To enable these optimizations, three different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + // Enable ARM Neon optimization. + #define RAPIDJSON_NEON + \endcode + + \c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +RAPIDJSON_NAMESPACE_BEGIN +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +RAPIDJSON_NAMESPACE_END +#endif + +// always import std::size_t to rapidjson namespace +RAPIDJSON_NAMESPACE_BEGIN +using std::size_t; +RAPIDJSON_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Prefer C++11 static_assert, if available +#ifndef RAPIDJSON_STATIC_ASSERT +#if RAPIDJSON_CPLUSPLUS >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 ) +#define RAPIDJSON_STATIC_ASSERT(x) \ + static_assert(x, RAPIDJSON_STRINGIFY(x)) +#endif // C++11 +#endif // RAPIDJSON_STATIC_ASSERT + +// Adopt C++03 implementation from boost +#ifndef RAPIDJSON_STATIC_ASSERT +#ifndef __clang__ +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#endif +RAPIDJSON_NAMESPACE_BEGIN +template struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; +template struct StaticAssertTest {}; +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +#ifndef __clang__ +//!@endcond +#endif + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) \ + typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ + sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE)> \ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif // RAPIDJSON_STATIC_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY + +//! Compiler branching hint for expression with high probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression likely to be true. +*/ +#ifndef RAPIDJSON_LIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) +#else +#define RAPIDJSON_LIKELY(x) (x) +#endif +#endif + +//! Compiler branching hint for expression with low probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression unlikely to be true. +*/ +#ifndef RAPIDJSON_UNLIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define RAPIDJSON_UNLIKELY(x) (x) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +#if defined(__has_builtin) +#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x) +#else +#define RAPIDJSON_HAS_BUILTIN(x) 0 +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11 +#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L) +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if RAPIDJSON_HAS_CXX11 +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#elif defined(__clang__) +#if __has_feature(cxx_rvalue_references) && \ + (defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if RAPIDJSON_HAS_CXX11 +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#elif defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#ifndef RAPIDJSON_NOEXCEPT +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT throw() +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT +#endif + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#if (defined(_MSC_VER) && _MSC_VER >= 1700) +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1 +#else +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1700) || \ + (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 +#else +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR + +/////////////////////////////////////////////////////////////////////////////// +// C++17 features + +#ifndef RAPIDJSON_HAS_CXX17 +#define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L) +#endif + +#if RAPIDJSON_HAS_CXX17 +# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]] +#elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(clang::fallthrough) +# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[clang::fallthrough]] +# elif __has_cpp_attribute(fallthrough) +# define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough)) +# else +# define RAPIDJSON_DELIBERATE_FALLTHROUGH +# endif +#else +# define RAPIDJSON_DELIBERATE_FALLTHROUGH +#endif + +//!@endcond + +//! Assertion (in non-throwing contexts). + /*! \ingroup RAPIDJSON_CONFIG + Some functions provide a \c noexcept guarantee, if the compiler supports it. + In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to + throw an exception. This macro adds a separate customization point for + such cases. + + Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is + supported, and to \ref RAPIDJSON_ASSERT otherwise. + */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NOEXCEPT_ASSERT + +#ifndef RAPIDJSON_NOEXCEPT_ASSERT +#ifdef RAPIDJSON_ASSERT_THROWS +#include +#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x) +#else +#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x) +#endif // RAPIDJSON_ASSERT_THROWS +#endif // RAPIDJSON_NOEXCEPT_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// malloc/realloc/free + +#ifndef RAPIDJSON_MALLOC +///! customization point for global \c malloc +#define RAPIDJSON_MALLOC(size) std::malloc(size) +#endif +#ifndef RAPIDJSON_REALLOC +///! customization point for global \c realloc +#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size) +#endif +#ifndef RAPIDJSON_FREE +///! customization point for global \c free +#define RAPIDJSON_FREE(ptr) std::free(ptr) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// new/delete + +#ifndef RAPIDJSON_NEW +///! customization point for global \c new +#define RAPIDJSON_NEW(TypeName) new TypeName +#endif +#ifndef RAPIDJSON_DELETE +///! customization point for global \c delete +#define RAPIDJSON_DELETE(x) delete x +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Type + +/*! \namespace rapidjson + \brief main RapidJSON namespace + \see RAPIDJSON_NAMESPACE +*/ +RAPIDJSON_NAMESPACE_BEGIN + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/reader.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/reader.h new file mode 100644 index 000000000..86c1f28ea --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/reader.h @@ -0,0 +1,2246 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "allocators.h" +#include "stream.h" +#include "encodedstream.h" +#include "internal/clzll.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strtod.h" +#include + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#elif defined(RAPIDJSON_NEON) +#include +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(old-style-cast) +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kParseDefaultFlags definition. + + User can define this as any \c ParseFlag combinations. +*/ +#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS +#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags +#endif + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseNoFlags = 0, //!< No flags are set. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. + kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). + kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. + kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. + kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. + kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. + kParseEscapedApostropheFlag = 512, //!< Allow escaped apostrophe in strings. + kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType length, bool copy); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + typename InputStream::Ch c; + while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') + s.Take(); +} + +inline const char* SkipWhitespace(const char* p, const char* end) { + while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + return p; +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY); + if (r != 16) // some of characters is non-whitespace + return p + r; + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The middle of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY); + if (r != 16) // some of characters is non-whitespace + return p + r; + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_NEON) + +//! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + const uint8x16_t w0 = vmovq_n_u8(' '); + const uint8x16_t w1 = vmovq_n_u8('\n'); + const uint8x16_t w2 = vmovq_n_u8('\r'); + const uint8x16_t w3 = vmovq_n_u8('\t'); + + for (;; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, w0); + x = vorrq_u8(x, vceqq_u8(s, w1)); + x = vorrq_u8(x, vceqq_u8(s, w2)); + x = vorrq_u8(x, vceqq_u8(s, w3)); + + x = vmvnq_u8(x); // Negate + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + return p + 8 + (lz >> 3); + } + } else { + uint32_t lz = internal::clzll(low); + return p + (lz >> 3); + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + const uint8x16_t w0 = vmovq_n_u8(' '); + const uint8x16_t w1 = vmovq_n_u8('\n'); + const uint8x16_t w2 = vmovq_n_u8('\r'); + const uint8x16_t w3 = vmovq_n_u8('\t'); + + for (; p <= end - 16; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, w0); + x = vorrq_u8(x, vceqq_u8(s, w1)); + x = vorrq_u8(x, vceqq_u8(s, w2)); + x = vorrq_u8(x, vceqq_u8(s, w3)); + + x = vmvnq_u8(x); // Negate + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + return p + 8 + (lz >> 3); + } + } else { + uint32_t lz = internal::clzll(low); + return p + (lz >> 3); + } + } + + return SkipWhitespace(p, end); +} + +#endif // RAPIDJSON_NEON + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} + +template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& is) { + is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : + stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse(is, handler); + } + + //! Initialize JSON text token-by-token parsing + /*! + */ + void IterativeParseInit() { + parseResult_.Clear(); + state_ = IterativeParsingStartState; + } + + //! Parse one token from JSON text + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + bool IterativeParseNext(InputStream& is, Handler& handler) { + while (RAPIDJSON_LIKELY(is.Peek() != '\0')) { + SkipWhitespaceAndComments(is); + + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state_, t); + IterativeParsingState d = Transit(state_, t, n, is, handler); + + // If we've finished or hit an error... + if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) { + // Report errors. + if (d == IterativeParsingErrorState) { + HandleError(state_, is); + return false; + } + + // Transition to the finish state. + RAPIDJSON_ASSERT(d == IterativeParsingFinishState); + state_ = d; + + // If StopWhenDone is not set... + if (!(parseFlags & kParseStopWhenDoneFlag)) { + // ... and extra non-whitespace data is found... + SkipWhitespaceAndComments(is); + if (is.Peek() != '\0') { + // ... this is considered an error. + HandleError(state_, is); + return false; + } + } + + // Success! We are done! + return true; + } + + // Transition to the new state. + state_ = d; + + // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now. + if (!IsIterativeParsingDelimiterState(n)) + return true; + } + + // We reached the end of file. + stack_.Clear(); + + if (state_ != IterativeParsingFinishState) { + HandleError(state_, is); + return false; + } + + return true; + } + + //! Check if token-by-token parsing JSON text is complete + /*! \return Whether the JSON has been fully decoded. + */ + RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const { + return IsIterativeParsingCompleteState(state_); + } + + //! Whether a parse error has occurred in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + template + void SkipWhitespaceAndComments(InputStream& is) { + SkipWhitespace(is); + + if (parseFlags & kParseCommentsFlag) { + while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { + if (Consume(is, '*')) { + while (true) { + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + else if (Consume(is, '*')) { + if (Consume(is, '/')) + break; + } + else + is.Take(); + } + } + else if (RAPIDJSON_LIKELY(Consume(is, '/'))) + while (is.Peek() != '\0' && is.Take() != '\n') {} + else + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + + SkipWhitespace(is); + } + } + } + + // Parse object: { string : value, ... } + template + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, '}')) { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++memberCount; + + switch (is.Peek()) { + case ',': + is.Take(); + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + break; + case '}': + is.Take(); + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy + } + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == '}') { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + // Parse array: [ value, ... ] + template + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ',')) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + } + else if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == ']') { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + template + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { + if (RAPIDJSON_UNLIKELY(!handler.Null())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { + if (RAPIDJSON_LIKELY(is.Peek() == expect)) { + is.Take(); + return true; + } + else + return false; + } + + // Helper function to parse four hexadecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(InputStream& is, size_t escapeOffset) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Peek(); + codepoint <<= 4; + codepoint += static_cast(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + is.Take(); + } + return codepoint; + } + + template + class StackStream { + public: + typedef CharType Ch; + + StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push() = c; + ++length_; + } + + RAPIDJSON_FORCEINLINE void* Push(SizeType count) { + length_ += count; + return stack_.template Push(count); + } + + size_t Length() const { return length_; } + + Ch* Pop() { + return stack_.template Pop(length_); + } + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + + internal::Stack& stack_; + SizeType length_; + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + RAPIDJSON_ASSERT(s.Peek() == '\"'); + s.Take(); // Skip '\"' + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream stackStream(stack_); + ParseStringToStream(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + SizeType length = static_cast(stackStream.Length()) - 1; + const typename TargetEncoding::Ch* const str = stackStream.Pop(); + success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); + } + if (RAPIDJSON_UNLIKELY(!success)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + for (;;) { + // Scan and copy string before "\\\"" or < 0x20. This is an optional optimization. + if (!(parseFlags & kParseValidateEncodingFlag)) + ScanCopyUnescapedString(is, os); + + Ch c = is.Peek(); + if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape + size_t escapeOffset = is.Tell(); // For invalid escaping, report the initial '\\' as error offset + is.Take(); + Ch e = is.Peek(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast(e)])) { + is.Take(); + os.Put(static_cast(escape[static_cast(e)])); + } + else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe + is.Take(); + os.Put('\''); + } + else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode + is.Take(); + unsigned codepoint = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) { + // high surrogate, check if followed by valid low surrogate + if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) { + // Handle UTF-16 surrogate pair + if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + unsigned codepoint2 = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + // single low surrogate + else + { + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + } + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); + } + else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (RAPIDJSON_UNLIKELY(static_cast(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell()); + } + else { + size_t offset = is.Tell(); + if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : + !Transcoder::Transcode(is, os)))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); + } + } + } + + template + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { + // Do nothing for generic version + } + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType length; + #ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; + #else + length = static_cast(__builtin_ffs(r) - 1); + #endif + if (length != 0) { + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + } + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16, q += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + for (const char* pend = p + length; p != pend; ) + *q++ = *p++; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + p += length; + break; + } + } + + is.src_ = is.dst_ = p; + } +#elif defined(RAPIDJSON_NEON) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (;; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + SizeType length = 0; + bool escaped = false; + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + length = 8 + (lz >> 3); + escaped = true; + } + } else { + uint32_t lz = internal::clzll(low); + length = lz >> 3; + escaped = true; + } + if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped + if (length != 0) { + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + } + break; + } + vst1q_u8(reinterpret_cast(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (;; p += 16, q += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + SizeType length = 0; + bool escaped = false; + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + length = 8 + (lz >> 3); + escaped = true; + } + } else { + uint32_t lz = internal::clzll(low); + length = lz >> 3; + escaped = true; + } + if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped + for (const char* pend = p + length; p != pend; ) { + *q++ = *p++; + } + break; + } + vst1q_u8(reinterpret_cast(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (;; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + p += 8 + (lz >> 3); + break; + } + } else { + uint32_t lz = internal::clzll(low); + p += lz >> 3; + break; + } + } + + is.src_ = is.dst_ = p; + } +#endif // RAPIDJSON_NEON + + template + class NumberStream; + + template + class NumberStream { + public: + typedef typename InputStream::Ch Ch; + + NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } + + RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } + RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } + RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } + RAPIDJSON_FORCEINLINE void Push(char) {} + + size_t Tell() { return is.Tell(); } + size_t Length() { return 0; } + const StackCharacter* Pop() { return 0; } + + protected: + NumberStream& operator=(const NumberStream&); + + InputStream& is; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {} + + RAPIDJSON_FORCEINLINE Ch TakePush() { + stackStream.Put(static_cast(Base::is.Peek())); + return Base::is.Take(); + } + + RAPIDJSON_FORCEINLINE void Push(StackCharacter c) { + stackStream.Put(c); + } + + size_t Length() { return stackStream.Length(); } + + const StackCharacter* Pop() { + stackStream.Put('\0'); + return stackStream.Pop(); + } + + private: + StackStream stackStream; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {} + + RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } + }; + + template + void ParseNumber(InputStream& is, Handler& handler) { + typedef typename internal::SelectIf, typename TargetEncoding::Ch, char>::Type NumberCharacter; + + internal::StreamLocalCopy copy(is); + NumberStream s(*this, copy.s); + + size_t startOffset = s.Tell(); + double d = 0.0; + bool useNanOrInf = false; + + // Parse minus + bool minus = Consume(s, '-'); + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + int significandDigit = 0; + if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { + i = 0; + s.TakePush(); + } + else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { + i = static_cast(s.TakePush() - '0'); + + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 + if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 + if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + // Parse NaN or Infinity here + else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { + if (Consume(s, 'N')) { + if (Consume(s, 'a') && Consume(s, 'N')) { + d = std::numeric_limits::quiet_NaN(); + useNanOrInf = true; + } + } + else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) { + if (Consume(s, 'n') && Consume(s, 'f')) { + d = (minus ? -std::numeric_limits::infinity() : std::numeric_limits::infinity()); + useNanOrInf = true; + + if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') + && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) { + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + } + } + + if (RAPIDJSON_UNLIKELY(!useNanOrInf)) { + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + bool useDouble = false; + if (use64bit) { + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + + // Force double for big integer + if (useDouble) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + d = d * 10 + (s.TakePush() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + size_t decimalPosition; + if (Consume(s, '.')) { + decimalPosition = s.Length(); + + if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + + if (!useDouble) { +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!use64bit) + i64 = i; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path + break; + else { + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + --expFrac; + if (i64 != 0) + significandDigit++; + } + } + + d = static_cast(i64); +#else + // Use double to store significand in 32-bit architecture + d = static_cast(use64bit ? i64 : i); +#endif + useDouble = true; + } + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (significandDigit < 17) { + d = d * 10.0 + (s.TakePush() - '0'); + --expFrac; + if (RAPIDJSON_LIKELY(d > 0.0)) + significandDigit++; + } + else + s.TakePush(); + } + } + else + decimalPosition = s.Length(); // decimal position at the end of integer. + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (Consume(s, 'e') || Consume(s, 'E')) { + if (!useDouble) { + d = static_cast(use64bit ? i64 : i); + useDouble = true; + } + + bool expMinus = false; + if (Consume(s, '+')) + ; + else if (Consume(s, '-')) + expMinus = true; + + if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = static_cast(s.Take() - '0'); + if (expMinus) { + // (exp + expFrac) must not underflow int => we're detecting when -exp gets + // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into + // underflow territory): + // + // -(exp * 10 + 9) + expFrac >= INT_MIN + // <=> exp <= (expFrac - INT_MIN - 9) / 10 + RAPIDJSON_ASSERT(expFrac <= 0); + int maxExp = (expFrac + 2147483639) / 10; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) { + while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + + if (parseFlags & kParseNumbersAsStringsFlag) { + if (parseFlags & kParseInsituFlag) { + s.Pop(); // Pop stack no matter if it will be used or not. + typename InputStream::Ch* head = is.PutBegin(); + const size_t length = s.Tell() - startOffset; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + // unable to insert the \0 character here, it will erase the comma after this number + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + cont = handler.RawNumber(str, SizeType(length), false); + } + else { + SizeType numCharsToCopy = static_cast(s.Length()); + GenericStringStream > srcStream(s.Pop()); + StackStream dstStream(stack_); + while (numCharsToCopy--) { + Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); + } + dstStream.Put('\0'); + const typename TargetEncoding::Ch* str = dstStream.Pop(); + const SizeType length = static_cast(dstStream.Length()) - 1; + cont = handler.RawNumber(str, SizeType(length), true); + } + } + else { + size_t length = s.Length(); + const NumberCharacter* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + + if (useDouble) { + int p = exp + expFrac; + if (parseFlags & kParseFullPrecisionFlag) + d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); + else + d = internal::StrtodNormalPrecision(d, p); + + // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal + if (d > (std::numeric_limits::max)()) { + // Overflow + // TODO: internal::StrtodX should report overflow (or underflow) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + + cont = handler.Double(minus ? -d : d); + } + else if (useNanOrInf) { + cont = handler.Double(d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(static_cast(~i64 + 1)); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(static_cast(~i + 1)); + else + cont = handler.Uint(i); + } + } + } + if (RAPIDJSON_UNLIKELY(!cont)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); + } + + // Parse any JSON value + template + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull (is, handler); break; + case 't': ParseTrue (is, handler); break; + case 'f': ParseFalse (is, handler); break; + case '"': ParseString(is, handler); break; + case '{': ParseObject(is, handler); break; + case '[': ParseArray (is, handler); break; + default : + ParseNumber(is, handler); + break; + + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingFinishState = 0, // sink states at top + IterativeParsingErrorState, // sink states at top + IterativeParsingStartState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingMemberValueState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState, + + // Delimiter states (at bottom) + IterativeParsingElementDelimiterState, + IterativeParsingMemberDelimiterState, + IterativeParsingKeyValueDelimiterState, + + cIterativeParsingStateCount + }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || static_cast(c) < 256) + return static_cast(tokenMap[static_cast(c)]); + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + }; // End of G + + return static_cast(G[state][token]); + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + (void)token; + + switch (dst) { + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push(1) = n; + // Initialize and push the member/element count. + *stack_.template Push(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + RAPIDJSON_ASSERT(token == ColonToken); + is.Take(); + return dst; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top() = *stack_.template Top() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); + return IterativeParsingErrorState; + } + // Get member count. + SizeType c = *stack_.template Pop(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); + return IterativeParsingErrorState; + } + // Get element count. + SizeType c = *stack_.template Pop(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + default: + // This branch is for IterativeParsingValueState actually. + // Use `default:` rather than + // `case IterativeParsingValueState:` is for code coverage. + + // The IterativeParsingStartState is not enumerated in this switch-case. + // It is impossible for that case. And it can be caught by following assertion. + + // The IterativeParsingFinishState is not enumerated in this switch-case either. + // It is a "derivative" state which cannot triggered from Predict() directly. + // Therefore it cannot happen here. And it can be caught by following assertion. + RAPIDJSON_ASSERT(dst == IterativeParsingValueState); + + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + } + } + + template + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; + case IterativeParsingKeyValueDelimiterState: + case IterativeParsingArrayInitialState: + case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; + default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; + } + } + + RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const { + return s >= IterativeParsingElementDelimiterState; + } + + RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const { + return s <= IterativeParsingErrorState; + } + + template + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; + IterativeParsingState state_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader, UTF8<> > Reader; + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/schema.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/schema.h new file mode 100644 index 000000000..453e43e30 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/schema.h @@ -0,0 +1,3262 @@ +// Tencent is pleased to support the open source community by making RapidJSON available-> +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License-> You may obtain a copy of the License at +// +// http://opensource->org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied-> See the License for the +// specific language governing permissions and limitations under the License-> + +#ifndef RAPIDJSON_SCHEMA_H_ +#define RAPIDJSON_SCHEMA_H_ + +#include "document.h" +#include "pointer.h" +#include "stringbuffer.h" +#include "error/en.h" +#include "uri.h" +#include // abs, floor + +#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 +#endif + +#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) +#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX +#include "internal/regex.h" +#elif RAPIDJSON_SCHEMA_USE_STDREGEX +#include +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX +#define RAPIDJSON_SCHEMA_HAS_REGEX 1 +#else +#define RAPIDJSON_SCHEMA_HAS_REGEX 0 +#endif + +#ifndef RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_VERBOSE 0 +#endif + +RAPIDJSON_DIAG_PUSH + +#if defined(__GNUC__) +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(weak-vtables) +RAPIDJSON_DIAG_OFF(exit-time-destructors) +RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) +RAPIDJSON_DIAG_OFF(variadic-macros) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Verbose Utilities + +#if RAPIDJSON_SCHEMA_VERBOSE + +namespace internal { + +inline void PrintInvalidKeywordData(const char* keyword) { + printf(" Fail keyword: '%s'\n", keyword); +} + +inline void PrintInvalidKeywordData(const wchar_t* keyword) { + wprintf(L" Fail keyword: '%ls'\n", keyword); +} + +inline void PrintInvalidDocumentData(const char* document) { + printf(" Fail document: '%s'\n", document); +} + +inline void PrintInvalidDocumentData(const wchar_t* document) { + wprintf(L" Fail document: '%ls'\n", document); +} + +inline void PrintValidatorPointersData(const char* s, const char* d, unsigned depth) { + printf(" Sch: %*s'%s'\n Doc: %*s'%s'\n", depth * 4, " ", s, depth * 4, " ", d); +} + +inline void PrintValidatorPointersData(const wchar_t* s, const wchar_t* d, unsigned depth) { + wprintf(L" Sch: %*ls'%ls'\n Doc: %*ls'%ls'\n", depth * 4, L" ", s, depth * 4, L" ", d); +} + +inline void PrintSchemaIdsData(const char* base, const char* local, const char* resolved) { + printf(" Resolving id: Base: '%s', Local: '%s', Resolved: '%s'\n", base, local, resolved); +} + +inline void PrintSchemaIdsData(const wchar_t* base, const wchar_t* local, const wchar_t* resolved) { + wprintf(L" Resolving id: Base: '%ls', Local: '%ls', Resolved: '%ls'\n", base, local, resolved); +} + +inline void PrintMethodData(const char* method) { + printf("%s\n", method); +} + +inline void PrintMethodData(const char* method, bool b) { + printf("%s, Data: '%s'\n", method, b ? "true" : "false"); +} + +inline void PrintMethodData(const char* method, int64_t i) { + printf("%s, Data: '%" PRId64 "'\n", method, i); +} + +inline void PrintMethodData(const char* method, uint64_t u) { + printf("%s, Data: '%" PRIu64 "'\n", method, u); +} + +inline void PrintMethodData(const char* method, double d) { + printf("%s, Data: '%lf'\n", method, d); +} + +inline void PrintMethodData(const char* method, const char* s) { + printf("%s, Data: '%s'\n", method, s); +} + +inline void PrintMethodData(const char* method, const wchar_t* s) { + wprintf(L"%hs, Data: '%ls'\n", method, s); +} + +inline void PrintMethodData(const char* method, const char* s1, const char* s2) { + printf("%s, Data: '%s', '%s'\n", method, s1, s2); +} + +inline void PrintMethodData(const char* method, const wchar_t* s1, const wchar_t* s2) { + wprintf(L"%hs, Data: '%ls', '%ls'\n", method, s1, s2); +} + +} // namespace internal + +#endif // RAPIDJSON_SCHEMA_VERBOSE + +#ifndef RAPIDJSON_SCHEMA_PRINT +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_PRINT(name, ...) internal::Print##name##Data(__VA_ARGS__) +#else +#define RAPIDJSON_SCHEMA_PRINT(name, ...) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_INVALID_KEYWORD_RETURN + +#define RAPIDJSON_INVALID_KEYWORD_RETURN(code)\ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + context.invalidCode = code;\ + context.invalidKeyword = SchemaType::GetValidateErrorKeyword(code).GetString();\ + RAPIDJSON_SCHEMA_PRINT(InvalidKeyword, context.invalidKeyword);\ + return false;\ +RAPIDJSON_MULTILINEMACRO_END + +/////////////////////////////////////////////////////////////////////////////// +// ValidateFlag + +/*! \def RAPIDJSON_VALIDATE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kValidateDefaultFlags definition. + + User can define this as any \c ValidateFlag combinations. +*/ +#ifndef RAPIDJSON_VALIDATE_DEFAULT_FLAGS +#define RAPIDJSON_VALIDATE_DEFAULT_FLAGS kValidateNoFlags +#endif + +//! Combination of validate flags +/*! \see + */ +enum ValidateFlag { + kValidateNoFlags = 0, //!< No flags are set. + kValidateContinueOnErrorFlag = 1, //!< Don't stop after first validation error. + kValidateReadFlag = 2, //!< Validation is for a read semantic. + kValidateWriteFlag = 4, //!< Validation is for a write semantic. + kValidateDefaultFlags = RAPIDJSON_VALIDATE_DEFAULT_FLAGS //!< Default validate flags. Can be customized by defining RAPIDJSON_VALIDATE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Specification +enum SchemaDraft { + kDraftUnknown = -1, + kDraftNone = 0, + kDraft03 = 3, + kDraftMin = 4, //!< Current minimum supported draft + kDraft04 = 4, + kDraft05 = 5, + kDraftMax = 5, //!< Current maximum supported draft + kDraft06 = 6, + kDraft07 = 7, + kDraft2019_09 = 8, + kDraft2020_12 = 9 +}; + +enum OpenApiVersion { + kVersionUnknown = -1, + kVersionNone = 0, + kVersionMin = 2, //!< Current minimum supported version + kVersion20 = 2, + kVersion30 = 3, + kVersionMax = 3, //!< Current maximum supported version + kVersion31 = 4, +}; + +struct Specification { + Specification(SchemaDraft d) : draft(d), oapi(kVersionNone) {} + Specification(OpenApiVersion o) : oapi(o) { + if (oapi == kVersion20) draft = kDraft04; + else if (oapi == kVersion30) draft = kDraft05; + else if (oapi == kVersion31) draft = kDraft2020_12; + else draft = kDraft04; + } + ~Specification() {} + bool IsSupported() const { + return ((draft >= kDraftMin && draft <= kDraftMax) && ((oapi == kVersionNone) || (oapi >= kVersionMin && oapi <= kVersionMax))); + } + SchemaDraft draft; + OpenApiVersion oapi; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Forward declarations + +template +class GenericSchemaDocument; + +namespace internal { + +template +class Schema; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidator + +class ISchemaValidator { +public: + virtual ~ISchemaValidator() {} + virtual bool IsValid() const = 0; + virtual void SetValidateFlags(unsigned flags) = 0; + virtual unsigned GetValidateFlags() const = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaStateFactory + +template +class ISchemaStateFactory { +public: + virtual ~ISchemaStateFactory() {} + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&, const bool inheritContinueOnErrors) = 0; + virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; + virtual void* CreateHasher() = 0; + virtual uint64_t GetHashCode(void* hasher) = 0; + virtual void DestroyHasher(void* hasher) = 0; + virtual void* MallocState(size_t size) = 0; + virtual void FreeState(void* p) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// IValidationErrorHandler + +template +class IValidationErrorHandler { +public: + typedef typename SchemaType::Ch Ch; + typedef typename SchemaType::SValue SValue; + + virtual ~IValidationErrorHandler() {} + + virtual void NotMultipleOf(int64_t actual, const SValue& expected) = 0; + virtual void NotMultipleOf(uint64_t actual, const SValue& expected) = 0; + virtual void NotMultipleOf(double actual, const SValue& expected) = 0; + virtual void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void AboveMaximum(double actual, const SValue& expected, bool exclusive) = 0; + virtual void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) = 0; + virtual void BelowMinimum(double actual, const SValue& expected, bool exclusive) = 0; + + virtual void TooLong(const Ch* str, SizeType length, SizeType expected) = 0; + virtual void TooShort(const Ch* str, SizeType length, SizeType expected) = 0; + virtual void DoesNotMatch(const Ch* str, SizeType length) = 0; + + virtual void DisallowedItem(SizeType index) = 0; + virtual void TooFewItems(SizeType actualCount, SizeType expectedCount) = 0; + virtual void TooManyItems(SizeType actualCount, SizeType expectedCount) = 0; + virtual void DuplicateItems(SizeType index1, SizeType index2) = 0; + + virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount) = 0; + virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount) = 0; + virtual void StartMissingProperties() = 0; + virtual void AddMissingProperty(const SValue& name) = 0; + virtual bool EndMissingProperties() = 0; + virtual void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void DisallowedProperty(const Ch* name, SizeType length) = 0; + + virtual void StartDependencyErrors() = 0; + virtual void StartMissingDependentProperties() = 0; + virtual void AddMissingDependentProperty(const SValue& targetName) = 0; + virtual void EndMissingDependentProperties(const SValue& sourceName) = 0; + virtual void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) = 0; + virtual bool EndDependencyErrors() = 0; + + virtual void DisallowedValue(const ValidateErrorCode code) = 0; + virtual void StartDisallowedType() = 0; + virtual void AddExpectedType(const typename SchemaType::ValueType& expectedType) = 0; + virtual void EndDisallowedType(const typename SchemaType::ValueType& actualType) = 0; + virtual void NotAllOf(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void NoneOf(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void NotOneOf(ISchemaValidator** subvalidators, SizeType count) = 0; + virtual void MultipleOneOf(SizeType index1, SizeType index2) = 0; + virtual void Disallowed() = 0; + virtual void DisallowedWhenWriting() = 0; + virtual void DisallowedWhenReading() = 0; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Hasher + +// For comparison of compound value +template +class Hasher { +public: + typedef typename Encoding::Ch Ch; + + Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} + + bool Null() { return WriteType(kNullType); } + bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } + bool Int(int i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Double(double d) { + Number n; + if (d < 0) n.u.i = static_cast(d); + else n.u.u = static_cast(d); + n.d = d; + return WriteNumber(n); + } + + bool RawNumber(const Ch* str, SizeType len, bool) { + WriteBuffer(kNumberType, str, len * sizeof(Ch)); + return true; + } + + bool String(const Ch* str, SizeType len, bool) { + WriteBuffer(kStringType, str, len * sizeof(Ch)); + return true; + } + + bool StartObject() { return true; } + bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } + bool EndObject(SizeType memberCount) { + uint64_t h = Hash(0, kObjectType); + uint64_t* kv = stack_.template Pop(memberCount * 2); + for (SizeType i = 0; i < memberCount; i++) + h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive + *stack_.template Push() = h; + return true; + } + + bool StartArray() { return true; } + bool EndArray(SizeType elementCount) { + uint64_t h = Hash(0, kArrayType); + uint64_t* e = stack_.template Pop(elementCount); + for (SizeType i = 0; i < elementCount; i++) + h = Hash(h, e[i]); // Use hash to achieve element order sensitive + *stack_.template Push() = h; + return true; + } + + bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } + + uint64_t GetHashCode() const { + RAPIDJSON_ASSERT(IsValid()); + return *stack_.template Top(); + } + +private: + static const size_t kDefaultSize = 256; + struct Number { + union U { + uint64_t u; + int64_t i; + }u; + double d; + }; + + bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } + + bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } + + bool WriteBuffer(Type type, const void* data, size_t len) { + // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ + uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); + const unsigned char* d = static_cast(data); + for (size_t i = 0; i < len; i++) + h = Hash(h, d[i]); + *stack_.template Push() = h; + return true; + } + + static uint64_t Hash(uint64_t h, uint64_t d) { + static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); + h ^= d; + h *= kPrime; + return h; + } + + Stack stack_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidationContext + +template +struct SchemaValidationContext { + typedef Schema SchemaType; + typedef ISchemaStateFactory SchemaValidatorFactoryType; + typedef IValidationErrorHandler ErrorHandlerType; + typedef typename SchemaType::ValueType ValueType; + typedef typename ValueType::Ch Ch; + + enum PatternValidatorType { + kPatternValidatorOnly, + kPatternValidatorWithProperty, + kPatternValidatorWithAdditionalProperty + }; + + SchemaValidationContext(SchemaValidatorFactoryType& f, ErrorHandlerType& eh, const SchemaType* s, unsigned fl = 0) : + factory(f), + error_handler(eh), + schema(s), + flags(fl), + valueSchema(), + invalidKeyword(), + invalidCode(), + hasher(), + arrayElementHashCodes(), + validators(), + validatorCount(), + patternPropertiesValidators(), + patternPropertiesValidatorCount(), + patternPropertiesSchemas(), + patternPropertiesSchemaCount(), + valuePatternValidatorType(kPatternValidatorOnly), + propertyExist(), + inArray(false), + valueUniqueness(false), + arrayUniqueness(false) + { + } + + ~SchemaValidationContext() { + if (hasher) + factory.DestroyHasher(hasher); + if (validators) { + for (SizeType i = 0; i < validatorCount; i++) { + if (validators[i]) { + factory.DestroySchemaValidator(validators[i]); + } + } + factory.FreeState(validators); + } + if (patternPropertiesValidators) { + for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) { + if (patternPropertiesValidators[i]) { + factory.DestroySchemaValidator(patternPropertiesValidators[i]); + } + } + factory.FreeState(patternPropertiesValidators); + } + if (patternPropertiesSchemas) + factory.FreeState(patternPropertiesSchemas); + if (propertyExist) + factory.FreeState(propertyExist); + } + + SchemaValidatorFactoryType& factory; + ErrorHandlerType& error_handler; + const SchemaType* schema; + unsigned flags; + const SchemaType* valueSchema; + const Ch* invalidKeyword; + ValidateErrorCode invalidCode; + void* hasher; // Only validator access + void* arrayElementHashCodes; // Only validator access this + ISchemaValidator** validators; + SizeType validatorCount; + ISchemaValidator** patternPropertiesValidators; + SizeType patternPropertiesValidatorCount; + const SchemaType** patternPropertiesSchemas; + SizeType patternPropertiesSchemaCount; + PatternValidatorType valuePatternValidatorType; + PatternValidatorType objectPatternValidatorType; + SizeType arrayElementIndex; + bool* propertyExist; + bool inArray; + bool valueUniqueness; + bool arrayUniqueness; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Schema + +template +class Schema { +public: + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef SchemaValidationContext Context; + typedef Schema SchemaType; + typedef GenericValue SValue; + typedef IValidationErrorHandler ErrorHandler; + typedef GenericUri UriType; + friend class GenericSchemaDocument; + + Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator, const UriType& id = UriType()) : + allocator_(allocator), + uri_(schemaDocument->GetURI(), *allocator), + id_(id, allocator), + spec_(schemaDocument->GetSpecification()), + pointer_(p, allocator), + typeless_(schemaDocument->GetTypeless()), + enum_(), + enumCount_(), + not_(), + type_((1 << kTotalSchemaType) - 1), // typeless + validatorCount_(), + notValidatorIndex_(), + properties_(), + additionalPropertiesSchema_(), + patternProperties_(), + patternPropertyCount_(), + propertyCount_(), + minProperties_(), + maxProperties_(SizeType(~0)), + additionalProperties_(true), + hasDependencies_(), + hasRequired_(), + hasSchemaDependencies_(), + additionalItemsSchema_(), + itemsList_(), + itemsTuple_(), + itemsTupleCount_(), + minItems_(), + maxItems_(SizeType(~0)), + additionalItems_(true), + uniqueItems_(false), + pattern_(), + minLength_(0), + maxLength_(~SizeType(0)), + exclusiveMinimum_(false), + exclusiveMaximum_(false), + defaultValueLength_(0), + readOnly_(false), + writeOnly_(false), + nullable_(false) + { + GenericStringBuffer sb; + p.StringifyUriFragment(sb); + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Schema", sb.GetString(), id.GetString()); + + typedef typename ValueType::ConstValueIterator ConstValueIterator; + typedef typename ValueType::ConstMemberIterator ConstMemberIterator; + + // PR #1393 + // Early add this Schema and its $ref(s) in schemaDocument's map to avoid infinite + // recursion (with recursive schemas), since schemaDocument->getSchema() is always + // checked before creating a new one. Don't cache typeless_, though. + if (this != typeless_) { + typedef typename SchemaDocumentType::SchemaEntry SchemaEntry; + SchemaEntry *entry = schemaDocument->schemaMap_.template Push(); + new (entry) SchemaEntry(pointer_, this, true, allocator_); + schemaDocument->AddSchemaRefs(this); + } + + if (!value.IsObject()) + return; + + // If we have an id property, resolve it with the in-scope id + // Not supported for open api 2.0 or 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (const ValueType* v = GetMember(value, GetIdString())) { + if (v->IsString()) { + UriType local(*v, allocator); + id_ = local.Resolve(id_, allocator); + RAPIDJSON_SCHEMA_PRINT(SchemaIds, id.GetString(), v->GetString(), id_.GetString()); + } + } + + if (const ValueType* v = GetMember(value, GetTypeString())) { + type_ = 0; + if (v->IsString()) + AddType(*v); + else if (v->IsArray()) + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) + AddType(*itr); + } + + if (const ValueType* v = GetMember(value, GetEnumString())) { + if (v->IsArray() && v->Size() > 0) { + enum_ = static_cast(allocator_->Malloc(sizeof(uint64_t) * v->Size())); + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { + typedef Hasher > EnumHasherType; + char buffer[256u + 24]; + MemoryPoolAllocator hasherAllocator(buffer, sizeof(buffer)); + EnumHasherType h(&hasherAllocator, 256); + itr->Accept(h); + enum_[enumCount_++] = h.GetHashCode(); + } + } + } + + if (schemaDocument) + AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); + + // AnyOf, OneOf, Not not supported for open api 2.0 + if (schemaDocument && spec_.oapi != kVersion20) { + AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); + AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); + + if (const ValueType* v = GetMember(value, GetNotString())) { + schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document, id_); + notValidatorIndex_ = validatorCount_; + validatorCount_++; + } + } + + // Object + + const ValueType* properties = GetMember(value, GetPropertiesString()); + const ValueType* required = GetMember(value, GetRequiredString()); + const ValueType* dependencies = GetMember(value, GetDependenciesString()); + { + // Gather properties from properties/required/dependencies + SValue allProperties(kArrayType); + + if (properties && properties->IsObject()) + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) + AddUniqueElement(allProperties, itr->name); + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) + AddUniqueElement(allProperties, *itr); + + // Dependencies not supported for open api 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (dependencies && dependencies->IsObject()) + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + AddUniqueElement(allProperties, itr->name); + if (itr->value.IsArray()) + for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) + if (i->IsString()) + AddUniqueElement(allProperties, *i); + } + + if (allProperties.Size() > 0) { + propertyCount_ = allProperties.Size(); + properties_ = static_cast(allocator_->Malloc(sizeof(Property) * propertyCount_)); + for (SizeType i = 0; i < propertyCount_; i++) { + new (&properties_[i]) Property(); + properties_[i].name = allProperties[i]; + properties_[i].schema = typeless_; + } + } + } + + if (properties && properties->IsObject()) { + PointerType q = p.Append(GetPropertiesString(), allocator_); + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { + SizeType index; + if (FindPropertyIndex(itr->name, &index)) + schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document, id_); + } + } + + // PatternProperties not supported for open api 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { + PointerType q = p.Append(GetPatternPropertiesString(), allocator_); + patternProperties_ = static_cast(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); + patternPropertyCount_ = 0; + + for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { + new (&patternProperties_[patternPropertyCount_]) PatternProperty(); + PointerType r = q.Append(itr->name, allocator_); + patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name, schemaDocument, r); + schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, r, itr->value, document, id_); + patternPropertyCount_++; + } + } + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) { + SizeType index; + if (FindPropertyIndex(*itr, &index)) { + properties_[index].required = true; + hasRequired_ = true; + } + } + + // Dependencies not supported for open api 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (dependencies && dependencies->IsObject()) { + PointerType q = p.Append(GetDependenciesString(), allocator_); + hasDependencies_ = true; + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + SizeType sourceIndex; + if (FindPropertyIndex(itr->name, &sourceIndex)) { + if (itr->value.IsArray()) { + properties_[sourceIndex].dependencies = static_cast(allocator_->Malloc(sizeof(bool) * propertyCount_)); + std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); + for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { + SizeType targetIndex; + if (FindPropertyIndex(*targetItr, &targetIndex)) + properties_[sourceIndex].dependencies[targetIndex] = true; + } + } + else if (itr->value.IsObject()) { + hasSchemaDependencies_ = true; + schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document, id_); + properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; + validatorCount_++; + } + } + } + } + + if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { + if (v->IsBool()) + additionalProperties_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document, id_); + } + + AssignIfExist(minProperties_, value, GetMinPropertiesString()); + AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); + + // Array + if (const ValueType* v = GetMember(value, GetItemsString())) { + PointerType q = p.Append(GetItemsString(), allocator_); + if (v->IsObject()) // List validation + schemaDocument->CreateSchema(&itemsList_, q, *v, document, id_); + else if (v->IsArray()) { // Tuple validation + itemsTuple_ = static_cast(allocator_->Malloc(sizeof(const Schema*) * v->Size())); + SizeType index = 0; + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) + schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document, id_); + } + } + + AssignIfExist(minItems_, value, GetMinItemsString()); + AssignIfExist(maxItems_, value, GetMaxItemsString()); + + // AdditionalItems not supported for openapi 2.0 and 3.0 + if (spec_.oapi != kVersion20 && spec_.oapi != kVersion30) + if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { + if (v->IsBool()) + additionalItems_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document, id_); + } + + AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); + + // String + AssignIfExist(minLength_, value, GetMinLengthString()); + AssignIfExist(maxLength_, value, GetMaxLengthString()); + + if (const ValueType* v = GetMember(value, GetPatternString())) + pattern_ = CreatePattern(*v, schemaDocument, p.Append(GetPatternString(), allocator_)); + + // Number + if (const ValueType* v = GetMember(value, GetMinimumString())) + if (v->IsNumber()) + minimum_.CopyFrom(*v, *allocator_); + + if (const ValueType* v = GetMember(value, GetMaximumString())) + if (v->IsNumber()) + maximum_.CopyFrom(*v, *allocator_); + + AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); + AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); + + if (const ValueType* v = GetMember(value, GetMultipleOfString())) + if (v->IsNumber() && v->GetDouble() > 0.0) + multipleOf_.CopyFrom(*v, *allocator_); + + // Default + if (const ValueType* v = GetMember(value, GetDefaultValueString())) + if (v->IsString()) + defaultValueLength_ = v->GetStringLength(); + + // ReadOnly - open api only (until draft 7 supported) + // WriteOnly - open api 3 only (until draft 7 supported) + // Both can't be true + if (spec_.oapi != kVersionNone) + AssignIfExist(readOnly_, value, GetReadOnlyString()); + if (spec_.oapi >= kVersion30) + AssignIfExist(writeOnly_, value, GetWriteOnlyString()); + if (readOnly_ && writeOnly_) + schemaDocument->SchemaError(kSchemaErrorReadOnlyAndWriteOnly, p); + + // Nullable - open api 3 only + // If true add 'null' as allowable type + if (spec_.oapi >= kVersion30) { + AssignIfExist(nullable_, value, GetNullableString()); + if (nullable_) + AddType(GetNullString()); + } + } + + ~Schema() { + AllocatorType::Free(enum_); + if (properties_) { + for (SizeType i = 0; i < propertyCount_; i++) + properties_[i].~Property(); + AllocatorType::Free(properties_); + } + if (patternProperties_) { + for (SizeType i = 0; i < patternPropertyCount_; i++) + patternProperties_[i].~PatternProperty(); + AllocatorType::Free(patternProperties_); + } + AllocatorType::Free(itemsTuple_); +#if RAPIDJSON_SCHEMA_HAS_REGEX + if (pattern_) { + pattern_->~RegexType(); + AllocatorType::Free(pattern_); + } +#endif + } + + const SValue& GetURI() const { + return uri_; + } + + const UriType& GetId() const { + return id_; + } + + const Specification& GetSpecification() const { + return spec_; + } + + const PointerType& GetPointer() const { + return pointer_; + } + + bool BeginValue(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::BeginValue"); + if (context.inArray) { + if (uniqueItems_) + context.valueUniqueness = true; + + if (itemsList_) + context.valueSchema = itemsList_; + else if (itemsTuple_) { + if (context.arrayElementIndex < itemsTupleCount_) + context.valueSchema = itemsTuple_[context.arrayElementIndex]; + else if (additionalItemsSchema_) + context.valueSchema = additionalItemsSchema_; + else if (additionalItems_) + context.valueSchema = typeless_; + else { + context.error_handler.DisallowedItem(context.arrayElementIndex); + // Must set valueSchema for when kValidateContinueOnErrorFlag is set, else reports spurious type error + context.valueSchema = typeless_; + // Must bump arrayElementIndex for when kValidateContinueOnErrorFlag is set + context.arrayElementIndex++; + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAdditionalItems); + } + } + else + context.valueSchema = typeless_; + + context.arrayElementIndex++; + } + return true; + } + + RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::EndValue"); + // Only check pattern properties if we have validators + if (context.patternPropertiesValidatorCount > 0) { + bool otherValid = false; + SizeType count = context.patternPropertiesValidatorCount; + if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) + otherValid = context.patternPropertiesValidators[--count]->IsValid(); + + bool patternValid = true; + for (SizeType i = 0; i < count; i++) + if (!context.patternPropertiesValidators[i]->IsValid()) { + patternValid = false; + break; + } + + if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { + if (!patternValid) { + context.error_handler.PropertyViolations(context.patternPropertiesValidators, count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties); + } + } + else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { + if (!patternValid || !otherValid) { + context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties); + } + } + else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty) + context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties); + } + } + + // For enums only check if we have a hasher + if (enum_ && context.hasher) { + const uint64_t h = context.factory.GetHashCode(context.hasher); + for (SizeType i = 0; i < enumCount_; i++) + if (enum_[i] == h) + goto foundEnum; + context.error_handler.DisallowedValue(kValidateErrorEnum); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorEnum); + foundEnum:; + } + + // Only check allOf etc if we have validators + if (context.validatorCount > 0) { + if (allOf_.schemas) + for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) + if (!context.validators[i]->IsValid()) { + context.error_handler.NotAllOf(&context.validators[allOf_.begin], allOf_.count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAllOf); + } + + if (anyOf_.schemas) { + for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) + if (context.validators[i]->IsValid()) + goto foundAny; + context.error_handler.NoneOf(&context.validators[anyOf_.begin], anyOf_.count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAnyOf); + foundAny:; + } + + if (oneOf_.schemas) { + bool oneValid = false; + SizeType firstMatch = 0; + for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) + if (context.validators[i]->IsValid()) { + if (oneValid) { + context.error_handler.MultipleOneOf(firstMatch, i - oneOf_.begin); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOfMatch); + } else { + oneValid = true; + firstMatch = i - oneOf_.begin; + } + } + if (!oneValid) { + context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOf); + } + } + + if (not_ && context.validators[notValidatorIndex_]->IsValid()) { + context.error_handler.Disallowed(); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorNot); + } + } + + return true; + } + + bool Null(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Null"); + if (!(type_ & (1 << kNullSchemaType))) { + DisallowedType(context, GetNullString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + return CreateParallelValidator(context); + } + + bool Bool(Context& context, bool b) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Bool", b); + if (!CheckBool(context, b)) + return false; + return CreateParallelValidator(context); + } + + bool Int(Context& context, int i) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Int", (int64_t)i); + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint(Context& context, unsigned u) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Uint", (uint64_t)u); + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Int64(Context& context, int64_t i) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Int64", i); + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint64(Context& context, uint64_t u) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Uint64", u); + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Double(Context& context, double d) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Double", d); + if (!(type_ & (1 << kNumberSchemaType))) { + DisallowedType(context, GetNumberString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) + return false; + + if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) + return false; + + if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) + return false; + + return CreateParallelValidator(context); + } + + bool String(Context& context, const Ch* str, SizeType length, bool) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::String", str); + if (!(type_ & (1 << kStringSchemaType))) { + DisallowedType(context, GetStringString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (minLength_ != 0 || maxLength_ != SizeType(~0)) { + SizeType count; + if (internal::CountStringCodePoint(str, length, &count)) { + if (count < minLength_) { + context.error_handler.TooShort(str, length, minLength_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinLength); + } + if (count > maxLength_) { + context.error_handler.TooLong(str, length, maxLength_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxLength); + } + } + } + + if (pattern_ && !IsPatternMatch(pattern_, str, length)) { + context.error_handler.DoesNotMatch(str, length); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPattern); + } + + return CreateParallelValidator(context); + } + + bool StartObject(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::StartObject"); + if (!(type_ & (1 << kObjectSchemaType))) { + DisallowedType(context, GetObjectString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (hasDependencies_ || hasRequired_) { + context.propertyExist = static_cast(context.factory.MallocState(sizeof(bool) * propertyCount_)); + std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); + } + + if (patternProperties_) { // pre-allocate schema array + SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType + context.patternPropertiesSchemas = static_cast(context.factory.MallocState(sizeof(const SchemaType*) * count)); + context.patternPropertiesSchemaCount = 0; + std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); + } + + return CreateParallelValidator(context); + } + + bool Key(Context& context, const Ch* str, SizeType len, bool) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::Key", str); + + if (patternProperties_) { + context.patternPropertiesSchemaCount = 0; + for (SizeType i = 0; i < patternPropertyCount_; i++) + if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; + context.valueSchema = typeless_; + } + } + + SizeType index = 0; + if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; + context.valueSchema = typeless_; + context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; + } + else + context.valueSchema = properties_[index].schema; + + if (context.propertyExist) + context.propertyExist[index] = true; + + return true; + } + + if (additionalPropertiesSchema_) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; + context.valueSchema = typeless_; + context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; + } + else + context.valueSchema = additionalPropertiesSchema_; + return true; + } + else if (additionalProperties_) { + context.valueSchema = typeless_; + return true; + } + + if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties + // Must set valueSchema for when kValidateContinueOnErrorFlag is set, else reports spurious type error + context.valueSchema = typeless_; + context.error_handler.DisallowedProperty(str, len); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAdditionalProperties); + } + + return true; + } + + bool EndObject(Context& context, SizeType memberCount) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::EndObject"); + if (hasRequired_) { + context.error_handler.StartMissingProperties(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].required && !context.propertyExist[index]) + if (properties_[index].schema->defaultValueLength_ == 0 ) + context.error_handler.AddMissingProperty(properties_[index].name); + if (context.error_handler.EndMissingProperties()) + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorRequired); + } + + if (memberCount < minProperties_) { + context.error_handler.TooFewProperties(memberCount, minProperties_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinProperties); + } + + if (memberCount > maxProperties_) { + context.error_handler.TooManyProperties(memberCount, maxProperties_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxProperties); + } + + if (hasDependencies_) { + context.error_handler.StartDependencyErrors(); + for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) { + const Property& source = properties_[sourceIndex]; + if (context.propertyExist[sourceIndex]) { + if (source.dependencies) { + context.error_handler.StartMissingDependentProperties(); + for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) + if (source.dependencies[targetIndex] && !context.propertyExist[targetIndex]) + context.error_handler.AddMissingDependentProperty(properties_[targetIndex].name); + context.error_handler.EndMissingDependentProperties(source.name); + } + else if (source.dependenciesSchema) { + ISchemaValidator* dependenciesValidator = context.validators[source.dependenciesValidatorIndex]; + if (!dependenciesValidator->IsValid()) + context.error_handler.AddDependencySchemaError(source.name, dependenciesValidator); + } + } + } + if (context.error_handler.EndDependencyErrors()) + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorDependencies); + } + + return true; + } + + bool StartArray(Context& context) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::StartArray"); + context.arrayElementIndex = 0; + context.inArray = true; // Ensure we note that we are in an array + + if (!(type_ & (1 << kArraySchemaType))) { + DisallowedType(context, GetArrayString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + return CreateParallelValidator(context); + } + + bool EndArray(Context& context, SizeType elementCount) const { + RAPIDJSON_SCHEMA_PRINT(Method, "Schema::EndArray"); + context.inArray = false; + + if (elementCount < minItems_) { + context.error_handler.TooFewItems(elementCount, minItems_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinItems); + } + + if (elementCount > maxItems_) { + context.error_handler.TooManyItems(elementCount, maxItems_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxItems); + } + + return true; + } + + static const ValueType& GetValidateErrorKeyword(ValidateErrorCode validateErrorCode) { + switch (validateErrorCode) { + case kValidateErrorMultipleOf: return GetMultipleOfString(); + case kValidateErrorMaximum: return GetMaximumString(); + case kValidateErrorExclusiveMaximum: return GetMaximumString(); // Same + case kValidateErrorMinimum: return GetMinimumString(); + case kValidateErrorExclusiveMinimum: return GetMinimumString(); // Same + + case kValidateErrorMaxLength: return GetMaxLengthString(); + case kValidateErrorMinLength: return GetMinLengthString(); + case kValidateErrorPattern: return GetPatternString(); + + case kValidateErrorMaxItems: return GetMaxItemsString(); + case kValidateErrorMinItems: return GetMinItemsString(); + case kValidateErrorUniqueItems: return GetUniqueItemsString(); + case kValidateErrorAdditionalItems: return GetAdditionalItemsString(); + + case kValidateErrorMaxProperties: return GetMaxPropertiesString(); + case kValidateErrorMinProperties: return GetMinPropertiesString(); + case kValidateErrorRequired: return GetRequiredString(); + case kValidateErrorAdditionalProperties: return GetAdditionalPropertiesString(); + case kValidateErrorPatternProperties: return GetPatternPropertiesString(); + case kValidateErrorDependencies: return GetDependenciesString(); + + case kValidateErrorEnum: return GetEnumString(); + case kValidateErrorType: return GetTypeString(); + + case kValidateErrorOneOf: return GetOneOfString(); + case kValidateErrorOneOfMatch: return GetOneOfString(); // Same + case kValidateErrorAllOf: return GetAllOfString(); + case kValidateErrorAnyOf: return GetAnyOfString(); + case kValidateErrorNot: return GetNotString(); + + case kValidateErrorReadOnly: return GetReadOnlyString(); + case kValidateErrorWriteOnly: return GetWriteOnlyString(); + + default: return GetNullString(); + } + } + + + // Generate functions for string literal according to Ch +#define RAPIDJSON_STRING_(name, ...) \ + static const ValueType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const ValueType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1));\ + return v;\ + } + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') + RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') + RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') + RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') + RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') + RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') + RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') + RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') + RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') + RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') + RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') + RAPIDJSON_STRING_(Not, 'n', 'o', 't') + RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') + RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') + RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') + RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') + RAPIDJSON_STRING_(DefaultValue, 'd', 'e', 'f', 'a', 'u', 'l', 't') + RAPIDJSON_STRING_(Schema, '$', 's', 'c', 'h', 'e', 'm', 'a') + RAPIDJSON_STRING_(Ref, '$', 'r', 'e', 'f') + RAPIDJSON_STRING_(Id, 'i', 'd') + RAPIDJSON_STRING_(Swagger, 's', 'w', 'a', 'g', 'g', 'e', 'r') + RAPIDJSON_STRING_(OpenApi, 'o', 'p', 'e', 'n', 'a', 'p', 'i') + RAPIDJSON_STRING_(ReadOnly, 'r', 'e', 'a', 'd', 'O', 'n', 'l', 'y') + RAPIDJSON_STRING_(WriteOnly, 'w', 'r', 'i', 't', 'e', 'O', 'n', 'l', 'y') + RAPIDJSON_STRING_(Nullable, 'n', 'u', 'l', 'l', 'a', 'b', 'l', 'e') + +#undef RAPIDJSON_STRING_ + +private: + enum SchemaValueType { + kNullSchemaType, + kBooleanSchemaType, + kObjectSchemaType, + kArraySchemaType, + kStringSchemaType, + kNumberSchemaType, + kIntegerSchemaType, + kTotalSchemaType + }; + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + typedef internal::GenericRegex RegexType; +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + typedef std::basic_regex RegexType; +#else + typedef char RegexType; +#endif + + struct SchemaArray { + SchemaArray() : schemas(), count() {} + ~SchemaArray() { AllocatorType::Free(schemas); } + const SchemaType** schemas; + SizeType begin; // begin index of context.validators + SizeType count; + }; + + template + void AddUniqueElement(V1& a, const V2& v) { + for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + if (*itr == v) + return; + V1 c(v, *allocator_); + a.PushBack(c, *allocator_); + } + + static const ValueType* GetMember(const ValueType& value, const ValueType& name) { + typename ValueType::ConstMemberIterator itr = value.FindMember(name); + return itr != value.MemberEnd() ? &(itr->value) : 0; + } + + static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsBool()) + out = v->GetBool(); + } + + static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) + out = static_cast(v->GetUint64()); + } + + void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { + if (const ValueType* v = GetMember(value, name)) { + if (v->IsArray() && v->Size() > 0) { + PointerType q = p.Append(name, allocator_); + out.count = v->Size(); + out.schemas = static_cast(allocator_->Malloc(out.count * sizeof(const Schema*))); + memset(out.schemas, 0, sizeof(Schema*)* out.count); + for (SizeType i = 0; i < out.count; i++) + schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document, id_); + out.begin = validatorCount_; + validatorCount_ += out.count; + } + } + } + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + template + RegexType* CreatePattern(const ValueType& value, SchemaDocumentType* sd, const PointerType& p) { + if (value.IsString()) { + RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), allocator_); + if (!r->IsValid()) { + sd->SchemaErrorValue(kSchemaErrorRegexInvalid, p, value.GetString(), value.GetStringLength()); + r->~RegexType(); + AllocatorType::Free(r); + r = 0; + } + return r; + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { + GenericRegexSearch rs(*pattern); + return rs.Search(str); + } +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + template + RegexType* CreatePattern(const ValueType& value, SchemaDocumentType* sd, const PointerType& p) { + if (value.IsString()) { + RegexType *r = static_cast(allocator_->Malloc(sizeof(RegexType))); + try { + return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); + } + catch (const std::regex_error& e) { + sd->SchemaErrorValue(kSchemaErrorRegexInvalid, p, value.GetString(), value.GetStringLength()); + AllocatorType::Free(r); + } + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { + std::match_results r; + return std::regex_search(str, str + length, r, *pattern); + } +#else + template + RegexType* CreatePattern(const ValueType&) { + return 0; + } + + static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } +#endif // RAPIDJSON_SCHEMA_USE_STDREGEX + + void AddType(const ValueType& type) { + if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; + else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; + else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; + else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; + else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; + else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; + else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); + } + + // Creates parallel validators for allOf, anyOf, oneOf, not and schema dependencies, if required. + // Also creates a hasher for enums and array uniqueness, if required. + // Also a useful place to add type-independent error checks. + bool CreateParallelValidator(Context& context) const { + if (enum_ || context.arrayUniqueness) + context.hasher = context.factory.CreateHasher(); + + if (validatorCount_) { + RAPIDJSON_ASSERT(context.validators == 0); + context.validators = static_cast(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); + std::memset(context.validators, 0, sizeof(ISchemaValidator*) * validatorCount_); + context.validatorCount = validatorCount_; + + // Always return after first failure for these sub-validators + if (allOf_.schemas) + CreateSchemaValidators(context, allOf_, false); + + if (anyOf_.schemas) + CreateSchemaValidators(context, anyOf_, false); + + if (oneOf_.schemas) + CreateSchemaValidators(context, oneOf_, false); + + if (not_) + context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_, false); + + if (hasSchemaDependencies_) { + for (SizeType i = 0; i < propertyCount_; i++) + if (properties_[i].dependenciesSchema) + context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema, false); + } + } + + // Add any other type-independent checks here + if (readOnly_ && (context.flags & kValidateWriteFlag)) { + context.error_handler.DisallowedWhenWriting(); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorReadOnly); + } + if (writeOnly_ && (context.flags & kValidateReadFlag)) { + context.error_handler.DisallowedWhenReading(); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorWriteOnly); + } + + return true; + } + + void CreateSchemaValidators(Context& context, const SchemaArray& schemas, const bool inheritContinueOnErrors) const { + for (SizeType i = 0; i < schemas.count; i++) + context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i], inheritContinueOnErrors); + } + + // O(n) + bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { + SizeType len = name.GetStringLength(); + const Ch* str = name.GetString(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].name.GetStringLength() == len && + (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) + { + *outIndex = index; + return true; + } + return false; + } + + bool CheckBool(Context& context, bool) const { + if (!(type_ & (1 << kBooleanSchemaType))) { + DisallowedType(context, GetBooleanString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + return true; + } + + bool CheckInt(Context& context, int64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { + DisallowedType(context, GetIntegerString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (!minimum_.IsNull()) { + if (minimum_.IsInt64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) { + context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); + } + } + else if (minimum_.IsUint64()) { + context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); // i <= max(int64_t) < minimum.GetUint64() + } + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsInt64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) { + context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); + } + } + else if (maximum_.IsUint64()) { } + /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64() + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (static_cast(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) { + context.error_handler.NotMultipleOf(i, multipleOf_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf); + } + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckUint(Context& context, uint64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { + DisallowedType(context, GetIntegerString()); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType); + } + + if (!minimum_.IsNull()) { + if (minimum_.IsUint64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) { + context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); + } + } + else if (minimum_.IsInt64()) + /* do nothing */; // i >= 0 > minimum.Getint64() + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsUint64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) { + context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); + } + } + else if (maximum_.IsInt64()) { + context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); // i >= 0 > maximum_ + } + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (i % multipleOf_.GetUint64() != 0) { + context.error_handler.NotMultipleOf(i, multipleOf_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf); + } + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckDoubleMinimum(Context& context, double d) const { + if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) { + context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); + } + return true; + } + + bool CheckDoubleMaximum(Context& context, double d) const { + if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) { + context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_); + RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); + } + return true; + } + + bool CheckDoubleMultipleOf(Context& context, double d) const { + double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); + double q = std::floor(a / b); + double r = a - q * b; + if (r > 0.0) { + context.error_handler.NotMultipleOf(d, multipleOf_); + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf); + } + return true; + } + + void DisallowedType(Context& context, const ValueType& actualType) const { + ErrorHandler& eh = context.error_handler; + eh.StartDisallowedType(); + + if (type_ & (1 << kNullSchemaType)) eh.AddExpectedType(GetNullString()); + if (type_ & (1 << kBooleanSchemaType)) eh.AddExpectedType(GetBooleanString()); + if (type_ & (1 << kObjectSchemaType)) eh.AddExpectedType(GetObjectString()); + if (type_ & (1 << kArraySchemaType)) eh.AddExpectedType(GetArrayString()); + if (type_ & (1 << kStringSchemaType)) eh.AddExpectedType(GetStringString()); + + if (type_ & (1 << kNumberSchemaType)) eh.AddExpectedType(GetNumberString()); + else if (type_ & (1 << kIntegerSchemaType)) eh.AddExpectedType(GetIntegerString()); + + eh.EndDisallowedType(actualType); + } + + struct Property { + Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} + ~Property() { AllocatorType::Free(dependencies); } + SValue name; + const SchemaType* schema; + const SchemaType* dependenciesSchema; + SizeType dependenciesValidatorIndex; + bool* dependencies; + bool required; + }; + + struct PatternProperty { + PatternProperty() : schema(), pattern() {} + ~PatternProperty() { + if (pattern) { + pattern->~RegexType(); + AllocatorType::Free(pattern); + } + } + const SchemaType* schema; + RegexType* pattern; + }; + + AllocatorType* allocator_; + SValue uri_; + UriType id_; + Specification spec_; + PointerType pointer_; + const SchemaType* typeless_; + uint64_t* enum_; + SizeType enumCount_; + SchemaArray allOf_; + SchemaArray anyOf_; + SchemaArray oneOf_; + const SchemaType* not_; + unsigned type_; // bitmask of kSchemaType + SizeType validatorCount_; + SizeType notValidatorIndex_; + + Property* properties_; + const SchemaType* additionalPropertiesSchema_; + PatternProperty* patternProperties_; + SizeType patternPropertyCount_; + SizeType propertyCount_; + SizeType minProperties_; + SizeType maxProperties_; + bool additionalProperties_; + bool hasDependencies_; + bool hasRequired_; + bool hasSchemaDependencies_; + + const SchemaType* additionalItemsSchema_; + const SchemaType* itemsList_; + const SchemaType** itemsTuple_; + SizeType itemsTupleCount_; + SizeType minItems_; + SizeType maxItems_; + bool additionalItems_; + bool uniqueItems_; + + RegexType* pattern_; + SizeType minLength_; + SizeType maxLength_; + + SValue minimum_; + SValue maximum_; + SValue multipleOf_; + bool exclusiveMinimum_; + bool exclusiveMaximum_; + + SizeType defaultValueLength_; + + bool readOnly_; + bool writeOnly_; + bool nullable_; +}; + +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + *documentStack.template Push() = '/'; + char buffer[21]; + size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); + for (size_t i = 0; i < length; i++) + *documentStack.template Push() = static_cast(buffer[i]); + } +}; + +// Partial specialized version for char to prevent buffer copying. +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + if (sizeof(SizeType) == 4) { + char *buffer = documentStack.template Push(1 + 10); // '/' + uint + *buffer++ = '/'; + const char* end = internal::u32toa(index, buffer); + documentStack.template Pop(static_cast(10 - (end - buffer))); + } + else { + char *buffer = documentStack.template Push(1 + 20); // '/' + uint64 + *buffer++ = '/'; + const char* end = internal::u64toa(index, buffer); + documentStack.template Pop(static_cast(20 - (end - buffer))); + } + } +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// IGenericRemoteSchemaDocumentProvider + +template +class IGenericRemoteSchemaDocumentProvider { +public: + typedef typename SchemaDocumentType::Ch Ch; + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + + virtual ~IGenericRemoteSchemaDocumentProvider() {} + virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; + virtual const SchemaDocumentType* GetRemoteDocument(const GenericUri uri, Specification& spec) { + // Default implementation just calls through for compatibility + // Following line suppresses unused parameter warning + (void)spec; + // printf("GetRemoteDocument: %d %d\n", spec.draft, spec.oapi); + return GetRemoteDocument(uri.GetBaseString(), uri.GetBaseStringLength()); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaDocument + +//! JSON schema document. +/*! + A JSON schema document is a compiled version of a JSON schema. + It is basically a tree of internal::Schema. + + \note This is an immutable class (i.e. its instance cannot be modified after construction). + \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. + \tparam Allocator Allocator type for allocating memory of this document. +*/ +template +class GenericSchemaDocument { +public: + typedef ValueT ValueType; + typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProviderType; + typedef Allocator AllocatorType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef internal::Schema SchemaType; + typedef GenericPointer PointerType; + typedef GenericValue GValue; + typedef GenericUri UriType; + typedef GenericStringRef StringRefType; + friend class internal::Schema; + template + friend class GenericSchemaValidator; + + //! Constructor. + /*! + Compile a JSON document into schema document. + + \param document A JSON document as source. + \param uri The base URI of this schema document for purposes of violation reporting. + \param uriLength Length of \c name, in code points. + \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. + \param allocator An optional allocator instance for allocating memory. Can be null. + \param pointer An optional JSON pointer to the start of the schema document + \param spec Optional schema draft or OpenAPI version. Used if no specification in document. Defaults to draft-04. + */ + explicit GenericSchemaDocument(const ValueType& document, const Ch* uri = 0, SizeType uriLength = 0, + IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0, + const PointerType& pointer = PointerType(), // PR #1393 + const Specification& spec = Specification(kDraft04)) : + remoteProvider_(remoteProvider), + allocator_(allocator), + ownAllocator_(), + root_(), + typeless_(), + schemaMap_(allocator, kInitialSchemaMapSize), + schemaRef_(allocator, kInitialSchemaRefSize), + spec_(spec), + error_(kObjectType), + currentError_() + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::GenericSchemaDocument"); + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + Ch noUri[1] = {0}; + uri_.SetString(uri ? uri : noUri, uriLength, *allocator_); + docId_ = UriType(uri_, allocator_); + + typeless_ = static_cast(allocator_->Malloc(sizeof(SchemaType))); + new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), allocator_, docId_); + + // Establish the schema draft or open api version. + // We only ever look for '$schema' or 'swagger' or 'openapi' at the root of the document. + SetSchemaSpecification(document); + + // Generate root schema, it will call CreateSchema() to create sub-schemas, + // And call HandleRefSchema() if there are $ref. + // PR #1393 use input pointer if supplied + root_ = typeless_; + if (pointer.GetTokenCount() == 0) { + CreateSchemaRecursive(&root_, pointer, document, document, docId_); + } + else if (const ValueType* v = pointer.Get(document)) { + CreateSchema(&root_, pointer, *v, document, docId_); + } + else { + GenericStringBuffer sb; + pointer.StringifyUriFragment(sb); + SchemaErrorValue(kSchemaErrorStartUnknown, PointerType(), sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch))); + } + + RAPIDJSON_ASSERT(root_ != 0); + + schemaRef_.ShrinkToFit(); // Deallocate all memory for ref + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : + remoteProvider_(rhs.remoteProvider_), + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + root_(rhs.root_), + typeless_(rhs.typeless_), + schemaMap_(std::move(rhs.schemaMap_)), + schemaRef_(std::move(rhs.schemaRef_)), + uri_(std::move(rhs.uri_)), + docId_(std::move(rhs.docId_)), + spec_(rhs.spec_), + error_(std::move(rhs.error_)), + currentError_(std::move(rhs.currentError_)) + { + rhs.remoteProvider_ = 0; + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.typeless_ = 0; + } +#endif + + //! Destructor + ~GenericSchemaDocument() { + while (!schemaMap_.Empty()) + schemaMap_.template Pop(1)->~SchemaEntry(); + + if (typeless_) { + typeless_->~SchemaType(); + Allocator::Free(typeless_); + } + + // these may contain some allocator data so clear before deleting ownAllocator_ + uri_.SetNull(); + error_.SetNull(); + currentError_.SetNull(); + + RAPIDJSON_DELETE(ownAllocator_); + } + + const GValue& GetURI() const { return uri_; } + + const Specification& GetSpecification() const { return spec_; } + bool IsSupportedSpecification() const { return spec_.IsSupported(); } + + //! Static method to get the specification of any schema document + // Returns kDraftNone if document is silent + static const Specification GetSpecification(const ValueType& document) { + SchemaDraft draft = GetSchemaDraft(document); + if (draft != kDraftNone) + return Specification(draft); + else { + OpenApiVersion oapi = GetOpenApiVersion(document); + if (oapi != kVersionNone) + return Specification(oapi); + } + return Specification(kDraftNone); + } + + //! Get the root schema. + const SchemaType& GetRoot() const { return *root_; } + + //! Gets the error object. + GValue& GetError() { return error_; } + const GValue& GetError() const { return error_; } + + static const StringRefType& GetSchemaErrorKeyword(SchemaErrorCode schemaErrorCode) { + switch (schemaErrorCode) { + case kSchemaErrorStartUnknown: return GetStartUnknownString(); + case kSchemaErrorRefPlainName: return GetRefPlainNameString(); + case kSchemaErrorRefInvalid: return GetRefInvalidString(); + case kSchemaErrorRefPointerInvalid: return GetRefPointerInvalidString(); + case kSchemaErrorRefUnknown: return GetRefUnknownString(); + case kSchemaErrorRefCyclical: return GetRefCyclicalString(); + case kSchemaErrorRefNoRemoteProvider: return GetRefNoRemoteProviderString(); + case kSchemaErrorRefNoRemoteSchema: return GetRefNoRemoteSchemaString(); + case kSchemaErrorRegexInvalid: return GetRegexInvalidString(); + case kSchemaErrorSpecUnknown: return GetSpecUnknownString(); + case kSchemaErrorSpecUnsupported: return GetSpecUnsupportedString(); + case kSchemaErrorSpecIllegal: return GetSpecIllegalString(); + case kSchemaErrorReadOnlyAndWriteOnly: return GetReadOnlyAndWriteOnlyString(); + default: return GetNullString(); + } + } + + //! Default error method + void SchemaError(const SchemaErrorCode code, const PointerType& location) { + currentError_ = GValue(kObjectType); + AddCurrentError(code, location); + } + + //! Method for error with single string value insert + void SchemaErrorValue(const SchemaErrorCode code, const PointerType& location, const Ch* value, SizeType length) { + currentError_ = GValue(kObjectType); + currentError_.AddMember(GetValueString(), GValue(value, length, *allocator_).Move(), *allocator_); + AddCurrentError(code, location); + } + + //! Method for error with invalid pointer + void SchemaErrorPointer(const SchemaErrorCode code, const PointerType& location, const Ch* value, SizeType length, const PointerType& pointer) { + currentError_ = GValue(kObjectType); + currentError_.AddMember(GetValueString(), GValue(value, length, *allocator_).Move(), *allocator_); + currentError_.AddMember(GetOffsetString(), static_cast(pointer.GetParseErrorOffset() / sizeof(Ch)), *allocator_); + AddCurrentError(code, location); + } + + private: + //! Prohibit copying + GenericSchemaDocument(const GenericSchemaDocument&); + //! Prohibit assignment + GenericSchemaDocument& operator=(const GenericSchemaDocument&); + + typedef const PointerType* SchemaRefPtr; // PR #1393 + + struct SchemaEntry { + SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} + ~SchemaEntry() { + if (owned) { + schema->~SchemaType(); + Allocator::Free(schema); + } + } + PointerType pointer; + SchemaType* schema; + bool owned; + }; + + void AddErrorInstanceLocation(GValue& result, const PointerType& location) { + GenericStringBuffer sb; + location.StringifyUriFragment(sb); + GValue instanceRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), *allocator_); + result.AddMember(GetInstanceRefString(), instanceRef, *allocator_); + } + + void AddError(GValue& keyword, GValue& error) { + typename GValue::MemberIterator member = error_.FindMember(keyword); + if (member == error_.MemberEnd()) + error_.AddMember(keyword, error, *allocator_); + else { + if (member->value.IsObject()) { + GValue errors(kArrayType); + errors.PushBack(member->value, *allocator_); + member->value = errors; + } + member->value.PushBack(error, *allocator_); + } + } + + void AddCurrentError(const SchemaErrorCode code, const PointerType& location) { + RAPIDJSON_SCHEMA_PRINT(InvalidKeyword, GetSchemaErrorKeyword(code)); + currentError_.AddMember(GetErrorCodeString(), code, *allocator_); + AddErrorInstanceLocation(currentError_, location); + AddError(GValue(GetSchemaErrorKeyword(code)).Move(), currentError_); + } + +#define RAPIDJSON_STRING_(name, ...) \ + static const StringRefType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const StringRefType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1)); \ + return v;\ + } + + RAPIDJSON_STRING_(InstanceRef, 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 'R', 'e', 'f') + RAPIDJSON_STRING_(ErrorCode, 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e') + RAPIDJSON_STRING_(Value, 'v', 'a', 'l', 'u', 'e') + RAPIDJSON_STRING_(Offset, 'o', 'f', 'f', 's', 'e', 't') + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(SpecUnknown, 'S', 'p', 'e', 'c', 'U', 'n', 'k', 'n', 'o', 'w', 'n') + RAPIDJSON_STRING_(SpecUnsupported, 'S', 'p', 'e', 'c', 'U', 'n', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd') + RAPIDJSON_STRING_(SpecIllegal, 'S', 'p', 'e', 'c', 'I', 'l', 'l', 'e', 'g', 'a', 'l') + RAPIDJSON_STRING_(StartUnknown, 'S', 't', 'a', 'r', 't', 'U', 'n', 'k', 'n', 'o', 'w', 'n') + RAPIDJSON_STRING_(RefPlainName, 'R', 'e', 'f', 'P', 'l', 'a', 'i', 'n', 'N', 'a', 'm', 'e') + RAPIDJSON_STRING_(RefInvalid, 'R', 'e', 'f', 'I', 'n', 'v', 'a', 'l', 'i', 'd') + RAPIDJSON_STRING_(RefPointerInvalid, 'R', 'e', 'f', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'I', 'n', 'v', 'a', 'l', 'i', 'd') + RAPIDJSON_STRING_(RefUnknown, 'R', 'e', 'f', 'U', 'n', 'k', 'n', 'o', 'w', 'n') + RAPIDJSON_STRING_(RefCyclical, 'R', 'e', 'f', 'C', 'y', 'c', 'l', 'i', 'c', 'a', 'l') + RAPIDJSON_STRING_(RefNoRemoteProvider, 'R', 'e', 'f', 'N', 'o', 'R', 'e', 'm', 'o', 't', 'e', 'P', 'r', 'o', 'v', 'i', 'd', 'e', 'r') + RAPIDJSON_STRING_(RefNoRemoteSchema, 'R', 'e', 'f', 'N', 'o', 'R', 'e', 'm', 'o', 't', 'e', 'S', 'c', 'h', 'e', 'm', 'a') + RAPIDJSON_STRING_(ReadOnlyAndWriteOnly, 'R', 'e', 'a', 'd', 'O', 'n', 'l', 'y', 'A', 'n', 'd', 'W', 'r', 'i', 't', 'e', 'O', 'n', 'l', 'y') + RAPIDJSON_STRING_(RegexInvalid, 'R', 'e', 'g', 'e', 'x', 'I', 'n', 'v', 'a', 'l', 'i', 'd') + +#undef RAPIDJSON_STRING_ + + // Static method to get schema draft of any schema document + static SchemaDraft GetSchemaDraft(const ValueType& document) { + static const Ch kDraft03String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '3', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft04String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '4', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft05String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '5', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft06String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '6', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft07String[] = { 'h', 't', 't', 'p', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '-', '0', '7', '/', 's', 'c', 'h', 'e', 'm', 'a', '#', '\0' }; + static const Ch kDraft2019_09String[] = { 'h', 't', 't', 'p', 's', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '/', '2', '0', '1', '9', '-', '0', '9', '/', 's', 'c', 'h', 'e', 'm', 'a', '\0' }; + static const Ch kDraft2020_12String[] = { 'h', 't', 't', 'p', 's', ':', '/', '/', 'j', 's', 'o', 'n', '-', 's', 'c', 'h', 'e', 'm', 'a', '.', 'o', 'r', 'g', '/', 'd', 'r', 'a', 'f', 't', '/', '2', '0', '2', '0', '-', '1', '2', '/', 's', 'c', 'h', 'e', 'm', 'a', '\0' }; + + if (!document.IsObject()) { + return kDraftNone; + } + + // Get the schema draft from the $schema keyword at the supplied location + typename ValueType::ConstMemberIterator itr = document.FindMember(SchemaType::GetSchemaString()); + if (itr != document.MemberEnd()) { + if (!itr->value.IsString()) return kDraftUnknown; + const UriType draftUri(itr->value); + // Check base uri for match + if (draftUri.Match(UriType(kDraft04String), false)) return kDraft04; + if (draftUri.Match(UriType(kDraft05String), false)) return kDraft05; + if (draftUri.Match(UriType(kDraft06String), false)) return kDraft06; + if (draftUri.Match(UriType(kDraft07String), false)) return kDraft07; + if (draftUri.Match(UriType(kDraft03String), false)) return kDraft03; + if (draftUri.Match(UriType(kDraft2019_09String), false)) return kDraft2019_09; + if (draftUri.Match(UriType(kDraft2020_12String), false)) return kDraft2020_12; + return kDraftUnknown; + } + // $schema not found + return kDraftNone; + } + + + // Get open api version of any schema document + static OpenApiVersion GetOpenApiVersion(const ValueType& document) { + static const Ch kVersion20String[] = { '2', '.', '0', '\0' }; + static const Ch kVersion30String[] = { '3', '.', '0', '.', '\0' }; // ignore patch level + static const Ch kVersion31String[] = { '3', '.', '1', '.', '\0' }; // ignore patch level + static SizeType len = internal::StrLen(kVersion30String); + + if (!document.IsObject()) { + return kVersionNone; + } + + // Get the open api version from the swagger / openapi keyword at the supplied location + typename ValueType::ConstMemberIterator itr = document.FindMember(SchemaType::GetSwaggerString()); + if (itr == document.MemberEnd()) itr = document.FindMember(SchemaType::GetOpenApiString()); + if (itr != document.MemberEnd()) { + if (!itr->value.IsString()) return kVersionUnknown; + const ValueType kVersion20Value(kVersion20String); + if (kVersion20Value == itr->value) return kVersion20; // must match 2.0 exactly + const ValueType kVersion30Value(kVersion30String); + if (itr->value.GetStringLength() > len && kVersion30Value == ValueType(itr->value.GetString(), len)) return kVersion30; // must match 3.0.x + const ValueType kVersion31Value(kVersion31String); + if (itr->value.GetStringLength() > len && kVersion31Value == ValueType(itr->value.GetString(), len)) return kVersion31; // must match 3.1.x + return kVersionUnknown; + } + // swagger or openapi not found + return kVersionNone; + } + + // Get the draft of the schema or the open api version (which implies the draft). + // Report an error if schema draft or open api version not supported or not recognized, or both in document, and carry on. + void SetSchemaSpecification(const ValueType& document) { + // Look for '$schema', 'swagger' or 'openapi' keyword at document root + SchemaDraft docDraft = GetSchemaDraft(document); + OpenApiVersion docOapi = GetOpenApiVersion(document); + // Error if both in document + if (docDraft != kDraftNone && docOapi != kVersionNone) + SchemaError(kSchemaErrorSpecIllegal, PointerType()); + // Use document draft or open api version if present or use spec from constructor + if (docDraft != kDraftNone) + spec_ = Specification(docDraft); + else if (docOapi != kVersionNone) + spec_ = Specification(docOapi); + // Error if draft or version unknown + if (spec_.draft == kDraftUnknown || spec_.oapi == kVersionUnknown) + SchemaError(kSchemaErrorSpecUnknown, PointerType()); + else if (!spec_.IsSupported()) + SchemaError(kSchemaErrorSpecUnsupported, PointerType()); + } + + // Changed by PR #1393 + void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document, const UriType& id) { + if (v.GetType() == kObjectType) { + UriType newid = UriType(CreateSchema(schema, pointer, v, document, id), allocator_); + + for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) + CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document, newid); + } + else if (v.GetType() == kArrayType) + for (SizeType i = 0; i < v.Size(); i++) + CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document, id); + } + + // Changed by PR #1393 + const UriType& CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document, const UriType& id) { + RAPIDJSON_ASSERT(pointer.IsValid()); + GenericStringBuffer sb; + pointer.StringifyUriFragment(sb); + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::CreateSchema", sb.GetString(), id.GetString()); + if (v.IsObject()) { + if (const SchemaType* sc = GetSchema(pointer)) { + if (schema) + *schema = sc; + AddSchemaRefs(const_cast(sc)); + } + else if (!HandleRefSchema(pointer, schema, v, document, id)) { + // The new schema constructor adds itself and its $ref(s) to schemaMap_ + SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_, id); + if (schema) + *schema = s; + return s->GetId(); + } + } + else { + if (schema) + *schema = typeless_; + AddSchemaRefs(typeless_); + } + return id; + } + + // Changed by PR #1393 + // TODO should this return a UriType& ? + bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document, const UriType& id) { + typename ValueType::ConstMemberIterator itr = v.FindMember(SchemaType::GetRefString()); + if (itr == v.MemberEnd()) + return false; + + GenericStringBuffer sb; + source.StringifyUriFragment(sb); + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::HandleRefSchema", sb.GetString(), id.GetString()); + // Resolve the source pointer to the $ref'ed schema (finally) + new (schemaRef_.template Push()) SchemaRefPtr(&source); + + if (itr->value.IsString()) { + SizeType len = itr->value.GetStringLength(); + if (len == 0) + SchemaError(kSchemaErrorRefInvalid, source); + else { + // First resolve $ref against the in-scope id + UriType scopeId = UriType(id, allocator_); + UriType ref = UriType(itr->value, allocator_).Resolve(scopeId, allocator_); + RAPIDJSON_SCHEMA_PRINT(SchemaIds, id.GetString(), itr->value.GetString(), ref.GetString()); + // See if the resolved $ref minus the fragment matches a resolved id in this document + // Search from the root. Returns the subschema in the document and its absolute JSON pointer. + PointerType basePointer = PointerType(); + const ValueType *base = FindId(document, ref, basePointer, docId_, false); + if (!base) { + // Remote reference - call the remote document provider + if (!remoteProvider_) + SchemaError(kSchemaErrorRefNoRemoteProvider, source); + else { + if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(ref, spec_)) { + const Ch* s = ref.GetFragString(); + len = ref.GetFragStringLength(); + if (len <= 1 || s[1] == '/') { + // JSON pointer fragment, absolute in the remote schema + const PointerType pointer(s, len, allocator_); + if (!pointer.IsValid()) + SchemaErrorPointer(kSchemaErrorRefPointerInvalid, source, s, len, pointer); + else { + // Get the subschema + if (const SchemaType *sc = remoteDocument->GetSchema(pointer)) { + if (schema) + *schema = sc; + AddSchemaRefs(const_cast(sc)); + return true; + } else + SchemaErrorValue(kSchemaErrorRefUnknown, source, ref.GetString(), ref.GetStringLength()); + } + } else + // Plain name fragment, not allowed in remote schema + SchemaErrorValue(kSchemaErrorRefPlainName, source, s, len); + } else + SchemaErrorValue(kSchemaErrorRefNoRemoteSchema, source, ref.GetString(), ref.GetStringLength()); + } + } + else { // Local reference + const Ch* s = ref.GetFragString(); + len = ref.GetFragStringLength(); + if (len <= 1 || s[1] == '/') { + // JSON pointer fragment, relative to the resolved URI + const PointerType relPointer(s, len, allocator_); + if (!relPointer.IsValid()) + SchemaErrorPointer(kSchemaErrorRefPointerInvalid, source, s, len, relPointer); + else { + // Get the subschema + if (const ValueType *pv = relPointer.Get(*base)) { + // Now get the absolute JSON pointer by adding relative to base + PointerType pointer(basePointer, allocator_); + for (SizeType i = 0; i < relPointer.GetTokenCount(); i++) + pointer = pointer.Append(relPointer.GetTokens()[i], allocator_); + if (IsCyclicRef(pointer)) + SchemaErrorValue(kSchemaErrorRefCyclical, source, ref.GetString(), ref.GetStringLength()); + else { + // Call CreateSchema recursively, but first compute the in-scope id for the $ref target as we have jumped there + // TODO: cache pointer <-> id mapping + size_t unresolvedTokenIndex; + scopeId = pointer.GetUri(document, docId_, &unresolvedTokenIndex, allocator_); + CreateSchema(schema, pointer, *pv, document, scopeId); + return true; + } + } else + SchemaErrorValue(kSchemaErrorRefUnknown, source, ref.GetString(), ref.GetStringLength()); + } + } else { + // Plain name fragment, relative to the resolved URI + // Not supported in open api 2.0 and 3.0 + PointerType pointer(allocator_); + if (spec_.oapi == kVersion20 || spec_.oapi == kVersion30) + SchemaErrorValue(kSchemaErrorRefPlainName, source, s, len); + // See if the fragment matches an id in this document. + // Search from the base we just established. Returns the subschema in the document and its absolute JSON pointer. + else if (const ValueType *pv = FindId(*base, ref, pointer, UriType(ref.GetBaseString(), ref.GetBaseStringLength(), allocator_), true, basePointer)) { + if (IsCyclicRef(pointer)) + SchemaErrorValue(kSchemaErrorRefCyclical, source, ref.GetString(), ref.GetStringLength()); + else { + // Call CreateSchema recursively, but first compute the in-scope id for the $ref target as we have jumped there + // TODO: cache pointer <-> id mapping + size_t unresolvedTokenIndex; + scopeId = pointer.GetUri(document, docId_, &unresolvedTokenIndex, allocator_); + CreateSchema(schema, pointer, *pv, document, scopeId); + return true; + } + } else + SchemaErrorValue(kSchemaErrorRefUnknown, source, ref.GetString(), ref.GetStringLength()); + } + } + } + } + + // Invalid/Unknown $ref + if (schema) + *schema = typeless_; + AddSchemaRefs(typeless_); + return true; + } + + //! Find the first subschema with a resolved 'id' that matches the specified URI. + // If full specified use all URI else ignore fragment. + // If found, return a pointer to the subschema and its JSON pointer. + // TODO cache pointer <-> id mapping + ValueType* FindId(const ValueType& doc, const UriType& finduri, PointerType& resptr, const UriType& baseuri, bool full, const PointerType& here = PointerType()) const { + SizeType i = 0; + ValueType* resval = 0; + UriType tempuri = UriType(finduri, allocator_); + UriType localuri = UriType(baseuri, allocator_); + if (doc.GetType() == kObjectType) { + // Establish the base URI of this object + typename ValueType::ConstMemberIterator m = doc.FindMember(SchemaType::GetIdString()); + if (m != doc.MemberEnd() && m->value.GetType() == kStringType) { + localuri = UriType(m->value, allocator_).Resolve(baseuri, allocator_); + } + // See if it matches + if (localuri.Match(finduri, full)) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::FindId (match)", full ? localuri.GetString() : localuri.GetBaseString()); + resval = const_cast(&doc); + resptr = here; + return resval; + } + // No match, continue looking + for (m = doc.MemberBegin(); m != doc.MemberEnd(); ++m) { + if (m->value.GetType() == kObjectType || m->value.GetType() == kArrayType) { + resval = FindId(m->value, finduri, resptr, localuri, full, here.Append(m->name.GetString(), m->name.GetStringLength(), allocator_)); + } + if (resval) break; + } + } else if (doc.GetType() == kArrayType) { + // Continue looking + for (typename ValueType::ConstValueIterator v = doc.Begin(); v != doc.End(); ++v) { + if (v->GetType() == kObjectType || v->GetType() == kArrayType) { + resval = FindId(*v, finduri, resptr, localuri, full, here.Append(i, allocator_)); + } + if (resval) break; + i++; + } + } + return resval; + } + + // Added by PR #1393 + void AddSchemaRefs(SchemaType* schema) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaDocument::AddSchemaRefs"); + while (!schemaRef_.Empty()) { + SchemaRefPtr *ref = schemaRef_.template Pop(1); + SchemaEntry *entry = schemaMap_.template Push(); + new (entry) SchemaEntry(**ref, schema, false, allocator_); + } + } + + // Added by PR #1393 + bool IsCyclicRef(const PointerType& pointer) const { + for (const SchemaRefPtr* ref = schemaRef_.template Bottom(); ref != schemaRef_.template End(); ++ref) + if (pointer == **ref) + return true; + return false; + } + + const SchemaType* GetSchema(const PointerType& pointer) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (pointer == target->pointer) + return target->schema; + return 0; + } + + PointerType GetPointer(const SchemaType* schema) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (schema == target->schema) + return target->pointer; + return PointerType(); + } + + const SchemaType* GetTypeless() const { return typeless_; } + + static const size_t kInitialSchemaMapSize = 64; + static const size_t kInitialSchemaRefSize = 64; + + IRemoteSchemaDocumentProviderType* remoteProvider_; + Allocator *allocator_; + Allocator *ownAllocator_; + const SchemaType* root_; //!< Root schema. + SchemaType* typeless_; + internal::Stack schemaMap_; // Stores created Pointer -> Schemas + internal::Stack schemaRef_; // Stores Pointer(s) from $ref(s) until resolved + GValue uri_; // Schema document URI + UriType docId_; + Specification spec_; + GValue error_; + GValue currentError_; +}; + +//! GenericSchemaDocument using Value type. +typedef GenericSchemaDocument SchemaDocument; +//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaValidator + +//! JSON Schema Validator. +/*! + A SAX style JSON schema validator. + It uses a \c GenericSchemaDocument to validate SAX events. + It delegates the incoming SAX events to an output handler. + The default output handler does nothing. + It can be reused multiple times by calling \c Reset(). + + \tparam SchemaDocumentType Type of schema document. + \tparam OutputHandler Type of output handler. Default handler does nothing. + \tparam StateAllocator Allocator for storing the internal validation states. +*/ +template < + typename SchemaDocumentType, + typename OutputHandler = BaseReaderHandler, + typename StateAllocator = CrtAllocator> +class GenericSchemaValidator : + public internal::ISchemaStateFactory, + public internal::ISchemaValidator, + public internal::IValidationErrorHandler { +public: + typedef typename SchemaDocumentType::SchemaType SchemaType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename SchemaType::EncodingType EncodingType; + typedef typename SchemaType::SValue SValue; + typedef typename EncodingType::Ch Ch; + typedef GenericStringRef StringRefType; + typedef GenericValue ValueType; + + //! Constructor without output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + outputHandler_(0), + error_(kObjectType), + currentError_(), + missingDependents_(), + valid_(true), + flags_(kValidateDefaultFlags), + depth_(0) + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::GenericSchemaValidator"); + } + + //! Constructor with output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + OutputHandler& outputHandler, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + outputHandler_(&outputHandler), + error_(kObjectType), + currentError_(), + missingDependents_(), + valid_(true), + flags_(kValidateDefaultFlags), + depth_(0) + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::GenericSchemaValidator (output handler)"); + } + + //! Destructor. + ~GenericSchemaValidator() { + Reset(); + RAPIDJSON_DELETE(ownStateAllocator_); + } + + //! Reset the internal states. + void Reset() { + while (!schemaStack_.Empty()) + PopSchema(); + documentStack_.Clear(); + ResetError(); + } + + //! Reset the error state. + void ResetError() { + error_.SetObject(); + currentError_.SetNull(); + missingDependents_.SetNull(); + valid_ = true; + } + + //! Implementation of ISchemaValidator + void SetValidateFlags(unsigned flags) { + flags_ = flags; + } + virtual unsigned GetValidateFlags() const { + return flags_; + } + + virtual bool IsValid() const { + if (!valid_) return false; + if (GetContinueOnErrors() && !error_.ObjectEmpty()) return false; + return true; + } + //! End of Implementation of ISchemaValidator + + //! Gets the error object. + ValueType& GetError() { return error_; } + const ValueType& GetError() const { return error_; } + + //! Gets the JSON pointer pointed to the invalid schema. + // If reporting all errors, the stack will be empty. + PointerType GetInvalidSchemaPointer() const { + return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer(); + } + + //! Gets the keyword of invalid schema. + // If reporting all errors, the stack will be empty, so return "errors". + const Ch* GetInvalidSchemaKeyword() const { + if (!schemaStack_.Empty()) return CurrentContext().invalidKeyword; + if (GetContinueOnErrors() && !error_.ObjectEmpty()) return (const Ch*)GetErrorsString(); + return 0; + } + + //! Gets the error code of invalid schema. + // If reporting all errors, the stack will be empty, so return kValidateErrors. + ValidateErrorCode GetInvalidSchemaCode() const { + if (!schemaStack_.Empty()) return CurrentContext().invalidCode; + if (GetContinueOnErrors() && !error_.ObjectEmpty()) return kValidateErrors; + return kValidateErrorNone; + } + + //! Gets the JSON pointer pointed to the invalid value. + // If reporting all errors, the stack will be empty. + PointerType GetInvalidDocumentPointer() const { + if (documentStack_.Empty()) { + return PointerType(); + } + else { + return PointerType(documentStack_.template Bottom(), documentStack_.GetSize() / sizeof(Ch)); + } + } + + void NotMultipleOf(int64_t actual, const SValue& expected) { + AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected); + } + void NotMultipleOf(uint64_t actual, const SValue& expected) { + AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected); + } + void NotMultipleOf(double actual, const SValue& expected) { + AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected); + } + void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMaximumString : 0); + } + void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMaximumString : 0); + } + void AboveMaximum(double actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMaximumString : 0); + } + void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMinimumString : 0); + } + void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMinimumString : 0); + } + void BelowMinimum(double actual, const SValue& expected, bool exclusive) { + AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected, + exclusive ? &SchemaType::GetExclusiveMinimumString : 0); + } + + void TooLong(const Ch* str, SizeType length, SizeType expected) { + AddNumberError(kValidateErrorMaxLength, + ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move()); + } + void TooShort(const Ch* str, SizeType length, SizeType expected) { + AddNumberError(kValidateErrorMinLength, + ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move()); + } + void DoesNotMatch(const Ch* str, SizeType length) { + currentError_.SetObject(); + currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator()); + AddCurrentError(kValidateErrorPattern); + } + + void DisallowedItem(SizeType index) { + currentError_.SetObject(); + currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator()); + AddCurrentError(kValidateErrorAdditionalItems, true); + } + void TooFewItems(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMinItems, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void TooManyItems(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMaxItems, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void DuplicateItems(SizeType index1, SizeType index2) { + ValueType duplicates(kArrayType); + duplicates.PushBack(index1, GetStateAllocator()); + duplicates.PushBack(index2, GetStateAllocator()); + currentError_.SetObject(); + currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator()); + AddCurrentError(kValidateErrorUniqueItems, true); + } + + void TooManyProperties(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMaxProperties, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void TooFewProperties(SizeType actualCount, SizeType expectedCount) { + AddNumberError(kValidateErrorMinProperties, + ValueType(actualCount).Move(), SValue(expectedCount).Move()); + } + void StartMissingProperties() { + currentError_.SetArray(); + } + void AddMissingProperty(const SValue& name) { + currentError_.PushBack(ValueType(name, GetStateAllocator()).Move(), GetStateAllocator()); + } + bool EndMissingProperties() { + if (currentError_.Empty()) + return false; + ValueType error(kObjectType); + error.AddMember(GetMissingString(), currentError_, GetStateAllocator()); + currentError_ = error; + AddCurrentError(kValidateErrorRequired); + return true; + } + void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) { + for (SizeType i = 0; i < count; ++i) + MergeError(static_cast(subvalidators[i])->GetError()); + } + void DisallowedProperty(const Ch* name, SizeType length) { + currentError_.SetObject(); + currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(), GetStateAllocator()); + AddCurrentError(kValidateErrorAdditionalProperties, true); + } + + void StartDependencyErrors() { + currentError_.SetObject(); + } + void StartMissingDependentProperties() { + missingDependents_.SetArray(); + } + void AddMissingDependentProperty(const SValue& targetName) { + missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator()); + } + void EndMissingDependentProperties(const SValue& sourceName) { + if (!missingDependents_.Empty()) { + // Create equivalent 'required' error + ValueType error(kObjectType); + ValidateErrorCode code = kValidateErrorRequired; + error.AddMember(GetMissingString(), missingDependents_.Move(), GetStateAllocator()); + AddErrorCode(error, code); + AddErrorInstanceLocation(error, false); + // When appending to a pointer ensure its allocator is used + PointerType schemaRef = GetInvalidSchemaPointer().Append(SchemaType::GetValidateErrorKeyword(kValidateErrorDependencies), &GetInvalidSchemaPointer().GetAllocator()); + AddErrorSchemaLocation(error, schemaRef.Append(sourceName.GetString(), sourceName.GetStringLength(), &GetInvalidSchemaPointer().GetAllocator())); + ValueType wrapper(kObjectType); + wrapper.AddMember(ValueType(SchemaType::GetValidateErrorKeyword(code), GetStateAllocator()).Move(), error, GetStateAllocator()); + currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), wrapper, GetStateAllocator()); + } + } + void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) { + currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), + static_cast(subvalidator)->GetError(), GetStateAllocator()); + } + bool EndDependencyErrors() { + if (currentError_.ObjectEmpty()) + return false; + ValueType error(kObjectType); + error.AddMember(GetErrorsString(), currentError_, GetStateAllocator()); + currentError_ = error; + AddCurrentError(kValidateErrorDependencies); + return true; + } + + void DisallowedValue(const ValidateErrorCode code = kValidateErrorEnum) { + currentError_.SetObject(); + AddCurrentError(code); + } + void StartDisallowedType() { + currentError_.SetArray(); + } + void AddExpectedType(const typename SchemaType::ValueType& expectedType) { + currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(), GetStateAllocator()); + } + void EndDisallowedType(const typename SchemaType::ValueType& actualType) { + ValueType error(kObjectType); + error.AddMember(GetExpectedString(), currentError_, GetStateAllocator()); + error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator()); + currentError_ = error; + AddCurrentError(kValidateErrorType); + } + void NotAllOf(ISchemaValidator** subvalidators, SizeType count) { + // Treat allOf like oneOf and anyOf to match https://rapidjson.org/md_doc_schema.html#allOf-anyOf-oneOf + AddErrorArray(kValidateErrorAllOf, subvalidators, count); + //for (SizeType i = 0; i < count; ++i) { + // MergeError(static_cast(subvalidators[i])->GetError()); + //} + } + void NoneOf(ISchemaValidator** subvalidators, SizeType count) { + AddErrorArray(kValidateErrorAnyOf, subvalidators, count); + } + void NotOneOf(ISchemaValidator** subvalidators, SizeType count) { + AddErrorArray(kValidateErrorOneOf, subvalidators, count); + } + void MultipleOneOf(SizeType index1, SizeType index2) { + ValueType matches(kArrayType); + matches.PushBack(index1, GetStateAllocator()); + matches.PushBack(index2, GetStateAllocator()); + currentError_.SetObject(); + currentError_.AddMember(GetMatchesString(), matches, GetStateAllocator()); + AddCurrentError(kValidateErrorOneOfMatch); + } + void Disallowed() { + currentError_.SetObject(); + AddCurrentError(kValidateErrorNot); + } + void DisallowedWhenWriting() { + currentError_.SetObject(); + AddCurrentError(kValidateErrorReadOnly); + } + void DisallowedWhenReading() { + currentError_.SetObject(); + AddCurrentError(kValidateErrorWriteOnly); + } + +#define RAPIDJSON_STRING_(name, ...) \ + static const StringRefType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const StringRefType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1)); \ + return v;\ + } + + RAPIDJSON_STRING_(InstanceRef, 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 'R', 'e', 'f') + RAPIDJSON_STRING_(SchemaRef, 's', 'c', 'h', 'e', 'm', 'a', 'R', 'e', 'f') + RAPIDJSON_STRING_(Expected, 'e', 'x', 'p', 'e', 'c', 't', 'e', 'd') + RAPIDJSON_STRING_(Actual, 'a', 'c', 't', 'u', 'a', 'l') + RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd') + RAPIDJSON_STRING_(Missing, 'm', 'i', 's', 's', 'i', 'n', 'g') + RAPIDJSON_STRING_(Errors, 'e', 'r', 'r', 'o', 'r', 's') + RAPIDJSON_STRING_(ErrorCode, 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e') + RAPIDJSON_STRING_(ErrorMessage, 'e', 'r', 'r', 'o', 'r', 'M', 'e', 's', 's', 'a', 'g', 'e') + RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's') + RAPIDJSON_STRING_(Matches, 'm', 'a', 't', 'c', 'h', 'e', 's') + +#undef RAPIDJSON_STRING_ + +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ + if (!valid_) return false; \ + if ((!BeginValue() && !GetContinueOnErrors()) || (!CurrentSchema().method arg1 && !GetContinueOnErrors())) {\ + *documentStack_.template Push() = '\0';\ + documentStack_.template Pop(1);\ + RAPIDJSON_SCHEMA_PRINT(InvalidDocument, documentStack_.template Bottom());\ + valid_ = false;\ + return valid_;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ + for (Context* context = schemaStack_.template Bottom(); context != schemaStack_.template End(); context++) {\ + if (context->hasher)\ + static_cast(context->hasher)->method arg2;\ + if (context->validators)\ + for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ + static_cast(context->validators[i_])->method arg2;\ + if (context->patternPropertiesValidators)\ + for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ + static_cast(context->patternPropertiesValidators[i_])->method arg2;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ + valid_ = (EndValue() || GetContinueOnErrors()) && (!outputHandler_ || outputHandler_->method arg2);\ + return valid_; + +#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ + RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) + + bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext()), ( )); } + bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } + bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } + bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } + bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } + bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } + bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } + bool RawNumber(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + bool String(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + + bool StartObject() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::StartObject"); + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); + valid_ = !outputHandler_ || outputHandler_->StartObject(); + return valid_; + } + + bool Key(const Ch* str, SizeType len, bool copy) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::Key", str); + if (!valid_) return false; + AppendToken(str, len); + if (!CurrentSchema().Key(CurrentContext(), str, len, copy) && !GetContinueOnErrors()) { + valid_ = false; + return valid_; + } + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); + valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy); + return valid_; + } + + bool EndObject(SizeType memberCount) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::EndObject"); + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); + if (!CurrentSchema().EndObject(CurrentContext(), memberCount) && !GetContinueOnErrors()) { + valid_ = false; + return valid_; + } + RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); + } + + bool StartArray() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::StartArray"); + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); + valid_ = !outputHandler_ || outputHandler_->StartArray(); + return valid_; + } + + bool EndArray(SizeType elementCount) { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::EndArray"); + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); + if (!CurrentSchema().EndArray(CurrentContext(), elementCount) && !GetContinueOnErrors()) { + valid_ = false; + return valid_; + } + RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); + } + +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ +#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ +#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ + + // Implementation of ISchemaStateFactory + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root, const bool inheritContinueOnErrors) { + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + ISchemaValidator* sv = new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, documentStack_.template Bottom(), documentStack_.GetSize(), + depth_ + 1, + &GetStateAllocator()); + sv->SetValidateFlags(inheritContinueOnErrors ? GetValidateFlags() : GetValidateFlags() & ~(unsigned)kValidateContinueOnErrorFlag); + return sv; + } + + virtual void DestroySchemaValidator(ISchemaValidator* validator) { + GenericSchemaValidator* v = static_cast(validator); + v->~GenericSchemaValidator(); + StateAllocator::Free(v); + } + + virtual void* CreateHasher() { + return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); + } + + virtual uint64_t GetHashCode(void* hasher) { + return static_cast(hasher)->GetHashCode(); + } + + virtual void DestroyHasher(void* hasher) { + HasherType* h = static_cast(hasher); + h->~HasherType(); + StateAllocator::Free(h); + } + + virtual void* MallocState(size_t size) { + return GetStateAllocator().Malloc(size); + } + + virtual void FreeState(void* p) { + StateAllocator::Free(p); + } + // End of implementation of ISchemaStateFactory + +private: + typedef typename SchemaType::Context Context; + typedef GenericValue, StateAllocator> HashCodeArray; + typedef internal::Hasher HasherType; + + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + const SchemaType& root, + const char* basePath, size_t basePathSize, + unsigned depth, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(root), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + outputHandler_(0), + error_(kObjectType), + currentError_(), + missingDependents_(), + valid_(true), + flags_(kValidateDefaultFlags), + depth_(depth) + { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::GenericSchemaValidator (internal)", basePath && basePathSize ? basePath : ""); + if (basePath && basePathSize) + memcpy(documentStack_.template Push(basePathSize), basePath, basePathSize); + } + + StateAllocator& GetStateAllocator() { + if (!stateAllocator_) + stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator)(); + return *stateAllocator_; + } + + bool GetContinueOnErrors() const { + return flags_ & kValidateContinueOnErrorFlag; + } + + bool BeginValue() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::BeginValue"); + if (schemaStack_.Empty()) + PushSchema(root_); + else { + if (CurrentContext().inArray) + internal::TokenHelper, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); + + if (!CurrentSchema().BeginValue(CurrentContext()) && !GetContinueOnErrors()) + return false; + + SizeType count = CurrentContext().patternPropertiesSchemaCount; + const SchemaType** sa = CurrentContext().patternPropertiesSchemas; + typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; + bool valueUniqueness = CurrentContext().valueUniqueness; + RAPIDJSON_ASSERT(CurrentContext().valueSchema); + PushSchema(*CurrentContext().valueSchema); + + if (count > 0) { + CurrentContext().objectPatternValidatorType = patternValidatorType; + ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; + SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; + va = static_cast(MallocState(sizeof(ISchemaValidator*) * count)); + std::memset(va, 0, sizeof(ISchemaValidator*) * count); + for (SizeType i = 0; i < count; i++) + va[validatorCount++] = CreateSchemaValidator(*sa[i], true); // Inherit continueOnError + } + + CurrentContext().arrayUniqueness = valueUniqueness; + } + return true; + } + + bool EndValue() { + RAPIDJSON_SCHEMA_PRINT(Method, "GenericSchemaValidator::EndValue"); + if (!CurrentSchema().EndValue(CurrentContext()) && !GetContinueOnErrors()) + return false; + + GenericStringBuffer sb; + schemaDocument_->GetPointer(&CurrentSchema()).StringifyUriFragment(sb); + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + RAPIDJSON_SCHEMA_PRINT(ValidatorPointers, sb.GetString(), documentStack_.template Bottom(), depth_); + void* hasher = CurrentContext().hasher; + uint64_t h = hasher && CurrentContext().arrayUniqueness ? static_cast(hasher)->GetHashCode() : 0; + + PopSchema(); + + if (!schemaStack_.Empty()) { + Context& context = CurrentContext(); + // Only check uniqueness if there is a hasher + if (hasher && context.valueUniqueness) { + HashCodeArray* a = static_cast(context.arrayElementHashCodes); + if (!a) + CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); + for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) + if (itr->GetUint64() == h) { + DuplicateItems(static_cast(itr - a->Begin()), a->Size()); + // Cleanup before returning if continuing + if (GetContinueOnErrors()) { + a->PushBack(h, GetStateAllocator()); + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/'); + } + RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorUniqueItems); + } + a->PushBack(h, GetStateAllocator()); + } + } + + // Remove the last token of document pointer + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/') + ; + + return true; + } + + void AppendToken(const Ch* str, SizeType len) { + documentStack_.template Reserve(1 + len * 2); // worst case all characters are escaped as two characters + *documentStack_.template PushUnsafe() = '/'; + for (SizeType i = 0; i < len; i++) { + if (str[i] == '~') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '0'; + } + else if (str[i] == '/') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '1'; + } + else + *documentStack_.template PushUnsafe() = str[i]; + } + } + + RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push()) Context(*this, *this, &schema, flags_); } + + RAPIDJSON_FORCEINLINE void PopSchema() { + Context* c = schemaStack_.template Pop(1); + if (HashCodeArray* a = static_cast(c->arrayElementHashCodes)) { + a->~HashCodeArray(); + StateAllocator::Free(a); + } + c->~Context(); + } + + void AddErrorInstanceLocation(ValueType& result, bool parent) { + GenericStringBuffer sb; + PointerType instancePointer = GetInvalidDocumentPointer(); + ((parent && instancePointer.GetTokenCount() > 0) + ? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1) + : instancePointer).StringifyUriFragment(sb); + ValueType instanceRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), + GetStateAllocator()); + result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator()); + } + + void AddErrorSchemaLocation(ValueType& result, PointerType schema = PointerType()) { + GenericStringBuffer sb; + SizeType len = CurrentSchema().GetURI().GetStringLength(); + if (len) memcpy(sb.Push(len), CurrentSchema().GetURI().GetString(), len * sizeof(Ch)); + if (schema.GetTokenCount()) schema.StringifyUriFragment(sb); + else GetInvalidSchemaPointer().StringifyUriFragment(sb); + ValueType schemaRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), + GetStateAllocator()); + result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator()); + } + + void AddErrorCode(ValueType& result, const ValidateErrorCode code) { + result.AddMember(GetErrorCodeString(), code, GetStateAllocator()); + } + + void AddError(ValueType& keyword, ValueType& error) { + typename ValueType::MemberIterator member = error_.FindMember(keyword); + if (member == error_.MemberEnd()) + error_.AddMember(keyword, error, GetStateAllocator()); + else { + if (member->value.IsObject()) { + ValueType errors(kArrayType); + errors.PushBack(member->value, GetStateAllocator()); + member->value = errors; + } + member->value.PushBack(error, GetStateAllocator()); + } + } + + void AddCurrentError(const ValidateErrorCode code, bool parent = false) { + AddErrorCode(currentError_, code); + AddErrorInstanceLocation(currentError_, parent); + AddErrorSchemaLocation(currentError_); + AddError(ValueType(SchemaType::GetValidateErrorKeyword(code), GetStateAllocator(), false).Move(), currentError_); + } + + void MergeError(ValueType& other) { + for (typename ValueType::MemberIterator it = other.MemberBegin(), end = other.MemberEnd(); it != end; ++it) { + AddError(it->name, it->value); + } + } + + void AddNumberError(const ValidateErrorCode code, ValueType& actual, const SValue& expected, + const typename SchemaType::ValueType& (*exclusive)() = 0) { + currentError_.SetObject(); + currentError_.AddMember(GetActualString(), actual, GetStateAllocator()); + currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator()); + if (exclusive) + currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(), true, GetStateAllocator()); + AddCurrentError(code); + } + + void AddErrorArray(const ValidateErrorCode code, + ISchemaValidator** subvalidators, SizeType count) { + ValueType errors(kArrayType); + for (SizeType i = 0; i < count; ++i) + errors.PushBack(static_cast(subvalidators[i])->GetError(), GetStateAllocator()); + currentError_.SetObject(); + currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator()); + AddCurrentError(code); + } + + const SchemaType& CurrentSchema() const { return *schemaStack_.template Top()->schema; } + Context& CurrentContext() { return *schemaStack_.template Top(); } + const Context& CurrentContext() const { return *schemaStack_.template Top(); } + + static const size_t kDefaultSchemaStackCapacity = 1024; + static const size_t kDefaultDocumentStackCapacity = 256; + const SchemaDocumentType* schemaDocument_; + const SchemaType& root_; + StateAllocator* stateAllocator_; + StateAllocator* ownStateAllocator_; + internal::Stack schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) + internal::Stack documentStack_; //!< stack to store the current path of validating document (Ch) + OutputHandler* outputHandler_; + ValueType error_; + ValueType currentError_; + ValueType missingDependents_; + bool valid_; + unsigned flags_; + unsigned depth_; +}; + +typedef GenericSchemaValidator SchemaValidator; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidatingReader + +//! A helper class for parsing with validation. +/*! + This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). + + \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam SourceEncoding Encoding of the input stream. + \tparam SchemaDocumentType Type of schema document. + \tparam StackAllocator Allocator type for stack. +*/ +template < + unsigned parseFlags, + typename InputStream, + typename SourceEncoding, + typename SchemaDocumentType = SchemaDocument, + typename StackAllocator = CrtAllocator> +class SchemaValidatingReader { +public: + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename InputStream::Ch Ch; + typedef GenericValue ValueType; + + //! Constructor + /*! + \param is Input stream. + \param sd Schema document. + */ + SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), invalidSchemaCode_(kValidateErrorNone), error_(kObjectType), isValid_(true) {} + + template + bool operator()(Handler& handler) { + GenericReader reader; + GenericSchemaValidator validator(sd_, handler); + parseResult_ = reader.template Parse(is_, validator); + + isValid_ = validator.IsValid(); + if (isValid_) { + invalidSchemaPointer_ = PointerType(); + invalidSchemaKeyword_ = 0; + invalidDocumentPointer_ = PointerType(); + error_.SetObject(); + } + else { + invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); + invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); + invalidSchemaCode_ = validator.GetInvalidSchemaCode(); + invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); + error_.CopyFrom(validator.GetError(), allocator_); + } + + return parseResult_; + } + + const ParseResult& GetParseResult() const { return parseResult_; } + bool IsValid() const { return isValid_; } + const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } + const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } + const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } + const ValueType& GetError() const { return error_; } + ValidateErrorCode GetInvalidSchemaCode() const { return invalidSchemaCode_; } + +private: + InputStream& is_; + const SchemaDocumentType& sd_; + + ParseResult parseResult_; + PointerType invalidSchemaPointer_; + const Ch* invalidSchemaKeyword_; + PointerType invalidDocumentPointer_; + ValidateErrorCode invalidSchemaCode_; + StackAllocator allocator_; + ValueType error_; + bool isValid_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_SCHEMA_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stream.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stream.h new file mode 100644 index 000000000..1fd70915c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stream.h @@ -0,0 +1,223 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "rapidjson.h" + +#ifndef RAPIDJSON_STREAM_H_ +#define RAPIDJSON_STREAM_H_ + +#include "encodings.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits. + */ + enum { copyOptimization = 0 }; +}; + +//! Reserve n characters for writing to a stream. +template +inline void PutReserve(Stream& stream, size_t count) { + (void)stream; + (void)count; +} + +//! Write character to a stream, presuming buffer is reserved. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { + stream.Put(c); +} + +//! Put N copies of a character to a stream. +template +inline void PutN(Stream& stream, Ch c, size_t n) { + PutReserve(stream, n); + for (size_t i = 0; i < n; i++) + PutUnsafe(stream, c); +} + +/////////////////////////////////////////////////////////////////////////////// +// GenericStreamWrapper + +//! A Stream Wrapper +/*! \tThis string stream is a wrapper for any stream by just forwarding any + \treceived message to the origin stream. + \note implements Stream concept +*/ + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4702) // unreachable code +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +template > +class GenericStreamWrapper { +public: + typedef typename Encoding::Ch Ch; + GenericStreamWrapper(InputStream& is): is_(is) {} + + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() { return is_.Tell(); } + Ch* PutBegin() { return is_.PutBegin(); } + void Put(Ch ch) { is_.Put(ch); } + void Flush() { is_.Flush(); } + size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); } + + // wrapper for MemoryStream + const Ch* Peek4() const { return is_.Peek4(); } + + // wrapper for AutoUTFInputStream + UTFType GetType() const { return is_.GetType(); } + bool HasBOM() const { return is_.HasBOM(); } + +protected: + InputStream& is_; +}; + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +RAPIDJSON_DIAG_POP +#endif + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream > InsituStringStream; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STREAM_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stringbuffer.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stringbuffer.h new file mode 100644 index 000000000..17bfeac9f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/stringbuffer.h @@ -0,0 +1,121 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#include "internal/stack.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +class GenericStringBuffer { +public: + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { + if (&rhs != this) + stack_ = std::move(rhs.stack_); + return *this; + } +#endif + + void Put(Ch c) { *stack_.template Push() = c; } + void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop(1); + } + + void Reserve(size_t count) { stack_.template Reserve(count); } + Ch* Push(size_t count) { return stack_.template Push(count); } + Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); + + return stack_.template Bottom(); + } + + //! Get the size of string in bytes in the string buffer. + size_t GetSize() const { return stack_.GetSize(); } + + //! Get the length of string in Ch in the string buffer. + size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; + +private: + // Prohibit copy constructor & assignment operator. + GenericStringBuffer(const GenericStringBuffer&); + GenericStringBuffer& operator=(const GenericStringBuffer&); +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer > StringBuffer; + +template +inline void PutReserve(GenericStringBuffer& stream, size_t count) { + stream.Reserve(count); +} + +template +inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { + stream.PutUnsafe(c); +} + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { + std::memset(stream.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/uri.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/uri.h new file mode 100644 index 000000000..f93e508a4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/uri.h @@ -0,0 +1,481 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// (C) Copyright IBM Corporation 2021 +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_URI_H_ +#define RAPIDJSON_URI_H_ + +#include "internal/strfunc.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// GenericUri + +template +class GenericUri { +public: + typedef typename ValueType::Ch Ch; +#if RAPIDJSON_HAS_STDSTRING + typedef std::basic_string String; +#endif + + //! Constructors + GenericUri(Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + } + + GenericUri(const Ch* uri, SizeType len, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + Parse(uri, len); + } + + GenericUri(const Ch* uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + Parse(uri, internal::StrLen(uri)); + } + + // Use with specializations of GenericValue + template GenericUri(const T& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + const Ch* u = uri.template Get(); // TypeHelper from document.h + Parse(u, internal::StrLen(u)); + } + +#if RAPIDJSON_HAS_STDSTRING + GenericUri(const String& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + Parse(uri.c_str(), internal::StrLen(uri.c_str())); + } +#endif + + //! Copy constructor + GenericUri(const GenericUri& rhs) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(), ownAllocator_() { + *this = rhs; + } + + //! Copy constructor + GenericUri(const GenericUri& rhs, Allocator* allocator) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() { + *this = rhs; + } + + //! Destructor. + ~GenericUri() { + Free(); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator + GenericUri& operator=(const GenericUri& rhs) { + if (this != &rhs) { + // Do not delete ownAllocator + Free(); + Allocate(rhs.GetStringLength()); + auth_ = CopyPart(scheme_, rhs.scheme_, rhs.GetSchemeStringLength()); + path_ = CopyPart(auth_, rhs.auth_, rhs.GetAuthStringLength()); + query_ = CopyPart(path_, rhs.path_, rhs.GetPathStringLength()); + frag_ = CopyPart(query_, rhs.query_, rhs.GetQueryStringLength()); + base_ = CopyPart(frag_, rhs.frag_, rhs.GetFragStringLength()); + uri_ = CopyPart(base_, rhs.base_, rhs.GetBaseStringLength()); + CopyPart(uri_, rhs.uri_, rhs.GetStringLength()); + } + return *this; + } + + //! Getters + // Use with specializations of GenericValue + template void Get(T& uri, Allocator& allocator) { + uri.template Set(this->GetString(), allocator); // TypeHelper from document.h + } + + const Ch* GetString() const { return uri_; } + SizeType GetStringLength() const { return uri_ == 0 ? 0 : internal::StrLen(uri_); } + const Ch* GetBaseString() const { return base_; } + SizeType GetBaseStringLength() const { return base_ == 0 ? 0 : internal::StrLen(base_); } + const Ch* GetSchemeString() const { return scheme_; } + SizeType GetSchemeStringLength() const { return scheme_ == 0 ? 0 : internal::StrLen(scheme_); } + const Ch* GetAuthString() const { return auth_; } + SizeType GetAuthStringLength() const { return auth_ == 0 ? 0 : internal::StrLen(auth_); } + const Ch* GetPathString() const { return path_; } + SizeType GetPathStringLength() const { return path_ == 0 ? 0 : internal::StrLen(path_); } + const Ch* GetQueryString() const { return query_; } + SizeType GetQueryStringLength() const { return query_ == 0 ? 0 : internal::StrLen(query_); } + const Ch* GetFragString() const { return frag_; } + SizeType GetFragStringLength() const { return frag_ == 0 ? 0 : internal::StrLen(frag_); } + +#if RAPIDJSON_HAS_STDSTRING + static String Get(const GenericUri& uri) { return String(uri.GetString(), uri.GetStringLength()); } + static String GetBase(const GenericUri& uri) { return String(uri.GetBaseString(), uri.GetBaseStringLength()); } + static String GetScheme(const GenericUri& uri) { return String(uri.GetSchemeString(), uri.GetSchemeStringLength()); } + static String GetAuth(const GenericUri& uri) { return String(uri.GetAuthString(), uri.GetAuthStringLength()); } + static String GetPath(const GenericUri& uri) { return String(uri.GetPathString(), uri.GetPathStringLength()); } + static String GetQuery(const GenericUri& uri) { return String(uri.GetQueryString(), uri.GetQueryStringLength()); } + static String GetFrag(const GenericUri& uri) { return String(uri.GetFragString(), uri.GetFragStringLength()); } +#endif + + //! Equality operators + bool operator==(const GenericUri& rhs) const { + return Match(rhs, true); + } + + bool operator!=(const GenericUri& rhs) const { + return !Match(rhs, true); + } + + bool Match(const GenericUri& uri, bool full = true) const { + Ch* s1; + Ch* s2; + if (full) { + s1 = uri_; + s2 = uri.uri_; + } else { + s1 = base_; + s2 = uri.base_; + } + if (s1 == s2) return true; + if (s1 == 0 || s2 == 0) return false; + return internal::StrCmp(s1, s2) == 0; + } + + //! Resolve this URI against another (base) URI in accordance with URI resolution rules. + // See https://tools.ietf.org/html/rfc3986 + // Use for resolving an id or $ref with an in-scope id. + // Returns a new GenericUri for the resolved URI. + GenericUri Resolve(const GenericUri& baseuri, Allocator* allocator = 0) { + GenericUri resuri; + resuri.allocator_ = allocator; + // Ensure enough space for combining paths + resuri.Allocate(GetStringLength() + baseuri.GetStringLength() + 1); // + 1 for joining slash + + if (!(GetSchemeStringLength() == 0)) { + // Use all of this URI + resuri.auth_ = CopyPart(resuri.scheme_, scheme_, GetSchemeStringLength()); + resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength()); + resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength()); + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + resuri.RemoveDotSegments(); + } else { + // Use the base scheme + resuri.auth_ = CopyPart(resuri.scheme_, baseuri.scheme_, baseuri.GetSchemeStringLength()); + if (!(GetAuthStringLength() == 0)) { + // Use this auth, path, query + resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength()); + resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength()); + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + resuri.RemoveDotSegments(); + } else { + // Use the base auth + resuri.path_ = CopyPart(resuri.auth_, baseuri.auth_, baseuri.GetAuthStringLength()); + if (GetPathStringLength() == 0) { + // Use the base path + resuri.query_ = CopyPart(resuri.path_, baseuri.path_, baseuri.GetPathStringLength()); + if (GetQueryStringLength() == 0) { + // Use the base query + resuri.frag_ = CopyPart(resuri.query_, baseuri.query_, baseuri.GetQueryStringLength()); + } else { + // Use this query + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + } + } else { + if (path_[0] == '/') { + // Absolute path - use all of this path + resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength()); + resuri.RemoveDotSegments(); + } else { + // Relative path - append this path to base path after base path's last slash + size_t pos = 0; + if (!(baseuri.GetAuthStringLength() == 0) && baseuri.GetPathStringLength() == 0) { + resuri.path_[pos] = '/'; + pos++; + } + size_t lastslashpos = baseuri.GetPathStringLength(); + while (lastslashpos > 0) { + if (baseuri.path_[lastslashpos - 1] == '/') break; + lastslashpos--; + } + std::memcpy(&resuri.path_[pos], baseuri.path_, lastslashpos * sizeof(Ch)); + pos += lastslashpos; + resuri.query_ = CopyPart(&resuri.path_[pos], path_, GetPathStringLength()); + resuri.RemoveDotSegments(); + } + // Use this query + resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength()); + } + } + } + // Always use this frag + resuri.base_ = CopyPart(resuri.frag_, frag_, GetFragStringLength()); + + // Re-constitute base_ and uri_ + resuri.SetBase(); + resuri.uri_ = resuri.base_ + resuri.GetBaseStringLength() + 1; + resuri.SetUri(); + return resuri; + } + + //! Get the allocator of this GenericUri. + Allocator& GetAllocator() { return *allocator_; } + +private: + // Allocate memory for a URI + // Returns total amount allocated + std::size_t Allocate(std::size_t len) { + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); + + // Allocate one block containing each part of the URI (5) plus base plus full URI, all null terminated. + // Order: scheme, auth, path, query, frag, base, uri + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + size_t total = (3 * len + 7) * sizeof(Ch); + scheme_ = static_cast(allocator_->Malloc(total)); + *scheme_ = '\0'; + auth_ = scheme_; + auth_++; + *auth_ = '\0'; + path_ = auth_; + path_++; + *path_ = '\0'; + query_ = path_; + query_++; + *query_ = '\0'; + frag_ = query_; + frag_++; + *frag_ = '\0'; + base_ = frag_; + base_++; + *base_ = '\0'; + uri_ = base_; + uri_++; + *uri_ = '\0'; + return total; + } + + // Free memory for a URI + void Free() { + if (scheme_) { + Allocator::Free(scheme_); + scheme_ = 0; + } + } + + // Parse a URI into constituent scheme, authority, path, query, & fragment parts + // Supports URIs that match regex ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? as per + // https://tools.ietf.org/html/rfc3986 + void Parse(const Ch* uri, std::size_t len) { + std::size_t start = 0, pos1 = 0, pos2 = 0; + Allocate(len); + + // Look for scheme ([^:/?#]+):)? + if (start < len) { + while (pos1 < len) { + if (uri[pos1] == ':') break; + pos1++; + } + if (pos1 != len) { + while (pos2 < len) { + if (uri[pos2] == '/') break; + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; + } + if (pos1 < pos2) { + pos1++; + std::memcpy(scheme_, &uri[start], pos1 * sizeof(Ch)); + scheme_[pos1] = '\0'; + start = pos1; + } + } + } + // Look for auth (//([^/?#]*))? + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + auth_ = scheme_ + GetSchemeStringLength(); + auth_++; + *auth_ = '\0'; + if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') { + pos2 = start + 2; + while (pos2 < len) { + if (uri[pos2] == '/') break; + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; + } + std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch)); + auth_[pos2 - start] = '\0'; + start = pos2; + } + // Look for path ([^?#]*) + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + path_ = auth_ + GetAuthStringLength(); + path_++; + *path_ = '\0'; + if (start < len) { + pos2 = start; + while (pos2 < len) { + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; + } + if (start != pos2) { + std::memcpy(path_, &uri[start], (pos2 - start) * sizeof(Ch)); + path_[pos2 - start] = '\0'; + if (path_[0] == '/') + RemoveDotSegments(); // absolute path - normalize + start = pos2; + } + } + // Look for query (\?([^#]*))? + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + query_ = path_ + GetPathStringLength(); + query_++; + *query_ = '\0'; + if (start < len && uri[start] == '?') { + pos2 = start + 1; + while (pos2 < len) { + if (uri[pos2] == '#') break; + pos2++; + } + if (start != pos2) { + std::memcpy(query_, &uri[start], (pos2 - start) * sizeof(Ch)); + query_[pos2 - start] = '\0'; + start = pos2; + } + } + // Look for fragment (#(.*))? + // Note need to set, increment, assign in 3 stages to avoid compiler warning bug. + frag_ = query_ + GetQueryStringLength(); + frag_++; + *frag_ = '\0'; + if (start < len && uri[start] == '#') { + std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch)); + frag_[len - start] = '\0'; + } + + // Re-constitute base_ and uri_ + base_ = frag_ + GetFragStringLength() + 1; + SetBase(); + uri_ = base_ + GetBaseStringLength() + 1; + SetUri(); + } + + // Reconstitute base + void SetBase() { + Ch* next = base_; + std::memcpy(next, scheme_, GetSchemeStringLength() * sizeof(Ch)); + next+= GetSchemeStringLength(); + std::memcpy(next, auth_, GetAuthStringLength() * sizeof(Ch)); + next+= GetAuthStringLength(); + std::memcpy(next, path_, GetPathStringLength() * sizeof(Ch)); + next+= GetPathStringLength(); + std::memcpy(next, query_, GetQueryStringLength() * sizeof(Ch)); + next+= GetQueryStringLength(); + *next = '\0'; + } + + // Reconstitute uri + void SetUri() { + Ch* next = uri_; + std::memcpy(next, base_, GetBaseStringLength() * sizeof(Ch)); + next+= GetBaseStringLength(); + std::memcpy(next, frag_, GetFragStringLength() * sizeof(Ch)); + next+= GetFragStringLength(); + *next = '\0'; + } + + // Copy a part from one GenericUri to another + // Return the pointer to the next part to be copied to + Ch* CopyPart(Ch* to, Ch* from, std::size_t len) { + RAPIDJSON_ASSERT(to != 0); + RAPIDJSON_ASSERT(from != 0); + std::memcpy(to, from, len * sizeof(Ch)); + to[len] = '\0'; + Ch* next = to + len + 1; + return next; + } + + // Remove . and .. segments from the path_ member. + // https://tools.ietf.org/html/rfc3986 + // This is done in place as we are only removing segments. + void RemoveDotSegments() { + std::size_t pathlen = GetPathStringLength(); + std::size_t pathpos = 0; // Position in path_ + std::size_t newpos = 0; // Position in new path_ + + // Loop through each segment in original path_ + while (pathpos < pathlen) { + // Get next segment, bounded by '/' or end + size_t slashpos = 0; + while ((pathpos + slashpos) < pathlen) { + if (path_[pathpos + slashpos] == '/') break; + slashpos++; + } + // Check for .. and . segments + if (slashpos == 2 && path_[pathpos] == '.' && path_[pathpos + 1] == '.') { + // Backup a .. segment in the new path_ + // We expect to find a previously added slash at the end or nothing + RAPIDJSON_ASSERT(newpos == 0 || path_[newpos - 1] == '/'); + size_t lastslashpos = newpos; + // Make sure we don't go beyond the start segment + if (lastslashpos > 1) { + // Find the next to last slash and back up to it + lastslashpos--; + while (lastslashpos > 0) { + if (path_[lastslashpos - 1] == '/') break; + lastslashpos--; + } + // Set the new path_ position + newpos = lastslashpos; + } + } else if (slashpos == 1 && path_[pathpos] == '.') { + // Discard . segment, leaves new path_ unchanged + } else { + // Move any other kind of segment to the new path_ + RAPIDJSON_ASSERT(newpos <= pathpos); + std::memmove(&path_[newpos], &path_[pathpos], slashpos * sizeof(Ch)); + newpos += slashpos; + // Add slash if not at end + if ((pathpos + slashpos) < pathlen) { + path_[newpos] = '/'; + newpos++; + } + } + // Move to next segment + pathpos += slashpos + 1; + } + path_[newpos] = '\0'; + } + + Ch* uri_; // Everything + Ch* base_; // Everything except fragment + Ch* scheme_; // Includes the : + Ch* auth_; // Includes the // + Ch* path_; // Absolute if starts with / + Ch* query_; // Includes the ? + Ch* frag_; // Includes the # + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Uri. +}; + +//! GenericUri for Value (UTF-8, default allocator). +typedef GenericUri Uri; + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_URI_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/writer.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/writer.h new file mode 100644 index 000000000..81f34fc80 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/rapidjson/writer.h @@ -0,0 +1,710 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "stream.h" +#include "internal/clzll.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include // placement new + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#elif defined(RAPIDJSON_NEON) +#include +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(c++98-compat) +#elif defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// WriteFlag + +/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kWriteDefaultFlags definition. + + User can define this as any \c WriteFlag combinations. +*/ +#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS +#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags +#endif + +//! Combination of writeFlags +enum WriteFlag { + kWriteNoFlags = 0, //!< No flags are set. + kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. + kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. + kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS +}; + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + static const int kDefaultMaxDecimalPlaces = 324; + + //! Constructor + /*! \param os Output stream. + \param stackAllocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + explicit + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Writer(Writer&& rhs) : + os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) { + rhs.os_ = 0; + } +#endif + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + int GetMaxDecimalPlaces() const { + return maxDecimalPlaces_; + } + + //! Sets the maximum number of decimal places for double output. + /*! + This setting truncates the output with specified number of decimal places. + + For example, + + \code + writer.SetMaxDecimalPlaces(3); + writer.StartArray(); + writer.Double(0.12345); // "0.123" + writer.Double(0.0001); // "0.0" + writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) + writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) + writer.EndArray(); + \endcode + + The default setting does not truncate any decimal places. You can restore to this setting by calling + \code + writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); + \endcode + */ + void SetMaxDecimalPlaces(int maxDecimalPlaces) { + maxDecimalPlaces_ = maxDecimalPlaces; + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } + bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } + bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } + bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + Prefix(kNumberType); + return EndValue(WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + RAPIDJSON_ASSERT(str != 0); + (void)copy; + Prefix(kStringType); + return EndValue(WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) + { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); // currently inside an Array, not Object + RAPIDJSON_ASSERT(0 == level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value + level_stack_.template Pop(1); + return EndValue(WriteEndObject()); + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndArray()); + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + */ + bool RawValue(const Ch* json, size_t length, Type type) { + RAPIDJSON_ASSERT(json != 0); + Prefix(type); + return EndValue(WriteRawValue(json, length)); + } + + //! Flush the output stream. + /*! + Allows the user to flush the output stream immediately. + */ + void Flush() { + os_->Flush(); + } + + static const size_t kDefaultLevelDepth = 32; + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + bool WriteNull() { + PutReserve(*os_, 4); + PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + PutReserve(*os_, 4); + PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); + } + else { + PutReserve(*os_, 5); + PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + if (!(writeFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char buffer[25]; + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + if (TargetEncoding::supportUnicode) + PutReserve(*os_, 2 + length * 6); // "\uxxxx..." + else + PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." + + PutUnsafe(*os_, '\"'); + GenericStringStream is(str); + while (ScanWriteUnescapedString(is, length)) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && static_cast(c) >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) + return false; + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); + } + else { + RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(lead ) & 15]); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(trail ) & 15]); + } + } + else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast(c)])) { + is.Take(); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, static_cast(escape[static_cast(c)])); + if (escape[static_cast(c)] == 'u') { + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); + PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); + } + } + else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + PutUnsafe(*os_, '\"'); + return true; + } + + bool ScanWriteUnescapedString(GenericStringStream& is, size_t length) { + return RAPIDJSON_LIKELY(is.Tell() < length); + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + bool WriteRawValue(const Ch* json, size_t length) { + PutReserve(*os_, length); + GenericStringStream is(json); + while (RAPIDJSON_LIKELY(is.Tell() < length)) { + RAPIDJSON_ASSERT(is.Peek() != '\0'); + if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + return true; + } + + void Prefix(Type type) { + (void)type; + if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + // Flush the value if it is the top level one. + bool EndValue(bool ret) { + if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text + Flush(); + return ret; + } + + OutputStream* os_; + internal::Stack level_stack_; + int maxDecimalPlaces_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(static_cast(11 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(static_cast(10 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(static_cast(21 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(static_cast(20 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). + if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + os_->Pop(static_cast(25 - (end - buffer))); + return true; +} + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (; p != endAligned; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType len; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + len = offset; +#else + len = static_cast(__builtin_ffs(r) - 1); +#endif + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#elif defined(RAPIDJSON_NEON) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + const uint8x16_t s0 = vmovq_n_u8('"'); + const uint8x16_t s1 = vmovq_n_u8('\\'); + const uint8x16_t s2 = vmovq_n_u8('\b'); + const uint8x16_t s3 = vmovq_n_u8(32); + + for (; p != endAligned; p += 16) { + const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); + uint8x16_t x = vceqq_u8(s, s0); + x = vorrq_u8(x, vceqq_u8(s, s1)); + x = vorrq_u8(x, vceqq_u8(s, s2)); + x = vorrq_u8(x, vcltq_u8(s, s3)); + + x = vrev64q_u8(x); // Rev in 64 + uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract + uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract + + SizeType len = 0; + bool escaped = false; + if (low == 0) { + if (high != 0) { + uint32_t lz = internal::clzll(high); + len = 8 + (lz >> 3); + escaped = true; + } + } else { + uint32_t lz = internal::clzll(low); + len = lz >> 3; + escaped = true; + } + if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + vst1q_u8(reinterpret_cast(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#endif // RAPIDJSON_NEON + +RAPIDJSON_NAMESPACE_END + +#if defined(_MSC_VER) || defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg.h index 7f5a84b94..da3944c5d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg.h @@ -1,23 +1,17 @@ -/*! - * @file thorvg.h - * - * The main APIs enabling the TVG initialization, preparation of the canvas and provisioning of its content: - * - drawing shapes: line, arc, curve, path, polygon... - * - drawing pictures: tvg, svg, png, jpg, bitmap... - * - drawing fillings: solid, linear and radial gradient... - * - drawing stroking: continuous stroking with arbitrary width, join, cap, dash styles. - * - drawing composition: blending, masking, path clipping... - * - drawing scene graph & affine transformation (translation, rotation, scale, ...) - * and finally drawing the canvas and TVG termination. - */ - -#include "../../lv_conf_internal.h" -#if LV_USE_THORVG_INTERNAL - - #ifndef _THORVG_H_ #define _THORVG_H_ +#include "../../lv_conf_internal.h" + +/*Testing of dependencies*/ +#if LV_USE_THORVG && LV_USE_VECTOR_GRAPHIC == 0 +#error "ThorVG: LV_USE_VECTOR_GRAPHIC is required. Enable it in lv_conf.h" +#endif + +#if LV_USE_THORVG_INTERNAL +#define TVG_BUILD 1 + + #include #include #include @@ -175,10 +169,10 @@ enum class CompositeMethod InvAlphaMask, ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value. LumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9 InvLumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the complement to the compositing target's pixels. - AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) @BETA_API - SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) @BETA_API - IntersectMask, ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) @BETA_API - DifferenceMask ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) @BETA_API + AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API) + SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API) + IntersectMask, ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) (Experimental API) + DifferenceMask ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API) }; @@ -189,7 +183,7 @@ enum class CompositeMethod * * @see Paint::blend() * - * @BETA_API + * @note Experimental API */ enum class BlendMethod : uint8_t { @@ -217,7 +211,7 @@ enum class CanvasEngine { Sw = (1 << 1), ///< CPU rasterizer. Gl = (1 << 2), ///< OpenGL rasterizer. - Wg = (1 << 3), ///< WebGPU rasterizer. @BETA_API + Wg = (1 << 3), ///< WebGPU rasterizer. (Experimental API) }; @@ -251,7 +245,7 @@ struct Matrix * @param pt The vertex coordinate * @param uv The normalized texture coordinate in the range (0.0..1.0, 0.0..1.0) * - * @BETA_API + * @note Experimental API */ struct Vertex { @@ -261,11 +255,11 @@ struct Vertex /** - * @brief A data structure representing a triange in a texture mesh + * @brief A data structure representing a triangle in a texture mesh * * @param vertex The three vertices that make up the polygon * - * @BETA_API + * @note Experimental API */ struct Polygon { @@ -295,7 +289,7 @@ public: * * @param[in] degree The value of the angle in degrees. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result rotate(float degree) noexcept; @@ -304,7 +298,7 @@ public: * * @param[in] factor The value of the scaling factor. The default value is 1. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result scale(float factor) noexcept; @@ -317,7 +311,7 @@ public: * @param[in] x The value of the horizontal shift. * @param[in] y The value of the vertical shift. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result translate(float x, float y) noexcept; @@ -328,7 +322,7 @@ public: * * @param[in] m The 3x3 augmented matrix. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result transform(const Matrix& m) noexcept; @@ -349,7 +343,7 @@ public: * * @param[in] o The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note Setting the opacity with this API may require multiple render pass for composition. It is recommended to avoid changing the opacity if possible. * @note ClipPath won't use the opacity value. (see: enum class CompositeMethod::ClipPath) @@ -362,7 +356,7 @@ public: * @param[in] target The paint of the target object. * @param[in] method The method used to composite the source object with the target. * - * @return Result::Success when succeed, Result::InvalidArguments otherwise. + * @retval Result::Success when succeed, Result::InvalidArguments otherwise. */ Result composite(std::unique_ptr target, CompositeMethod method) noexcept; @@ -375,9 +369,9 @@ public: * * @param[in] method The blending method to be set. * - * @return Result::Success when the blending method is successfully set. + * @retval Result::Success when the blending method is successfully set. * - * @BETA_API + * @note Experimental API */ Result blend(BlendMethod method) const noexcept; @@ -408,7 +402,7 @@ public: * @param[out] h The height of the object. * @param[in] transformed If @c true, the paint's transformations are taken into account, otherwise they aren't. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @note The bounding box doesn't indicate the actual drawing region. It's the smallest rectangle that encloses the object. */ @@ -446,7 +440,7 @@ public: * * @return The blending method * - * @BETA_API + * @note Experimental API */ BlendMethod blend() const noexcept; @@ -497,7 +491,7 @@ public: * @param[in] colorStops An array of ColorStop data structure. * @param[in] cnt The count of the @p colorStops array equal to the colors number used in the gradient. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept; @@ -506,7 +500,7 @@ public: * * @param[in] s The FillSpread value. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result spread(FillSpread s) noexcept; @@ -517,7 +511,7 @@ public: * * @param[in] m The 3x3 augmented matrix. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result transform(const Matrix& m) noexcept; @@ -542,7 +536,7 @@ public: * * In case no transformation was applied, the identity matrix is returned. * - * @retval The augmented transformation matrix. + * @return The augmented transformation matrix. */ Matrix transform() const noexcept; @@ -604,7 +598,7 @@ public: * @warning Please avoid accessing the paints during Canvas update/draw. You can access them after calling sync(). * @see Canvas::sync() * - * @BETA_API + * @note Experimental API */ std::list& paints() noexcept; @@ -635,7 +629,7 @@ public: * * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @see Canvas::push() * @see Canvas::paints() @@ -650,7 +644,7 @@ public: * * @param[in] paint A pointer to the Paint object or @c nullptr. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @note The Update behavior can be asynchronous if the assigned thread number is greater than zero. */ @@ -659,20 +653,44 @@ public: /** * @brief Requests the canvas to draw the Paint objects. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @note Drawing can be asynchronous if the assigned thread number is greater than zero. To guarantee the drawing is done, call sync() afterwards. * @see Canvas::sync() */ virtual Result draw() noexcept; + /** + * @brief Sets the drawing region in the canvas. + * + * This function defines the rectangular area of the canvas that will be used for drawing operations. + * The specified viewport is used to clip the rendering output to the boundaries of the rectangle. + * + * @param[in] x The x-coordinate of the upper-left corner of the rectangle. + * @param[in] y The y-coordinate of the upper-left corner of the rectangle. + * @param[in] w The width of the rectangle. + * @param[in] h The height of the rectangle. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @see SwCanvas::target() + * @see GlCanvas::target() + * @see WgCanvas::target() + * + * @warning It's not allowed to change the viewport during Canvas::push() - Canvas::sync() or Canvas::update() - Canvas::sync(). + * + * @note When resetting the target, the viewport will also be reset to the target size. + * @note Experimental API + */ + virtual Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept; + /** * @brief Guarantees that drawing task is finished. * * The Canvas rendering can be performed asynchronously. To make sure that rendering is finished, * the sync() must be called after the draw() regardless of threading. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * @see Canvas::draw() */ virtual Result sync() noexcept; @@ -706,7 +724,7 @@ public: * @param[in] x2 The horizontal coordinate of the second point used to determine the gradient bounds. * @param[in] y2 The vertical coordinate of the second point used to determine the gradient bounds. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case the first and the second points are equal, an object filled with such a gradient fill is not rendered. */ @@ -724,7 +742,7 @@ public: * @param[out] x2 The horizontal coordinate of the second point used to determine the gradient bounds. * @param[out] y2 The vertical coordinate of the second point used to determine the gradient bounds. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result linear(float* x1, float* y1, float* x2, float* y2) const noexcept; @@ -768,7 +786,7 @@ public: * @param[in] cy The vertical coordinate of the center of the bounding circle. * @param[in] radius The radius of the bounding circle. * - * @return Result::Success when succeed, Result::InvalidArguments in case the @p radius value is zero or less. + * @retval Result::Success when succeed, Result::InvalidArguments in case the @p radius value is zero or less. */ Result radial(float cx, float cy, float radius) noexcept; @@ -781,7 +799,7 @@ public: * @param[out] cy The vertical coordinate of the center of the bounding circle. * @param[out] radius The radius of the bounding circle. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result radial(float* cx, float* cy, float* radius) const noexcept; @@ -827,7 +845,7 @@ public: * * The transformation matrix, the color, the fill and the stroke properties are retained. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note The memory, where the path data is stored, is not deallocated at this stage for caching effect. */ @@ -841,7 +859,7 @@ public: * @param[in] x The horizontal coordinate of the initial point of the sub-path. * @param[in] y The vertical coordinate of the initial point of the sub-path. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result moveTo(float x, float y) noexcept; @@ -853,7 +871,7 @@ public: * @param[in] x The horizontal coordinate of the end-point of the line. * @param[in] y The vertical coordinate of the end-point of the line. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case this is the first command in the path, it corresponds to the moveTo() call. */ @@ -872,7 +890,7 @@ public: * @param[in] x The horizontal coordinate of the end-point of the curve. * @param[in] y The vertical coordinate of the end-point of the curve. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case this is the first command in the path, no data from the path are rendered. */ @@ -883,7 +901,7 @@ public: * * The value of the current point is set to the initial point of the closed sub-path. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case the sub-path does not contain any points, this function has no effect. */ @@ -909,7 +927,7 @@ public: * @param[in] rx The x-axis radius of the ellipse defining the rounded corners of the rectangle. * @param[in] ry The y-axis radius of the ellipse defining the rounded corners of the rectangle. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note For @p rx and @p ry greater than or equal to the half of @p w and the half of @p h, respectively, the shape become an ellipse. */ @@ -929,7 +947,7 @@ public: * @param[in] rx The x-axis radius of the ellipse. * @param[in] ry The y-axis radius of the ellipse. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result appendCircle(float cx, float cy, float rx, float ry) noexcept; @@ -946,7 +964,7 @@ public: * @param[in] sweep The central angle of the arc given in degrees, measured counter-clockwise from @p startAngle. * @param[in] pie Specifies whether to draw radii from the arc's center to both of its end-point - drawn if @c true. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note Setting @p sweep value greater than 360 degrees, is equivalent to calling appendCircle(cx, cy, radius, radius). */ @@ -964,7 +982,7 @@ public: * @param[in] pts The array of the two-dimensional points. * @param[in] ptsCnt The number of the points in the @p pts array. * - * @return Result::Success when succeed, Result::InvalidArguments otherwise. + * @retval Result::Success when succeed, Result::InvalidArguments otherwise. * * @note The interface is designed for optimal path setting if the caller has a completed path commands already. */ @@ -975,7 +993,7 @@ public: * * @param[in] width The width of the stroke. The default value is 0. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(float width) noexcept; @@ -987,7 +1005,7 @@ public: * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept; @@ -1022,7 +1040,7 @@ public: * * @param[in] cap The cap style value. The default value is @c StrokeCap::Square. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(StrokeCap cap) noexcept; @@ -1033,7 +1051,7 @@ public: * * @param[in] join The join style value. The default value is @c StrokeJoin::Bevel. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(StrokeJoin join) noexcept; @@ -1043,8 +1061,8 @@ public: * * @param[in] miterlimit The miterlimit imposes a limit on the extent of the stroke join, when the @c StrokeJoin::Miter join style is set. The default value is 4. * - * @return Result::Success when succeed, Result::NonSupport unsupported value, Result::FailedAllocation otherwise. - * + * @retval Result::Success when succeed, Result::NonSupport unsupported value, Result::FailedAllocation otherwise. + * * @since 0.11 */ Result strokeMiterlimit(float miterlimit) noexcept; @@ -1059,7 +1077,7 @@ public: * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note Either a solid color or a gradient fill is applied, depending on what was set as last. * @note ClipPath won't use the fill values. (see: enum class CompositeMethod::ClipPath) @@ -1073,7 +1091,7 @@ public: * * @param[in] f The unique pointer to the gradient fill. * - * @return Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. * * @note Either a solid color or a gradient fill is applied, depending on what was set as last. */ @@ -1084,7 +1102,7 @@ public: * * @param[in] r The fill rule value. The default value is @c FillRule::Winding. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result fill(FillRule r) noexcept; @@ -1094,7 +1112,7 @@ public: * * @param[in] strokeFirst If @c true the stroke is rendered before the fill, otherwise the stroke is rendered as the second one (the default option). * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. * * @since 0.10 */ @@ -1160,7 +1178,7 @@ public: * @param[out] b The blue color channel value in the range [0 ~ 255]. * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. */ Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a = nullptr) const noexcept; @@ -1240,6 +1258,10 @@ public: /** * @brief Loads a picture data directly from a file. * + * ThorVG efficiently caches the loaded data using the specified @p path as a key. + * This means that loading the same file again will not result in duplicate operations; + * instead, ThorVG will reuse the previously loaded picture data. + * * @param[in] path A path to the picture file. * * @retval Result::Success When succeed. @@ -1255,6 +1277,10 @@ public: /** * @brief Loads a picture data from a memory block of a given size. * + * ThorVG efficiently caches the loaded data using the specified @p data address as a key + * when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations + * for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. + * * @param[in] data A pointer to a memory location where the content of the picture file is stored. * @param[in] size The size in bytes of the memory occupied by the @p data. * @param[in] copy Decides whether the data should be copied into the engine local buffer. @@ -1299,7 +1325,7 @@ public: * @param[in] w A new width of the image in pixels. * @param[in] h A new height of the image in pixels. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. */ Result size(float w, float h) noexcept; @@ -1309,13 +1335,24 @@ public: * @param[out] w The width of the image in pixels. * @param[out] h The height of the image in pixels. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result size(float* w, float* h) const noexcept; /** * @brief Loads a raw data from a memory block with a given size. * + * ThorVG efficiently caches the loaded data using the specified @p data address as a key + * when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations + * for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. + * + * @param[in] paint A Tvg_Paint pointer to the picture object. + * @param[in] data A pointer to a memory location where the content of the picture raw data is stored. + * @param[in] w The width of the image @p data in pixels. + * @param[in] h The height of the image @p data in pixels. + * @param[in] premultiplied If @c true, the given image data is alpha-premultiplied. + * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. + * * @retval Result::Success When succeed, Result::InsufficientCondition otherwise. * @retval Result::FailedAllocation An internal error possibly with memory allocation. * @@ -1343,7 +1380,7 @@ public: * @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect. * @warning Please do not use it, this API is not official one. It could be modified in the next version. * - * @BETA_API + * @note Experimental API */ Result mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept; @@ -1352,12 +1389,12 @@ public: * * @param[out] triangles Optional. A pointer to the array of Polygons used by this mesh. * - * @return uint32_t The number of polygons in the array. + * @return The number of polygons in the array. * * @note Modifying the triangles returned by this method will modify them directly within the mesh. * @warning Please do not use it, this API is not official one. It could be modified in the next version. * - * @BETA_API + * @note Experimental API */ uint32_t mesh(const Polygon** triangles) const noexcept; @@ -1406,7 +1443,7 @@ public: * * @param[in] paint A Paint object to be drawn. * - * @return Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. * * @note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. * @see Scene::paints() @@ -1436,7 +1473,7 @@ public: * @see Scene::push() * @see Scene::clear() * - * @BETA_API + * @note Experimental API */ std::list& paints() noexcept; @@ -1446,7 +1483,7 @@ public: * * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. * - * @return Result::Success when succeed + * @retval Result::Success when succeed * * @warning If you don't free the paints they become dangled. They are supposed to be reused, otherwise you are responsible for their lives. Thus please use the @p free argument only when you know how it works, otherwise it's not recommended. * @@ -1474,6 +1511,142 @@ public: }; +/** + * @class Text + * + * @brief A class to represent text objects in a graphical context, allowing for rendering and manipulation of unicode text. + * + * @note Experimental API + */ +class TVG_API Text final : public Paint +{ +public: + ~Text(); + + /** + * @brief Sets the font properties for the text. + * + * This function allows you to define the font characteristics used for text rendering. + * It sets the font name, size and optionally the style. + * + * @param[in] name The name of the font. This should correspond to a font available in the canvas. + * @param[in] size The size of the font in points. This determines how large the text will appear. + * @param[in] style The style of the font. It can be used to set the font to 'italic'. + * If not specified, the default style is used. Only 'italic' style is supported currently. + * + * @retval Result::Success when the font properties are set successfully. + * @retval Result::InsufficientCondition when the specified @p name cannot be found. + * + * @note Experimental API + */ + Result font(const char* name, float size, const char* style = nullptr) noexcept; + + /** + * @brief Assigns the given unicode text to be rendered. + * + * This function sets the unicode string that will be displayed by the rendering system. + * The text is set according to the specified UTF encoding method, which defaults to UTF-8. + * + * @param[in] text The multi-byte text encoded with utf8 string to be rendered. + * + * @retval Result::Success when succeed. + * + * @note Experimental API + */ + Result text(const char* text) noexcept; + + /** + * @brief Sets the text color. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * + * @retval Result::Success when succeed. + * @retval Result::InsufficientCondition when the font has not been set up prior to this operation. + * + * @see Text::font() + * + * @note Experimental API + */ + Result fill(uint8_t r, uint8_t g, uint8_t b) noexcept; + + /** + * @brief Sets the gradient fill for all of the figures from the text. + * + * The parts of the text defined as inner are filled. + * + * @param[in] f The unique pointer to the gradient fill. + * + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::InsufficientCondition when the font has not been set up prior to this operation. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + * @note Experimental API + * + * @see Text::font() + */ + Result fill(std::unique_ptr f) noexcept; + + /** + * @brief Loads a scalable font data(ttf) from a file. + * + * ThorVG efficiently caches the loaded data using the specified @p path as a key. + * This means that loading the same file again will not result in duplicate operations; + * instead, ThorVG will reuse the previously loaded font data. + * + * @param[in] path The path to the font file. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case the @p path is invalid. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @note Experimental API + * + * @see Text::unload(const std::string& path) + */ + static Result load(const std::string& path) noexcept; + + /** + * @brief Unloads the specified scalable font data (TTF) that was previously loaded. + * + * This function is used to release resources associated with a font file that has been loaded into memory. + * + * @param[in] path The file path of the loaded font. + * + * @retval Result::Success Successfully unloads the font data. + * @retval Result::InsufficientCondition Fails if the loader is not initialized. + * + * @note If the font data is currently in use, it will not be immediately unloaded. + * @note Experimental API + * + * @see Text::load(const std::string& path) + */ + static Result unload(const std::string& path) noexcept; + + /** + * @brief Creates a new Text object. + * + * @return A new Text object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Text class type. + * + * @return The type id of the Text class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Text); +}; + + /** * @class SwCanvas * @@ -1491,8 +1664,8 @@ public: { ABGR8888 = 0, ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. (a << 24 | b << 16 | g << 8 | r) ARGB8888, ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. (a << 24 | r << 16 | g << 8 | b) - ABGR8888S, ///< @BETA_API The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. - ARGB8888S, ///< @BETA_API The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. + ABGR8888S, ///< The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. @since 0.12 + ARGB8888S, ///< The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. @since 0.12 }; /** @@ -1507,7 +1680,7 @@ public: }; /** - * @brief Sets the target buffer for the rasterization. + * @brief Sets the drawing target for the rasterization. * * The buffer of a desirable size should be allocated and owned by the caller. * @@ -1522,7 +1695,9 @@ public: * @retval Result::InvalidArguments In case no valid pointer is provided or the width, or the height or the stride is zero. * @retval Result::NonSupport In case the software engine is not supported. * - * @warning Do not access @p buffer during Canvas::draw() - Canvas::sync(). It should not be accessed while TVG is writing on it. + * @warning Do not access @p buffer during Canvas::push() - Canvas::sync(). It should not be accessed while the engine is writing on it. + * + * @see Canvas::viewport() */ Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept; @@ -1568,7 +1743,7 @@ public: * * @warning Please do not use it. This class is not fully supported yet. * - * @BETA_API + * @note Experimental API */ class TVG_API GlCanvas final : public Canvas { @@ -1576,20 +1751,31 @@ public: ~GlCanvas(); /** - * @brief Sets the target buffer for the rasterization. + * @brief Sets the drawing target for rasterization. * - * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * This function specifies the drawing target where the rasterization will occur. It can target + * a specific framebuffer object (FBO) or the main surface. * - * @BETA_API - */ - Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept; + * @param[in] id The GL target ID, usually indicating the FBO ID. A value of @c 0 specifies the main surface. + * @param[in] w The width (in pixels) of the raster image. + * @param[in] h The height (in pixels) of the raster image. + * + * @warning This API is experimental and not officially supported. It may be modified or removed in future versions. + * @warning Drawing on the main surface is currently not permitted. If the identifier (@p id) is set to @c 0, the operation will be aborted. + * + * @see Canvas::viewport() + * + * @note Currently, this only allows the GL_RGBA8 color space format. + * @note Experimental API + */ + Result target(int32_t id, uint32_t w, uint32_t h) noexcept; /** * @brief Creates a new GlCanvas object. * * @return A new GlCanvas object. * - * @BETA_API + * @note Experimental API */ static std::unique_ptr gen() noexcept; @@ -1604,7 +1790,7 @@ public: * * @warning Please do not use it. This class is not fully supported yet. * - * @BETA_API + * @note Experimental API */ class TVG_API WgCanvas final : public Canvas { @@ -1616,7 +1802,8 @@ public: * * @warning Please do not use it, this API is not official one. It could be modified in the next version. * - * @BETA_API + * @note Experimental API + * @see Canvas::viewport() */ Result target(void* window, uint32_t w, uint32_t h) noexcept; @@ -1625,7 +1812,7 @@ public: * * @return A new WgCanvas object. * - * @BETA_API + * @note Experimental API */ static std::unique_ptr gen() noexcept; @@ -1690,7 +1877,7 @@ public: * * This class supports the display and control of animation frames. * - * @BETA_API + * @since 0.13 */ class TVG_API Animation @@ -1704,14 +1891,17 @@ public: * @param[in] no The index of the animation frame to be displayed. The index should be less than the totalFrame(). * * @retval Result::Success Successfully set the frame. - * @retval Result::InsufficientCondition No animatable data loaded from the Picture. - * @retval Result::NonSupport The Picture data does not support animations. + * @retval Result::InsufficientCondition if the given @p no is the same as the current frame value. + * @retval Result::NonSupport The current Picture data does not support animations. + * + * @note For efficiency, ThorVG ignores updates to the new frame value if the difference from the current frame value + * is less than 0.001. In such cases, it returns @c Result::InsufficientCondition. + * Values less than 0.001 may be disregarded and may not be accurately retained by the Animation. * * @see totalFrame() * - * @BETA_API */ - Result frame(uint32_t no) noexcept; + Result frame(float no) noexcept; /** * @brief Retrieves a picture instance associated with this animation instance. @@ -1724,7 +1914,6 @@ public: * * @warning The picture instance is owned by Animation. It should not be deleted manually. * - * @BETA_API */ Picture* picture() const noexcept; @@ -1735,12 +1924,11 @@ public: * * @note If the Picture is not properly configured, this function will return 0. * - * @see Animation::frame(uint32_t no) + * @see Animation::frame(float no) * @see Animation::totalFrame() * - * @BETA_API */ - uint32_t curFrame() const noexcept; + float curFrame() const noexcept; /** * @brief Retrieves the total number of frames in the animation. @@ -1750,9 +1938,8 @@ public: * @note Frame numbering starts from 0. * @note If the Picture is not properly configured, this function will return 0. * - * @BETA_API */ - uint32_t totalFrame() const noexcept; + float totalFrame() const noexcept; /** * @brief Retrieves the duration of the animation in seconds. @@ -1761,16 +1948,52 @@ public: * * @note If the Picture is not properly configured, this function will return 0. * - * @BETA_API */ float duration() const noexcept; + /** + * @brief Specifies the playback segment of the animation. + * + * The set segment is designated as the play area of the animation. + * This is useful for playing a specific segment within the entire animation. + * After setting, the number of animation frames and the playback time are calculated + * by mapping the playback segment as the entire range. + * + * @param[in] begin segment start. + * @param[in] end segment end. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * @retval Result::NonSupport When it's not animatable. + * + * @note Range from 0.0~1.0 + * @note If a marker has been specified, its range will be disregarded. + * @see LottieAnimation::segment(const char* marker) + * @note Experimental API + */ + Result segment(float begin, float end) noexcept; + + /** + * @brief Gets the current segment. + * + * @param[out] begin segment start. + * @param[out] end segment end. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * @retval Result::NonSupport When it's not animatable. + * + * @note Experimental API + */ + Result segment(float* begin, float* end = nullptr) noexcept; + /** * @brief Creates a new Animation object. * * @return A new Animation object. * - * @BETA_API */ static std::unique_ptr gen() noexcept; @@ -1787,7 +2010,7 @@ public: * It's useful when you need to save the composed scene or image from a paint object and recreate it later. * * The file format is decided by the extension name(i.e. "*.tvg") while the supported formats depend on the TVG packaging environment. - * If it doesn't support the file format, the save() method returns the @c Result::NonSuppport result. + * If it doesn't support the file format, the save() method returns the @c Result::NonSupport result. * * Once you export a paint to the file successfully, you can recreate it using the Picture class. * @@ -1800,6 +2023,15 @@ class TVG_API Saver final public: ~Saver(); + /** + * @brief Sets the base background content for the saved image. + * + * @param[in] paint The paint to be drawn as the background image for the saving paint. + * + * @note Experimental API + */ + Result background(std::unique_ptr paint) noexcept; + /** * @brief Exports the given @p paint data to the given @p path * @@ -1824,6 +2056,31 @@ public: */ Result save(std::unique_ptr paint, const std::string& path, bool compress = true) noexcept; + /** + * @brief Export the provided animation data to the specified file path. + * + * This function exports the given animation data to the provided file path. You can also specify the desired frame rate in frames per second (FPS) by providing the fps parameter. + * + * @param[in] animation The animation to be saved, including all associated properties. + * @param[in] path The path to the file where the animation will be saved. + * @param[in] quality The encoded quality level. @c 0 is the minimum, @c 100 is the maximum value(recommended). + * @param[in] fps The desired frames per second (FPS). For example, to encode data at 60 FPS, pass 60. Pass 0 to keep the original frame data. + * + * @retval Result::Success if the export succeeds. + * @retval Result::InsufficientCondition if there are ongoing resource-saving operations. + * @retval Result::NonSupport if an attempt is made to save the file with an unknown extension or in an unsupported format. + * @retval Result::MemoryCorruption in case of an internal error. + * @retval Result::Unknown if attempting to save an empty paint. + * + * @note A higher frames per second (FPS) would result in a larger file size. It is recommended to use the default value. + * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards. + * + * @see Saver::sync() + * + * @note Experimental API + */ + Result save(std::unique_ptr animation, const std::string& path, uint32_t quality = 100, uint32_t fps = 0) noexcept; + /** * @brief Guarantees that the saving task is finished. * diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_capi.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_capi.h index c4db0cdfd..98b709ea2 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_capi.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_capi.h @@ -17,9 +17,9 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL +#define TVG_BUILD 1 -#include "../../lv_conf_internal.h" -#if LV_USE_THORVG_INTERNAL +#define TVG_BUILD 1 #ifndef __THORVG_CAPI_H__ #define __THORVG_CAPI_H__ @@ -86,7 +86,7 @@ typedef struct _Tvg_Canvas Tvg_Canvas; /** * \brief A structure representing a graphical element. * -* \warning The TvgPaint objects can not be shared between Canvases. +* \warning The TvgPaint objects cannot be shared between Canvases. */ typedef struct _Tvg_Paint Tvg_Paint; @@ -103,7 +103,7 @@ typedef struct _Tvg_Gradient Tvg_Gradient; typedef struct _Tvg_Saver Tvg_Saver; /** -* \brief A structure representing an animation controller object. (BETA_API) +* \brief A structure representing an animation controller object. */ typedef struct _Tvg_Animation Tvg_Animation; @@ -144,7 +144,7 @@ typedef enum { TVG_COMPOSITE_METHOD_ALPHA_MASK, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible. TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. TVG_COMPOSITE_METHOD_LUMA_MASK, ///< The source pixels are converted to grayscale (luma value) and alpha blended with the target. As a result, only the part of the source which intersects with the target is visible. \since 0.9 - TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK ///< The source pixels are converted to grayscale (luma value) and complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. \BETA_API + TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK ///< The source pixels are converted to grayscale (luma value) and complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. \Experimental API } Tvg_Composite_Method; /** @@ -152,7 +152,7 @@ typedef enum { * * \ingroup ThorVGCapi_Paint * - * @BETA_API + * @note Experimental API */ typedef enum { TVG_BLEND_METHOD_NORMAL = 0, ///< Perform the alpha blending(default). S if (Sa == 255), otherwise (Sa * S) + (255 - Sa) * D @@ -404,8 +404,10 @@ typedef enum { * \brief Enumeration specifying the methods of combining the 8-bit color channels into 32-bit color. */ typedef enum { - TVG_COLORSPACE_ABGR8888 = 0, ///< The 8-bit color channels are combined into 32-bit color in the order: alpha, blue, green, red. - TVG_COLORSPACE_ARGB8888 ///< The 8-bit color channels are combined into 32-bit color in the order: alpha, red, green, blue. + TVG_COLORSPACE_ABGR8888 = 0, ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. (a << 24 | b << 16 | g << 8 | r) + TVG_COLORSPACE_ARGB8888, ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. (a << 24 | r << 16 | g << 8 | b) + TVG_COLORSPACE_ABGR8888S, ///< The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. @since 0.13 + TVG_COLORSPACE_ARGB8888S ///< The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. @since 0.13 } Tvg_Colorspace; @@ -457,7 +459,7 @@ TVG_API Tvg_Canvas* tvg_swcanvas_create(void); * \retval TVG_RESULT_INVALID_ARGUMENTS An invalid canvas or buffer pointer passed or one of the @p stride, @p w or @p h being zero. * \retval TVG_RESULT_NOT_SUPPORTED The software engine is not supported. * -* \warning Do not access @p buffer during tvg_canvas_draw() - tvg_canvas_sync(). It should not be accessed while TVG is writing on it. +* \warning Do not access @p buffer during tvg_canvas_draw() - tvg_canvas_sync(). It should not be accessed while the engine is writing on it. * * \see Tvg_Colorspace */ @@ -747,6 +749,30 @@ TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas); TVG_API Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas); +/*! +* \brief Sets the drawing region in the canvas. +* +* This function defines the rectangular area of the canvas that will be used for drawing operations. +* The specified viewport is used to clip the rendering output to the boundaries of the rectangle. +* +* \param[in] canvas The Tvg_Canvas object containing elements which were drawn. +* \param[in] x The x-coordinate of the upper-left corner of the rectangle. +* \param[in] y The y-coordinate of the upper-left corner of the rectangle. +* \param[in] w The width of the rectangle. +* \param[in] h The height of the rectangle. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. +* +* \warning It's not allowed to change the viewport during tvg_canvas_update() - tvg_canvas_sync() or tvg_canvas_push() - tvg_canvas_sync(). +* +* \note When resetting the target, the viewport will also be reset to the target size. +* \note Experimental API +* \see tvg_swcanvas_set_target() +*/ +TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h); + /** \} */ // end defgroup ThorVGCapi_Canvas @@ -989,7 +1015,7 @@ TVG_API Tvg_Result tvg_paint_get_identifier(const Tvg_Paint* paint, Tvg_Identifi * \return Tvg_Result enumeration. * \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. * - * @BETA_API + * @note Experimental API */ TVG_API Tvg_Result tvg_paint_set_blend_method(const Tvg_Paint* paint, Tvg_Blend_Method method); @@ -1007,7 +1033,7 @@ TVG_API Tvg_Result tvg_paint_set_blend_method(const Tvg_Paint* paint, Tvg_Blend_ * \return Tvg_Result enumeration. * \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. * - * @BETA_API + * @note Experimental API */ TVG_API Tvg_Result tvg_paint_get_blend_method(const Tvg_Paint* paint, Tvg_Blend_Method* method); @@ -1962,6 +1988,10 @@ TVG_API Tvg_Paint* tvg_picture_new(void); /*! * \brief Loads a picture data directly from a file. * +* ThorVG efficiently caches the loaded data using the specified @p path as a key. +* This means that loading the same file again will not result in duplicate operations; +* instead, ThorVG will reuse the previously loaded picture data. +* * \param[in] paint A Tvg_Paint pointer to the picture object. * \param[in] path The absolute path to the image file. * @@ -1977,6 +2007,17 @@ TVG_API Tvg_Result tvg_picture_load(Tvg_Paint* paint, const char* path); /*! * \brief Loads a picture data from a memory block of a given size. * +* ThorVG efficiently caches the loaded data using the specified @p data address as a key +* when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations +* for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. +* +* \param[in] paint A Tvg_Paint pointer to the picture object. +* \param[in] data A pointer to a memory location where the content of the picture raw data is stored. +* \param[in] w The width of the image @p data in pixels. +* \param[in] h The height of the image @p data in pixels. +* \param[in] premultiplied If @c true, the given image data is alpha-premultiplied. +* \param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. +* * \return Tvg_Result enumeration. * \retval TVG_RESULT_SUCCESS Succeed. * \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer or no data are provided or the @p width or @p height value is zero or less. @@ -1991,6 +2032,10 @@ TVG_API Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uint32 /*! * \brief Loads a picture data from a memory block of a given size. * +* ThorVG efficiently caches the loaded data using the specified @p data address as a key +* when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations +* for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data. +* * \param[in] paint A Tvg_Paint pointer to the picture object. * \param[in] data A pointer to a memory location where the content of the picture file is stored. * \param[in] size The size in bytes of the memory occupied by the @p data. @@ -2219,18 +2264,20 @@ TVG_API Tvg_Result tvg_saver_del(Tvg_Saver* saver); /************************************************************************/ /*! -* \brief Creates a new Animation object. (BETA_API) +* \brief Creates a new Animation object. * * \return Tvg_Animation A new Tvg_Animation object. +* +* \since 0.13 */ TVG_API Tvg_Animation* tvg_animation_new(void); /*! -* \brief Specifies the current frame in the animation. (BETA_API) +* \brief Specifies the current frame in the animation. * * \param[in] animation A Tvg_Animation pointer to the animation object. -* \param[in] no The index of the animation frame to be displayed. The index should be less than the tvg_animatio_total_frame(). +* \param[in] no The index of the animation frame to be displayed. The index should be less than the tvg_animation_total_frame(). * * \return Tvg_Result enumeration. * \retval TVG_RESULT_SUCCESS Succeed. @@ -2238,13 +2285,18 @@ TVG_API Tvg_Animation* tvg_animation_new(void); * \retval TVG_RESULT_INSUFFICIENT_CONDITION No animatable data loaded from the Picture. * \retval TVG_RESULT_NOT_SUPPORTED The picture data does not support animations. * +* \note For efficiency, ThorVG ignores updates to the new frame value if the difference from the current frame value +* is less than 0.001. In such cases, it returns @c Result::InsufficientCondition. +* Values less than 0.001 may be disregarded and may not be accurately retained by the Animation. * \see tvg_animation_get_total_frame() +* +* \since 0.13 */ -TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, uint32_t no); +TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, float no); /*! -* \brief Retrieves a picture instance associated with this animation instance. (BETA_API) +* \brief Retrieves a picture instance associated with this animation instance. * * This function provides access to the picture instance that can be used to load animation formats, such as Lottie(json). * After setting up the picture, it can be pushed to the designated canvas, enabling control over animation frames @@ -2255,12 +2307,14 @@ TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, uint32_t no * \return A picture instance that is tied to this animation. * * \warning The picture instance is owned by Animation. It should not be deleted manually. +* +* \since 0.13 */ TVG_API Tvg_Paint* tvg_animation_get_picture(Tvg_Animation* animation); /*! -* \brief Retrieves the current frame number of the animation. (BETA_API) +* \brief Retrieves the current frame number of the animation. * * \param[in] animation A Tvg_Animation pointer to the animation object. * \param[in] no The current frame number of the animation, between 0 and totalFrame() - 1. @@ -2271,12 +2325,14 @@ TVG_API Tvg_Paint* tvg_animation_get_picture(Tvg_Animation* animation); * * \see tvg_animation_get_total_frame() * \see tvg_animation_set_frame() +* +* \since 0.13 */ -TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, uint32_t* no); +TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, float* no); /*! -* \brief Retrieves the total number of frames in the animation. (BETA_API) +* \brief Retrieves the total number of frames in the animation. * * \param[in] animation A Tvg_Animation pointer to the animation object. * \param[in] cnt The total number of frames in the animation. @@ -2287,12 +2343,14 @@ TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, uint32_t* n * * \note Frame numbering starts from 0. * \note If the Picture is not properly configured, this function will return 0. +* +* \since 0.13 */ -TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, uint32_t* cnt); +TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, float* cnt); /*! -* \brief Retrieves the duration of the animation in seconds. (BETA_API) +* \brief Retrieves the duration of the animation in seconds. * * \param[in] animation A Tvg_Animation pointer to the animation object. * \param[in] duration The duration of the animation in seconds. @@ -2302,10 +2360,44 @@ TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, uint3 * \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer or @p duration. * * \note If the Picture is not properly configured, this function will return 0. +* +* \since 0.13 */ TVG_API Tvg_Result tvg_animation_get_duration(Tvg_Animation* animation, float* duration); +/*! +* \brief Specifies the playback segment of the animation. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the animation object. +* \param[in] begin segment begin. +* \param[in] end segment end. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given parameters are out of range. +* +* \since 0.13 +*/ +TVG_API Tvg_Result tvg_animation_set_segment(Tvg_Animation* animation, float begin, float end); + + +/*! +* \brief Gets the current segment. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the animation object. +* \param[out] begin segment begin. +* \param[out] end segment end. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given parameters are @c nullptr. +*/ +TVG_API Tvg_Result tvg_animation_get_segment(Tvg_Animation* animation, float* begin, float* end); + + /*! * \brief Deletes the given Tvg_Animation object. * @@ -2314,11 +2406,96 @@ TVG_API Tvg_Result tvg_animation_get_duration(Tvg_Animation* animation, float* d * \return Tvg_Result enumeration. * \retval TVG_RESULT_SUCCESS Succeed. * \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Animation pointer. +* +* \since 0.13 */ TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation); -/** \} */ // end defgroup ThorVG_CAPI +/** \} */ // end defgroup ThorVGCapi_Animation + + +/** +* \defgroup ThorVGCapi_LottieAnimation LottieAnimation +* \brief A module for manipulation of lottie extension features. +* +* The module enables control of advanced Lottie features. +* \{ +*/ + +/************************************************************************/ +/* LottieAnimation Extension API */ +/************************************************************************/ + +/*! +* \brief Creates a new LottieAnimation object. (Experimental API) +* +* \return Tvg_Animation A new Tvg_LottieAnimation object. +*/ +TVG_API Tvg_Animation* tvg_lottie_animation_new(void); + + +/*! +* \brief Override the lottie properties through the slot data. (Experimental API) +* +* \param[in] animation The Tvg_Animation object to override the property with the slot. +* \param[in] slot The Lottie slot data in json, or @c nullptr to reset. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given @p slot is invalid +* \retval TVG_RESULT_NOT_SUPPORTED The Lottie Animation is not supported. +*/ +TVG_API Tvg_Result tvg_lottie_animation_override(Tvg_Animation* animation, const char* slot); + + +/*! +* \brief Specifies a segment by marker. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the Lottie animation object. +* \param[in] marker The name of the segment marker. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION In case the animation is not loaded. +* \retval TVG_RESULT_INVALID_ARGUMENT When the given @p marker is invalid. +* \retval TVG_RESULT_NOT_SUPPORTED The Lottie Animation is not supported. +*/ +TVG_API Tvg_Result tvg_lottie_animation_set_marker(Tvg_Animation* animation, const char* marker); + + +/*! +* \brief Gets the marker count of the animation. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the Lottie animation object. +* \param[out] cnt The count value of the markers. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. +*/ +TVG_API Tvg_Result tvg_lottie_animation_get_markers_cnt(Tvg_Animation* animation, uint32_t* cnt); + + +/*! +* \brief Gets the marker name by a given index. (Experimental API) +* +* \param[in] animation The Tvg_Animation pointer to the Lottie animation object. +* \param[in] idx The index of the animation marker, starts from 0. +* \param[out] name The name of marker when succeed. +* +* \return Tvg_Result enumeration. +* \retval TVG_RESULT_SUCCESS Succeed. +* \retval TVG_RESULT_INVALID_ARGUMENT In case @c nullptr is passed as the argument or @c idx is out of range. +*/ +TVG_API Tvg_Result tvg_lottie_animation_get_marker(Tvg_Animation* animation, uint32_t idx, const char** name); + + +/** \} */ // end addtogroup ThorVGCapi_LottieAnimation + + +/** \} */ // end defgroup ThorVGCapi #ifdef __cplusplus @@ -2329,6 +2506,3 @@ TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation); #endif /* LV_USE_THORVG_INTERNAL */ - -#endif /* LV_USE_THORVG_INTERNAL */ - diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_lottie.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_lottie.h new file mode 100644 index 000000000..b69410ae9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/thorvg_lottie.h @@ -0,0 +1,100 @@ +#ifndef _THORVG_LOTTIE_H_ +#define _THORVG_LOTTIE_H_ + +#include "thorvg.h" + +namespace tvg +{ + +/** + * @class LottieAnimation + * + * @brief The LottieAnimation class enables control of advanced Lottie features. + * + * This class extends the Animation and has additional interfaces. + * + * @see Animation + * + * @note Experimental API + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL +class TVG_API LottieAnimation final : public Animation +{ +public: + ~LottieAnimation(); + + /** + * @brief Override Lottie properties using slot data. + * + * @param[in] slot The Lottie slot data in JSON format to override, or @c nullptr to reset. + * + * @retval Result::Success When succeed. + * @retval Result::InsufficientCondition In case the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * + * @note Experimental API + */ + Result override(const char* slot) noexcept; + + /** + * @brief Specifies a segment by marker. + * + * Markers are used to control animation playback by specifying start and end points, + * eliminating the need to know the exact frame numbers. + * Generally, markers are designated at the design level, + * meaning the callers must know the marker name in advance to use it. + * + * @param[in] marker The name of the segment marker. + * + * @retval Result::Success When successful. + * @retval Result::InsufficientCondition If the animation is not loaded. + * @retval Result::InvalidArguments When the given parameter is invalid. + * @retval Result::NonSupport When it's not animatable. + * + * @note If a @c marker is specified, the previously set segment will be disregarded. + * @note Set @c nullptr to reset the specified segment. + * @see Animation::segment(float begin, float end) + * @note Experimental API + */ + Result segment(const char* marker) noexcept; + + /** + * @brief Gets the marker count of the animation. + * + * @retval The count of the markers, zero if there is no marker. + * + * @see LottieAnimation::marker() + * @note Experimental API + */ + uint32_t markersCnt() noexcept; + + /** + * @brief Gets the marker name by a given index. + * + * @param[in] idx The index of the animation marker, starts from 0. + * + * @retval The name of marker when succeed, @c nullptr otherwise. + * + * @see LottieAnimation::markersCnt() + * @note Experimental API + */ + const char* marker(uint32_t idx) noexcept; + + /** + * @brief Creates a new LottieAnimation object. + * + * @return A new LottieAnimation object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; +}; + +} //namespace + +#endif //_THORVG_LOTTIE_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAccessor.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAccessor.cpp new file mode 100644 index 000000000..e1f8608db --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAccessor.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgIteratorAccessor.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static bool accessChildren(Iterator* it, function func) +{ + while (auto child = it->next()) { + //Access the child + if (!func(child)) return false; + + //Access the children of the child + if (auto it2 = IteratorAccessor::iterator(child)) { + if (!accessChildren(it2, func)) { + delete(it2); + return false; + } + delete(it2); + } + } + return true; +} + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +unique_ptr Accessor::set(unique_ptr picture, function func) noexcept +{ + auto p = picture.get(); + if (!p || !func) return picture; + + //Use the Preorder Tree-Search + + //Root + if (!func(p)) return picture; + + //Children + if (auto it = IteratorAccessor::iterator(p)) { + accessChildren(it, func); + delete(it); + } + return picture; +} + + +Accessor::~Accessor() +{ + +} + + +Accessor::Accessor() : pImpl(nullptr) +{ + +} + + +unique_ptr Accessor::gen() noexcept +{ + return unique_ptr(new Accessor); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.cpp index ae5e8f94e..399ee4589 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,33 +23,13 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#include "tvgCommon.h" #include "tvgFrameModule.h" -#include "tvgPaint.h" -#include "tvgPicture.h" +#include "tvgAnimation.h" /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -struct Animation::Impl -{ - Picture* picture = nullptr; - - Impl() - { - picture = Picture::gen().release(); - PP(picture)->ref(); - } - - ~Impl() - { - if (PP(picture)->unref() == 0) { - delete(picture); - } - } -}; - /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -65,9 +45,9 @@ Animation::Animation() : pImpl(new Impl) } -Result Animation::frame(uint32_t no) noexcept +Result Animation::frame(float no) noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return Result::InsufficientCondition; if (!loader->animatable()) return Result::NonSupport; @@ -83,9 +63,9 @@ Picture* Animation::picture() const noexcept } -uint32_t Animation::curFrame() const noexcept +float Animation::curFrame() const noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return 0; if (!loader->animatable()) return 0; @@ -94,9 +74,9 @@ uint32_t Animation::curFrame() const noexcept } -uint32_t Animation::totalFrame() const noexcept +float Animation::totalFrame() const noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return 0; if (!loader->animatable()) return 0; @@ -107,7 +87,7 @@ uint32_t Animation::totalFrame() const noexcept float Animation::duration() const noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return 0; if (!loader->animatable()) return 0; @@ -116,6 +96,33 @@ float Animation::duration() const noexcept } +Result Animation::segment(float begin, float end) noexcept +{ + if (begin < 0.0 || end > 1.0 || begin >= end) return Result::InvalidArguments; + + auto loader = pImpl->picture->pImpl->loader; + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + + static_cast(loader)->segment(begin, end); + + return Result::Success; +} + + +Result Animation::segment(float *begin, float *end) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + if (!begin && !end) return Result::InvalidArguments; + + static_cast(loader)->segment(begin, end); + + return Result::Success; +} + + unique_ptr Animation::gen() noexcept { return unique_ptr(new Animation); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.h new file mode 100644 index 000000000..d0b456716 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgAnimation.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_ANIMATION_H_ +#define _TVG_ANIMATION_H_ + +#include "tvgCommon.h" +#include "tvgPaint.h" +#include "tvgPicture.h" + +struct Animation::Impl +{ + Picture* picture = nullptr; + + Impl() + { + picture = Picture::gen().release(); + PP(picture)->ref(); + } + + ~Impl() + { + if (PP(picture)->unref() == 0) { + delete(picture); + } + } +}; + +#endif //_TVG_ANIMATION_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgArray.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgArray.h index 41accc13b..33cd55ba2 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgArray.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgArray.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +28,7 @@ #include #include +#include namespace tvg { @@ -41,6 +42,11 @@ struct Array Array(){} + Array(int32_t size) + { + reserve(size); + } + Array(const Array& rhs) { reset(); @@ -58,6 +64,7 @@ struct Array void push(Array& rhs) { + if (rhs.count == 0) return; grow(rhs.count); memcpy(data + count, rhs.data, rhs.count * sizeof(T)); count += rhs.count; @@ -87,6 +94,16 @@ struct Array return data[idx]; } + const T* begin() const + { + return data; + } + + T* begin() + { + return data; + } + T* end() { return data + count; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBinaryDesc.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBinaryDesc.h new file mode 100644 index 000000000..add8b081a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBinaryDesc.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_BINARY_DESC_H_ +#define _TVG_BINARY_DESC_H_ + +/* TODO: Need to consider whether uin8_t is enough size for extension... + Rather than optimal data, we can use enough size and data compress? */ + +using TvgBinByte = uint8_t; +using TvgBinCounter = uint32_t; +using TvgBinTag = TvgBinByte; +using TvgBinFlag = TvgBinByte; + + +//Header +#define TVG_HEADER_SIZE 33 //TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH + 2*SIZE(float) + TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE +#define TVG_HEADER_SIGNATURE "ThorVG" +#define TVG_HEADER_SIGNATURE_LENGTH 6 +#define TVG_HEADER_VERSION "001200" //Major 00, Minor 12, Micro 00 +#define TVG_HEADER_VERSION_LENGTH 6 +#define TVG_HEADER_RESERVED_LENGTH 1 //Storing flags for extensions +#define TVG_HEADER_COMPRESS_SIZE 12 //TVG_HEADER_UNCOMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE_BITS +//Compress Size +#define TVG_HEADER_UNCOMPRESSED_SIZE 4 //SIZE (TvgBinCounter) +#define TVG_HEADER_COMPRESSED_SIZE 4 //SIZE (TvgBinCounter) +#define TVG_HEADER_COMPRESSED_SIZE_BITS 4 //SIZE (TvgBinCounter) +//Reserved Flag +#define TVG_HEAD_FLAG_COMPRESSED 0x01 + +//Paint Type +#define TVG_TAG_CLASS_PICTURE (TvgBinTag)0xfc +#define TVG_TAG_CLASS_SHAPE (TvgBinTag)0xfd +#define TVG_TAG_CLASS_SCENE (TvgBinTag)0xfe + + +//Paint +#define TVG_TAG_PAINT_OPACITY (TvgBinTag)0x10 +#define TVG_TAG_PAINT_TRANSFORM (TvgBinTag)0x11 +#define TVG_TAG_PAINT_CMP_TARGET (TvgBinTag)0x01 +#define TVG_TAG_PAINT_CMP_METHOD (TvgBinTag)0x20 + + +//TODO: Keep this for the compatibility, Remove in TVG 1.0 release +//Scene + #define TVG_TAG_SCENE_RESERVEDCNT (TvgBinTag)0x30 + + +//Shape +#define TVG_TAG_SHAPE_PATH (TvgBinTag)0x40 +#define TVG_TAG_SHAPE_STROKE (TvgBinTag)0x41 +#define TVG_TAG_SHAPE_FILL (TvgBinTag)0x42 +#define TVG_TAG_SHAPE_COLOR (TvgBinTag)0x43 +#define TVG_TAG_SHAPE_FILLRULE (TvgBinTag)0x44 + + +//Stroke +#define TVG_TAG_SHAPE_STROKE_CAP (TvgBinTag)0x50 +#define TVG_TAG_SHAPE_STROKE_JOIN (TvgBinTag)0x51 +#define TVG_TAG_SHAPE_STROKE_WIDTH (TvgBinTag)0x52 +#define TVG_TAG_SHAPE_STROKE_COLOR (TvgBinTag)0x53 +#define TVG_TAG_SHAPE_STROKE_FILL (TvgBinTag)0x54 +#define TVG_TAG_SHAPE_STROKE_DASHPTRN (TvgBinTag)0x55 +#define TVG_TAG_SHAPE_STROKE_MITERLIMIT (TvgBinTag)0x56 +#define TVG_TAG_SHAPE_STROKE_ORDER (TvgBinTag)0x57 +#define TVG_TAG_SHAPE_STROKE_DASH_OFFSET (TvgBinTag)0x58 + + +//Fill +#define TVG_TAG_FILL_LINEAR_GRADIENT (TvgBinTag)0x60 +#define TVG_TAG_FILL_RADIAL_GRADIENT (TvgBinTag)0x61 +#define TVG_TAG_FILL_COLORSTOPS (TvgBinTag)0x62 +#define TVG_TAG_FILL_FILLSPREAD (TvgBinTag)0x63 +#define TVG_TAG_FILL_TRANSFORM (TvgBinTag)0x64 +#define TVG_TAG_FILL_RADIAL_GRADIENT_FOCAL (TvgBinTag)0x65 + +//Picture +#define TVG_TAG_PICTURE_RAW_IMAGE (TvgBinTag)0x70 +#define TVG_TAG_PICTURE_MESH (TvgBinTag)0x71 + +#endif //_TVG_BINARY_DESC_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.cpp index 4da0e5e12..22a97c20d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -66,9 +66,9 @@ Result Canvas::clear(bool free) noexcept Result Canvas::draw() noexcept { - TVGLOG("COMMON", "Draw S. -------------------------------- Canvas(%p)", this); + TVGLOG("RENDERER", "Draw S. -------------------------------- Canvas(%p)", this); auto ret = pImpl->draw(); - TVGLOG("COMMON", "Draw E. -------------------------------- Canvas(%p)", this); + TVGLOG("RENDERER", "Draw E. -------------------------------- Canvas(%p)", this); return ret; } @@ -76,14 +76,20 @@ Result Canvas::draw() noexcept Result Canvas::update(Paint* paint) noexcept { - TVGLOG("COMMON", "Update S. ------------------------------ Canvas(%p)", this); + TVGLOG("RENDERER", "Update S. ------------------------------ Canvas(%p)", this); auto ret = pImpl->update(paint, false); - TVGLOG("COMMON", "Update E. ------------------------------ Canvas(%p)", this); + TVGLOG("RENDERER", "Update E. ------------------------------ Canvas(%p)", this); return ret; } +Result Canvas::viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept +{ + return pImpl->viewport(x, y, w, h); +} + + Result Canvas::sync() noexcept { return pImpl->sync(); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.h index 852f7db43..171f6aaea 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCanvas.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,36 +23,51 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#ifndef _TVG_CANVAS_IMPL_H_ -#define _TVG_CANVAS_IMPL_H_ +#ifndef _TVG_CANVAS_H_ +#define _TVG_CANVAS_H_ #include "tvgPaint.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct Canvas::Impl { + enum Status : uint8_t {Synced = 0, Updating, Drawing}; + list paints; RenderMethod* renderer; - bool refresh = false; //if all paints should be updated by force. - bool drawing = false; //on drawing condition? + RenderRegion vport = {0, 0, INT32_MAX, INT32_MAX}; + Status status = Status::Synced; - Impl(RenderMethod* pRenderer):renderer(pRenderer) + bool refresh = false; //if all paints should be updated by force. + + Impl(RenderMethod* pRenderer) : renderer(pRenderer) { + renderer->ref(); } ~Impl() { - clear(true); - delete(renderer); + //make it sure any deferred jobs + renderer->sync(); + renderer->clear(); + + clearPaints(); + + if (renderer->unref() == 0) delete(renderer); + } + + void clearPaints() + { + for (auto paint : paints) { + if (P(paint)->unref() == 0) delete(paint); + } + paints.clear(); } Result push(unique_ptr paint) { - //You can not push paints during rendering. - if (drawing) return Result::InsufficientCondition; + //You cannot push paints during rendering. + if (status == Status::Drawing) return Result::InsufficientCondition; auto p = paint.release(); if (!p) return Result::MemoryCorruption; @@ -65,19 +80,12 @@ struct Canvas::Impl Result clear(bool free) { //Clear render target before drawing - if (!renderer || !renderer->clear()) return Result::InsufficientCondition; + if (!renderer->clear()) return Result::InsufficientCondition; //Free paints - if (free) { - for (auto paint : paints) { - P(paint)->unref(); - if (paint->pImpl->dispose(*renderer) && P(paint)->refCnt == 0) { - delete(paint); - } - } - paints.clear(); - } - drawing = false; + if (free) clearPaints(); + + status = Status::Synced; return Result::Success; } @@ -89,64 +97,69 @@ struct Canvas::Impl Result update(Paint* paint, bool force) { - if (paints.empty() || drawing || !renderer) return Result::InsufficientCondition; + if (paints.empty() || status == Status::Drawing) return Result::InsufficientCondition; Array clips; auto flag = RenderUpdateFlag::None; if (refresh || force) flag = RenderUpdateFlag::All; - //Update single paint node if (paint) { - //Optimize Me: Can we skip the searching? - for (auto paint2 : paints) { - if (paint2 == paint) { - paint->pImpl->update(*renderer, nullptr, clips, 255, flag); - return Result::Success; - } - } - return Result::InvalidArguments; - //Update all retained paint nodes + paint->pImpl->update(renderer, nullptr, clips, 255, flag); } else { for (auto paint : paints) { - paint->pImpl->update(*renderer, nullptr, clips, 255, flag); + paint->pImpl->update(renderer, nullptr, clips, 255, flag); } + refresh = false; } - - refresh = false; - + status = Status::Updating; return Result::Success; } Result draw() { - if (drawing || paints.empty() || !renderer || !renderer->preRender()) return Result::InsufficientCondition; + if (status == Status::Drawing || paints.empty() || !renderer->preRender()) return Result::InsufficientCondition; bool rendered = false; for (auto paint : paints) { - if (paint->pImpl->render(*renderer)) rendered = true; + if (paint->pImpl->render(renderer)) rendered = true; } if (!rendered || !renderer->postRender()) return Result::InsufficientCondition; - drawing = true; - + status = Status::Drawing; return Result::Success; } Result sync() { - if (!drawing) return Result::InsufficientCondition; + if (status == Status::Synced) return Result::InsufficientCondition; if (renderer->sync()) { - drawing = false; + status = Status::Synced; return Result::Success; } return Result::InsufficientCondition; } + + Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) + { + if (status != Status::Synced) return Result::InsufficientCondition; + RenderRegion val = {x, y, w, h}; + //intersect if the target buffer is already set. + auto surface = renderer->mainSurface(); + if (surface && surface->w > 0 && surface->h > 0) { + val.intersect({0, 0, (int32_t)surface->w, (int32_t)surface->h}); + } + if (vport == val) return Result::Success; + renderer->viewport(val); + vport = val; + needRefresh(); + return Result::Success; + } }; -#endif /* _TVG_CANVAS_IMPL_H_ */ +#endif /* _TVG_CANVAS_H_ */ #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCapi.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCapi.cpp index 203a11d09..1720d5088 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCapi.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCapi.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,9 +23,13 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL +#include "config.h" #include #include "thorvg.h" #include "thorvg_capi.h" +#ifdef THORVG_LOTTIE_LOADER_SUPPORT +#include "thorvg_lottie.h" +#endif using namespace std; using namespace tvg; @@ -34,6 +38,7 @@ using namespace tvg; extern "C" { #endif + /************************************************************************/ /* Engine API */ /************************************************************************/ @@ -109,6 +114,13 @@ TVG_API Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas) } +TVG_API Tvg_Result tvg_canvas_est_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->viewport(x, y, w, h); +} + + TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint) { if (!canvas || !paint) return TVG_RESULT_INVALID_ARGUMENT; @@ -129,6 +141,12 @@ TVG_API Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas) return (Tvg_Result) reinterpret_cast(canvas)->sync(); } +TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_t y, int32_t w, int32_t h) +{ + if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(canvas)->viewport(x, y, w, h); +} + /************************************************************************/ /* Paint API */ @@ -730,15 +748,14 @@ TVG_API Tvg_Animation* tvg_animation_new() } -TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, uint32_t no) +TVG_API Tvg_Result tvg_animation_set_frame(Tvg_Animation* animation, float no) { - return TVG_RESULT_INVALID_ARGUMENT; -// if (!animation) return TVG_RESULT_INVALID_ARGUMENT; -// return (Tvg_Result) reinterpret_cast(animation)->frame(no); + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->frame(no); } -TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, uint32_t* no) +TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, float* no) { if (!animation || !no) return TVG_RESULT_INVALID_ARGUMENT; *no = reinterpret_cast(animation)->curFrame(); @@ -746,7 +763,7 @@ TVG_API Tvg_Result tvg_animation_get_frame(Tvg_Animation* animation, uint32_t* n } -TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, uint32_t* cnt) +TVG_API Tvg_Result tvg_animation_get_total_frame(Tvg_Animation* animation, float* cnt) { if (!animation || !cnt) return TVG_RESULT_INVALID_ARGUMENT; *cnt = reinterpret_cast(animation)->totalFrame(); @@ -769,6 +786,20 @@ TVG_API Tvg_Result tvg_animation_get_duration(Tvg_Animation* animation, float* d } +TVG_API Tvg_Result tvg_animation_set_segment(Tvg_Animation* animation, float start, float end) +{ + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->segment(start, end); +} + + +TVG_API Tvg_Result tvg_animation_get_segment(Tvg_Animation* animation, float* start, float* end) +{ + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->segment(start, end); +} + + TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation) { if (!animation) return TVG_RESULT_INVALID_ARGUMENT; @@ -776,6 +807,62 @@ TVG_API Tvg_Result tvg_animation_del(Tvg_Animation* animation) return TVG_RESULT_SUCCESS; } + +/************************************************************************/ +/* Lottie Animation API */ +/************************************************************************/ + +TVG_API Tvg_Animation* tvg_lottie_animation_new() +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + return (Tvg_Animation*) LottieAnimation::gen().release(); +#endif + return nullptr; +} + + +TVG_API Tvg_Result tvg_lottie_animation_override(Tvg_Animation* animation, const char* slot) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->override(slot); +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_lottie_animation_set_marker(Tvg_Animation* animation, const char* marker) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation) return TVG_RESULT_INVALID_ARGUMENT; + return (Tvg_Result) reinterpret_cast(animation)->segment(marker); +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_lottie_animation_get_markers_cnt(Tvg_Animation* animation, uint32_t* cnt) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation || !cnt) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(animation)->markersCnt(); + return TVG_RESULT_SUCCESS; +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + + +TVG_API Tvg_Result tvg_lottie_animation_get_marker(Tvg_Animation* animation, uint32_t idx, const char** name) +{ +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + if (!animation || !name) return TVG_RESULT_INVALID_ARGUMENT; + *name = reinterpret_cast(animation)->marker(idx); + if (!(*name)) return TVG_RESULT_INVALID_ARGUMENT; + return TVG_RESULT_SUCCESS; +#endif + return TVG_RESULT_NOT_SUPPORTED; +} + #ifdef __cplusplus } #endif diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCommon.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCommon.h index d70681170..d22c893fe 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCommon.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -64,8 +64,9 @@ using namespace tvg; #define TVG_CLASS_ID_PICTURE 3 #define TVG_CLASS_ID_LINEAR 4 #define TVG_CLASS_ID_RADIAL 5 +#define TVG_CLASS_ID_TEXT 6 -enum class FileType { Tvg = 0, Svg, Lottie, Raw, Png, Jpg, Webp, Unknown }; +enum class FileType { Png = 0, Jpg, Webp, Tvg, Svg, Lottie, Ttf, Raw, Gif, Unknown }; using Size = Point; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.cpp index 20941712f..d0c7c4ecb 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -461,11 +461,11 @@ size_t b64Decode(const char* encoded, const size_t len, char** decoded) auto value2 = B64_INDEX[(size_t)encoded[1]]; output[idx++] = (value1 << 2) + ((value2 & 0x30) >> 4); - if (!encoded[2] || encoded[2] == '=' || encoded[2] == '.') break; + if (!encoded[2] || encoded[3] < 0 || encoded[2] == '=' || encoded[2] == '.') break; auto value3 = B64_INDEX[(size_t)encoded[2]]; output[idx++] = ((value2 & 0x0f) << 4) + ((value3 & 0x3c) >> 2); - if (!encoded[3] || encoded[3] == '=' || encoded[3] == '.') break; + if (!encoded[3] || encoded[3] < 0 || encoded[3] == '=' || encoded[3] == '.') break; auto value4 = B64_INDEX[(size_t)encoded[3]]; output[idx++] = ((value3 & 0x03) << 6) + value4; encoded += 4; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.h index 6d9dfce1b..11e5fb39a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgCompressor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.cpp index 152883445..76d678fe0 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.h index 159540398..e6d776f92 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFill.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFrameModule.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFrameModule.h index 726b84c84..02e69a87a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFrameModule.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgFrameModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,17 +31,32 @@ namespace tvg { -class FrameModule: public LoadModule +class FrameModule: public ImageLoader { public: + float segmentBegin = 0.0f; + float segmentEnd = 1.0f; + + FrameModule(FileType type) : ImageLoader(type) {} virtual ~FrameModule() {} - virtual bool frame(uint32_t frameNo) = 0; //set the current frame number - - virtual uint32_t totalFrame() = 0; //return the total frame count - virtual uint32_t curFrame() = 0; //return the current frame number + virtual bool frame(float no) = 0; //set the current frame number + virtual float totalFrame() = 0; //return the total frame count + virtual float curFrame() = 0; //return the current frame number virtual float duration() = 0; //return the animation duration in seconds + void segment(float* begin, float* end) + { + if (begin) *begin = segmentBegin; + if (end) *end = segmentEnd; + } + + void segment(float begin, float end) + { + segmentBegin = begin; + segmentEnd = end; + } + virtual bool animatable() override { return true; } }; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgGlCanvas.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgGlCanvas.cpp new file mode 100644 index 000000000..d246ea551 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgGlCanvas.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCanvas.h" + +#ifdef THORVG_GL_RASTER_SUPPORT + #include "tvgGlRenderer.h" +#else + class GlRenderer : public RenderMethod + { + //Non Supported. Dummy Class */ + }; +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct GlCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_GL_RASTER_SUPPORT +GlCanvas::GlCanvas() : Canvas(GlRenderer::gen()), pImpl(new Impl) +#else +GlCanvas::GlCanvas() : Canvas(nullptr), pImpl(new Impl) +#endif +{ +} + + + +GlCanvas::~GlCanvas() +{ + delete(pImpl); +} + + +Result GlCanvas::target(int32_t id, uint32_t w, uint32_t h) noexcept +{ +#ifdef THORVG_GL_RASTER_SUPPORT + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(id, w, h)) return Result::Unknown; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + + +unique_ptr GlCanvas::gen() noexcept +{ +#ifdef THORVG_GL_RASTER_SUPPORT + if (GlRenderer::init() <= 0) return nullptr; + return unique_ptr(new GlCanvas); +#endif + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInitializer.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInitializer.cpp index 66d260276..2506fd2b9 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInitializer.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInitializer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -167,6 +167,8 @@ Result Initializer::term(CanvasEngine engine) noexcept if (--_initCnt > 0) return Result::Success; + TaskScheduler::term(); + if (!LoaderMgr::term()) return Result::Unknown; return Result::Success; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInlist.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInlist.h new file mode 100644 index 000000000..eaedecce5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgInlist.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_INLIST_H_ +#define _TVG_INLIST_H_ + +namespace tvg { + +//NOTE: declare this in your list item +#define INLIST_ITEM(T) \ + T* prev; \ + T* next + +template +struct Inlist +{ + T* head = nullptr; + T* tail = nullptr; + + void free() + { + while (head) { + auto t = head; + head = t->next; + delete(t); + } + head = tail = nullptr; + } + + void back(T* element) + { + if (tail) { + tail->next = element; + element->prev = tail; + element->next = nullptr; + tail = element; + } else { + head = tail = element; + element->prev = nullptr; + element->next = nullptr; + } + } + + void front(T* element) + { + if (head) { + head->prev = element; + element->prev = nullptr; + element->next = head; + head = element; + } else { + head = tail = element; + element->prev = nullptr; + element->next = nullptr; + } + } + + T* back() + { + if (!tail) return nullptr; + auto t = tail; + tail = t->prev; + if (!tail) head = nullptr; + return t; + } + + T* front() + { + if (!head) return nullptr; + auto t = head; + head = t->next; + if (!head) tail = nullptr; + return t; + } + + void remove(T* element) + { + if (element->prev) element->prev->next = element->next; + if (element->next) element->next->prev = element->prev; + if (element == head) head = element->next; + if (element == tail) tail = element->prev; + } + + bool empty() + { + return head ? false : true; + } +}; + +} + +#endif // _TVG_INLIST_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgIteratorAccessor.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgIteratorAccessor.h index ac7015fe4..adc5f6ea8 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgIteratorAccessor.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgIteratorAccessor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBezier.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.cpp similarity index 77% rename from lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBezier.cpp rename to lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.cpp index e00fc1855..3bdab769e 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBezier.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,15 +24,15 @@ #if LV_USE_THORVG_INTERNAL #include "tvgMath.h" -#include "tvgBezier.h" +#include "tvgLines.h" -#define BEZIER_EPSILON 1e-4f +#define BEZIER_EPSILON 1e-2f /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -static float _lineLength(const Point& pt1, const Point& pt2) +static float _lineLengthApprox(const Point& pt1, const Point& pt2) { /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. With alpha = 1, beta = 3/8, giving results with the largest error less @@ -44,6 +44,59 @@ static float _lineLength(const Point& pt1, const Point& pt2) } +static float _lineLength(const Point& pt1, const Point& pt2) +{ + Point diff = {pt2.x - pt1.x, pt2.y - pt1.y}; + return sqrtf(diff.x * diff.x + diff.y * diff.y); +} + + +template +float _bezLength(const Bezier& cur, LengthFunc lineLengthFunc) +{ + Bezier left, right; + auto len = lineLengthFunc(cur.start, cur.ctrl1) + lineLengthFunc(cur.ctrl1, cur.ctrl2) + lineLengthFunc(cur.ctrl2, cur.end); + auto chord = lineLengthFunc(cur.start, cur.end); + + if (fabsf(len - chord) > BEZIER_EPSILON) { + tvg::bezSplit(cur, left, right); + return _bezLength(left, lineLengthFunc) + _bezLength(right, lineLengthFunc); + } + return len; +} + + +template +float _bezAt(const Bezier& bz, float at, float length, LengthFunc lineLengthFunc) +{ + auto biggest = 1.0f; + auto smallest = 0.0f; + auto t = 0.5f; + + //just in case to prevent an infinite loop + if (at <= 0) return 0.0f; + if (at >= length) return 1.0f; + + while (true) { + auto right = bz; + Bezier left; + bezSplitLeft(right, t, left); + length = _bezLength(left, lineLengthFunc); + if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) { + break; + } + if (length < at) { + smallest = t; + t = (t + biggest) * 0.5f; + } else { + biggest = t; + t = (smallest + t) * 0.5f; + } + } + return t; +} + + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -51,7 +104,26 @@ static float _lineLength(const Point& pt1, const Point& pt2) namespace tvg { -void bezSplit(const Bezier&cur, Bezier& left, Bezier& right) +float lineLength(const Point& pt1, const Point& pt2) +{ + return _lineLength(pt1, pt2); +} + + +void lineSplitAt(const Line& cur, float at, Line& left, Line& right) +{ + auto len = lineLength(cur.pt1, cur.pt2); + auto dx = ((cur.pt2.x - cur.pt1.x) / len) * at; + auto dy = ((cur.pt2.y - cur.pt1.y) / len) * at; + left.pt1 = cur.pt1; + left.pt2.x = left.pt1.x + dx; + left.pt2.y = left.pt1.y + dy; + right.pt1 = left.pt2; + right.pt2 = cur.pt2; +} + + +void bezSplit(const Bezier& cur, Bezier& left, Bezier& right) { auto c = (cur.ctrl1.x + cur.ctrl2.x) * 0.5f; left.ctrl1.x = (cur.start.x + cur.ctrl1.x) * 0.5f; @@ -75,15 +147,13 @@ void bezSplit(const Bezier&cur, Bezier& left, Bezier& right) float bezLength(const Bezier& cur) { - Bezier left, right; - auto len = _lineLength(cur.start, cur.ctrl1) + _lineLength(cur.ctrl1, cur.ctrl2) + _lineLength(cur.ctrl2, cur.end); - auto chord = _lineLength(cur.start, cur.end); + return _bezLength(cur, _lineLength); +} - if (fabsf(len - chord) > BEZIER_EPSILON) { - bezSplit(cur, left, right); - return bezLength(left) + bezLength(right); - } - return len; + +float bezLengthApprox(const Bezier& cur) +{ + return _bezLength(cur, _lineLengthApprox); } @@ -113,31 +183,13 @@ void bezSplitLeft(Bezier& cur, float at, Bezier& left) float bezAt(const Bezier& bz, float at, float length) { - auto biggest = 1.0f; - auto smallest = 0.0f; - auto t = 0.5f; + return _bezAt(bz, at, length, _lineLength); +} - //just in case to prevent an infinite loop - if (at <= 0) return 0.0f; - if (at >= length) return 1.0f; - while (true) { - auto right = bz; - Bezier left; - bezSplitLeft(right, t, left); - length = bezLength(left); - if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) { - break; - } - if (length < at) { - smallest = t; - t = (t + biggest) * 0.5f; - } else { - biggest = t; - t = (smallest + t) * 0.5f; - } - } - return t; +float bezAtApprox(const Bezier& bz, float at, float length) +{ + return _bezAt(bz, at, length, _lineLengthApprox); } @@ -189,11 +241,9 @@ float bezAngleAt(const Bezier& bz, float t) pt.x *= 3; pt.y *= 3; - return atan2(pt.x, pt.y) * 180.0f / 3.141592f; + return mathRad2Deg(atan2(pt.x, pt.y)); } - } #endif /* LV_USE_THORVG_INTERNAL */ - diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBezier.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.h similarity index 80% rename from lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBezier.h rename to lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.h index 24f70f336..804ced13a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgBezier.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,14 +23,24 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#ifndef _TVG_BEZIER_H_ -#define _TVG_BEZIER_H_ +#ifndef _TVG_LINES_H_ +#define _TVG_LINES_H_ #include "tvgCommon.h" namespace tvg { +struct Line +{ + Point pt1; + Point pt2; +}; + +float lineLength(const Point& pt1, const Point& pt2); +void lineSplitAt(const Line& cur, float at, Line& left, Line& right); + + struct Bezier { Point start; @@ -47,9 +57,10 @@ void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right); Point bezPointAt(const Bezier& bz, float t); float bezAngleAt(const Bezier& bz, float t); +float bezLengthApprox(const Bezier& cur); +float bezAtApprox(const Bezier& bz, float at, float length); } -#endif //_TVG_BEZIER_H_ +#endif //_TVG_LINES_H_ #endif /* LV_USE_THORVG_INTERNAL */ - diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoadModule.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoadModule.h index 7ccf94850..210995fcf 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoadModule.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoadModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,36 +27,85 @@ #define _TVG_LOAD_MODULE_H_ #include "tvgRender.h" +#include "tvgInlist.h" -namespace tvg + +struct LoadModule { + INLIST_ITEM(LoadModule); -class LoadModule -{ -public: - float w = 0, h = 0; //default image size - ColorSpace cs = ColorSpace::Unsupported; //must be clarified at open() + //Use either hashkey(data) or hashpath(path) + union { + uintptr_t hashkey; + char* hashpath = nullptr; + }; - virtual ~LoadModule() {} + FileType type; //current loader file type + uint16_t sharing = 0; //reference count + bool readied = false; //read done already. + bool pathcache = false; //cached by path + + LoadModule(FileType type) : type(type) {} + virtual ~LoadModule() + { + if (pathcache) free(hashpath); + } virtual bool open(const string& path) { return false; } virtual bool open(const char* data, uint32_t size, bool copy) { return false; } - virtual bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { return false; } - - //Override this if the vector-format has own resizing policy. virtual bool resize(Paint* paint, float w, float h) { return false; } - - virtual bool animatable() { return false; } //true if this loader supports animation. virtual void sync() {}; //finish immediately if any async update jobs. - virtual bool read() = 0; - virtual bool close() = 0; + virtual bool read() + { + if (readied) return false; + readied = true; + return true; + } - virtual unique_ptr bitmap() { return nullptr; } - virtual unique_ptr paint() { return nullptr; } + bool cached() + { + if (hashkey) return true; + return false; + } + + virtual bool close() + { + if (sharing == 0) return true; + --sharing; + return false; + } }; -} + +struct ImageLoader : LoadModule +{ + static ColorSpace cs; //desired value + + float w = 0, h = 0; //default image size + Surface surface; + + ImageLoader(FileType type) : LoadModule(type) {} + + virtual bool animatable() { return false; } //true if this loader supports animation. + virtual Paint* paint() { return nullptr; } + + virtual Surface* bitmap() + { + if (surface.data) return &surface; + return nullptr; + } +}; + + +struct FontLoader : LoadModule +{ + float scale = 1.0f; + + FontLoader(FileType type) : LoadModule(type) {} + + virtual bool request(Shape* shape, char* text, bool italic = false) = 0; +}; #endif //_TVG_LOAD_MODULE_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.cpp index 3a2cb32a4..8d1a3c58b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,11 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL +#include + +#include "tvgInlist.h" #include "tvgLoader.h" +#include "tvgLock.h" #ifdef THORVG_SVG_LOADER_SUPPORT #include "tvgSvgLoader.h" @@ -45,41 +49,35 @@ #include "tvgWebpLoader.h" #endif +#ifdef THORVG_TTF_LOADER_SUPPORT + #include "tvgTtfLoader.h" +#endif + #ifdef THORVG_LOTTIE_LOADER_SUPPORT #include "tvgLottieLoader.h" #endif #include "tvgRawLoader.h" + +uintptr_t HASH_KEY(const char* data) +{ + return reinterpret_cast(data); +} + /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ +ColorSpace ImageLoader::cs = ColorSpace::ARGB8888; + +static Key key; +static Inlist _activeLoaders; + + static LoadModule* _find(FileType type) { switch(type) { - case FileType::Tvg: { -#ifdef THORVG_TVG_LOADER_SUPPORT - return new TvgLoader; -#endif - break; - } - case FileType::Svg: { -#ifdef THORVG_SVG_LOADER_SUPPORT - return new SvgLoader; -#endif - break; - } - case FileType::Lottie: { -#ifdef THORVG_LOTTIE_LOADER_SUPPORT - return new LottieLoader; -#endif - break; - } - case FileType::Raw: { - return new RawLoader; - break; - } case FileType::Png: { #ifdef THORVG_PNG_LOADER_SUPPORT return new PngLoader; @@ -98,6 +96,34 @@ static LoadModule* _find(FileType type) #endif break; } + case FileType::Tvg: { +#ifdef THORVG_TVG_LOADER_SUPPORT + return new TvgLoader; +#endif + break; + } + case FileType::Svg: { +#ifdef THORVG_SVG_LOADER_SUPPORT + return new SvgLoader; +#endif + break; + } + case FileType::Ttf: { +#ifdef THORVG_TTF_LOADER_SUPPORT + return new TtfLoader; +#endif + break; + } + case FileType::Lottie: { +#ifdef THORVG_LOTTIE_LOADER_SUPPORT + return new LottieLoader; +#endif + break; + } + case FileType::Raw: { + return new RawLoader; + break; + } default: { break; } @@ -114,6 +140,10 @@ static LoadModule* _find(FileType type) format = "SVG"; break; } + case FileType::Ttf: { + format = "TTF"; + break; + } case FileType::Lottie: { format = "lottie(json)"; break; @@ -139,7 +169,7 @@ static LoadModule* _find(FileType type) break; } } - TVGLOG("LOADER", "%s format is not supported", format); + TVGLOG("RENDERER", "%s format is not supported", format); #endif return nullptr; } @@ -151,33 +181,74 @@ static LoadModule* _findByPath(const string& path) if (!ext.compare("tvg")) return _find(FileType::Tvg); if (!ext.compare("svg")) return _find(FileType::Svg); if (!ext.compare("json")) return _find(FileType::Lottie); - if (!ext.compare("lottie")) return _find(FileType::Lottie); if (!ext.compare("png")) return _find(FileType::Png); if (!ext.compare("jpg")) return _find(FileType::Jpg); if (!ext.compare("webp")) return _find(FileType::Webp); + if (!ext.compare("ttf") || !ext.compare("ttc")) return _find(FileType::Ttf); + if (!ext.compare("otf") || !ext.compare("otc")) return _find(FileType::Ttf); return nullptr; } -static LoadModule* _findByType(const string& mimeType) +static FileType _convert(const string& mimeType) { - if (mimeType.empty()) return nullptr; - auto type = FileType::Unknown; if (mimeType == "tvg") type = FileType::Tvg; else if (mimeType == "svg" || mimeType == "svg+xml") type = FileType::Svg; + else if (mimeType == "ttf" || mimeType == "otf") type = FileType::Ttf; else if (mimeType == "lottie") type = FileType::Lottie; else if (mimeType == "raw") type = FileType::Raw; else if (mimeType == "png") type = FileType::Png; else if (mimeType == "jpg" || mimeType == "jpeg") type = FileType::Jpg; else if (mimeType == "webp") type = FileType::Webp; - else { - TVGLOG("LOADER", "Given mimetype is unknown = \"%s\".", mimeType.c_str()); - return nullptr; - } + else TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType.c_str()); - return _find(type); + return type; +} + + +static LoadModule* _findByType(const string& mimeType) +{ + return _find(_convert(mimeType)); +} + + +static LoadModule* _findFromCache(const string& path) +{ + ScopedLock lock(key); + + auto loader = _activeLoaders.head; + + while (loader) { + if (loader->pathcache && !strcmp(loader->hashpath, path.c_str())) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; +} + + +static LoadModule* _findFromCache(const char* data, uint32_t size, const string& mimeType) +{ + auto type = _convert(mimeType); + if (type == FileType::Unknown) return nullptr; + + ScopedLock lock(key); + auto loader = _activeLoaders.head; + + auto key = HASH_KEY(data); + + while (loader) { + if (loader->type == type && loader->hashkey == key) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; } @@ -188,66 +259,181 @@ static LoadModule* _findByType(const string& mimeType) bool LoaderMgr::init() { - //TODO: - return true; } bool LoaderMgr::term() { - //TODO: + auto loader = _activeLoaders.head; + //clean up the remained font loaders which is globally used. + while (loader && loader->type == FileType::Ttf) { + auto ret = loader->close(); + auto tmp = loader; + loader = loader->next; + _activeLoaders.remove(tmp); + if (ret) delete(tmp); + } return true; } -shared_ptr LoaderMgr::loader(const string& path, bool* invalid) +bool LoaderMgr::retrieve(LoadModule* loader) +{ + if (!loader) return false; + if (loader->close()) { + if (loader->cached()) { + ScopedLock lock(key); + _activeLoaders.remove(loader); + } + delete(loader); + } + return true; +} + + +LoadModule* LoaderMgr::loader(const string& path, bool* invalid) { *invalid = false; + //TODO: lottie is not sharable. + auto allowCache = true; + auto ext = path.substr(path.find_last_of(".") + 1); + if (!ext.compare("json")) allowCache = false; + + if (allowCache) { + if (auto loader = _findFromCache(path)) return loader; + } + if (auto loader = _findByPath(path)) { - if (loader->open(path)) return shared_ptr(loader); - else delete(loader); - *invalid = true; + if (loader->open(path)) { + if (allowCache) { + loader->hashpath = strdup(path.c_str()); + loader->pathcache = true; + { + ScopedLock lock(key); + _activeLoaders.back(loader); + } + } + return loader; + } + delete(loader); + } + //Unknown MimeType. Try with the candidates in the order + for (int i = 0; i < static_cast(FileType::Raw); i++) { + if (auto loader = _find(static_cast(i))) { + if (loader->open(path)) { + if (allowCache) { + loader->hashpath = strdup(path.c_str()); + loader->pathcache = true; + { + ScopedLock lock(key); + _activeLoaders.back(loader); + } + } + return loader; + } + delete(loader); + } + } + *invalid = true; + return nullptr; +} + + +bool LoaderMgr::retrieve(const string& path) +{ + return retrieve(_findFromCache(path)); +} + + +LoadModule* LoaderMgr::loader(const char* key) +{ + auto loader = _activeLoaders.head; + + while (loader) { + if (loader->pathcache && strstr(loader->hashpath, key)) { + ++loader->sharing; + return loader; + } + loader = loader->next; } return nullptr; } -shared_ptr LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) +LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) { + //Note that users could use the same data pointer with the different content. + //Thus caching is only valid for shareable. + auto allowCache = !copy; + + //TODO: lottie is not sharable. + if (allowCache) { + auto type = _convert(mimeType); + if (type == FileType::Lottie) allowCache = false; + } + + if (allowCache) { + if (auto loader = _findFromCache(data, size, mimeType)) return loader; + } + //Try with the given MimeType if (!mimeType.empty()) { if (auto loader = _findByType(mimeType)) { if (loader->open(data, size, copy)) { - return shared_ptr(loader); + if (allowCache) { + loader->hashkey = HASH_KEY(data); + ScopedLock lock(key); + _activeLoaders.back(loader); + } + return loader; } else { TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str()); delete(loader); } } - //Unkown MimeType. Try with the candidates in the order - } else { - for (int i = 0; i < static_cast(FileType::Unknown); i++) { - auto loader = _find(static_cast(i)); - if (loader) { - if (loader->open(data, size, copy)) return shared_ptr(loader); - else delete(loader); + } + //Unknown MimeType. Try with the candidates in the order + for (int i = 0; i < static_cast(FileType::Raw); i++) { + auto loader = _find(static_cast(i)); + if (loader) { + if (loader->open(data, size, copy)) { + if (allowCache) { + loader->hashkey = HASH_KEY(data); + ScopedLock lock(key); + _activeLoaders.back(loader); + } + return loader; } + delete(loader); } } return nullptr; } -shared_ptr LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) +LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) { + //Note that users could use the same data pointer with the different content. + //Thus caching is only valid for shareable. + if (!copy) { + //TODO: should we check premultiplied?? + if (auto loader = _findFromCache((const char*)(data), w * h, "raw")) return loader; + } + //function is dedicated for raw images only auto loader = new RawLoader; - if (loader->open(data, w, h, copy)) return shared_ptr(loader); - else delete(loader); - + if (loader->open(data, w, h, copy)) { + if (!copy) { + loader->hashkey = HASH_KEY((const char*)data); + ScopedLock lock(key); + _activeLoaders.back(loader); + } + return loader; + } + delete(loader); return nullptr; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.h index 7acdc943a..50676990c 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,9 +32,12 @@ struct LoaderMgr { static bool init(); static bool term(); - static shared_ptr loader(const string& path, bool* invalid); - static shared_ptr loader(const char* data, uint32_t size, const string& mimeType, bool copy); - static shared_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static LoadModule* loader(const string& path, bool* invalid); + static LoadModule* loader(const char* data, uint32_t size, const string& mimeType, bool copy); + static LoadModule* loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static LoadModule* loader(const char* key); + static bool retrieve(const string& path); + static bool retrieve(LoadModule* loader); }; #endif //_TVG_LOADER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLock.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLock.h new file mode 100644 index 000000000..709c120e3 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLock.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOCK_H_ +#define _TVG_LOCK_H_ + +#ifdef THORVG_THREAD_SUPPORT + +#include + +namespace tvg { + + struct Key + { + std::mutex mtx; + }; + + struct ScopedLock + { + Key* key = nullptr; + + ScopedLock(Key& k) + { + k.mtx.lock(); + key = &k; + } + + ~ScopedLock() + { + key->mtx.unlock(); + } + }; + +} + +#else //THORVG_THREAD_SUPPORT + +namespace tvg { + + struct Key {}; + + struct ScopedLock + { + ScopedLock(Key& key) {} + }; + +} + +#endif //THORVG_THREAD_SUPPORT + +#endif //_TVG_LOCK_H_ + + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieAnimation.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieAnimation.cpp new file mode 100644 index 000000000..69818b37d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieAnimation.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCommon.h" +#include "thorvg_lottie.h" +#include "tvgLottieLoader.h" +#include "tvgAnimation.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LottieAnimation::~LottieAnimation() +{ +} + + +Result LottieAnimation::override(const char* slot) noexcept +{ + if (!pImpl->picture->pImpl->loader) return Result::InsufficientCondition; + + if (static_cast(pImpl->picture->pImpl->loader)->override(slot)) { + return Result::Success; + } + + return Result::InvalidArguments; +} + + +Result LottieAnimation::segment(const char* marker) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader) return Result::InsufficientCondition; + if (!loader->animatable()) return Result::NonSupport; + + if (!marker) { + static_cast(loader)->segment(0.0f, 1.0f); + return Result::Success; + } + + float begin, end; + if (!static_cast(loader)->segment(marker, begin, end)) { + return Result::InvalidArguments; + } + return static_cast(this)->segment(begin, end); +} + + +uint32_t LottieAnimation::markersCnt() noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader || !loader->animatable()) return 0; + return static_cast(loader)->markersCnt(); +} + + +const char* LottieAnimation::marker(uint32_t idx) noexcept +{ + auto loader = pImpl->picture->pImpl->loader; + if (!loader || !loader->animatable()) return nullptr; + return static_cast(loader)->markers(idx); +} + + +unique_ptr LottieAnimation::gen() noexcept +{ + return unique_ptr(new LottieAnimation); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.cpp new file mode 100644 index 000000000..82a43cfd2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.cpp @@ -0,0 +1,1378 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include + +#include "tvgCommon.h" +#include "tvgMath.h" +#include "tvgPaint.h" +#include "tvgShape.h" +#include "tvgInlist.h" +#include "tvgTaskScheduler.h" +#include "tvgLottieModel.h" +#include "tvgLottieBuilder.h" +#include "tvgLottieExpressions.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct RenderRepeater +{ + int cnt; + float offset; + Point position; + Point anchor; + Point scale; + float rotation; + uint8_t startOpacity; + uint8_t endOpacity; + bool interpOpacity; + bool inorder; +}; + + +struct RenderContext +{ + INLIST_ITEM(RenderContext); + + Shape* propagator = nullptr; + Shape* merging = nullptr; //merging shapes if possible (if shapes have same properties) + LottieObject** begin = nullptr; //iteration entry point + RenderRepeater* repeater = nullptr; + Matrix* transform = nullptr; + float roundness = 0.0f; + bool fragmenting = false; //render context has been fragmented by filling + bool reqFragment = false; //requirement to fragment the render context + bool ownPropagator = true; //this rendering context shares the propagator + + RenderContext() + { + propagator = Shape::gen().release(); + } + + ~RenderContext() + { + if (ownPropagator) delete(propagator); + delete(repeater); + free(transform); + } + + RenderContext(const RenderContext& rhs, bool mergeable = false) + { + if (mergeable) { + this->ownPropagator = false; + propagator = rhs.propagator; + merging = rhs.merging; + } else { + propagator = static_cast(rhs.propagator->duplicate()); + } + + if (rhs.repeater) { + repeater = new RenderRepeater(); + *repeater = *rhs.repeater; + } + roundness = rhs.roundness; + } +}; + + +static void _updateChildren(LottieGroup* parent, float frameNo, Inlist& contexts, LottieExpressions* exps); +static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps); +static bool _buildComposition(LottieComposition* comp, LottieGroup* parent); +static Shape* _draw(LottieGroup* parent, RenderContext* ctx); + +static void _rotateX(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + auto radian = mathDeg2Rad(degree); + m->e22 *= cosf(radian); +} + + +static void _rotateY(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + auto radian = mathDeg2Rad(degree); + m->e11 *= cosf(radian); +} + + +static void _rotationZ(Matrix* m, float degree) +{ + if (degree == 0.0f) return; + auto radian = mathDeg2Rad(degree); + m->e11 = cosf(radian); + m->e12 = -sinf(radian); + m->e21 = sinf(radian); + m->e22 = cosf(radian); +} + + +static void _skew(Matrix* m, float angleDeg, float axisDeg) +{ + auto angle = -mathDeg2Rad(angleDeg); + float tanVal = tanf(angle); + + axisDeg = fmod(axisDeg, 180.0f); + if (fabsf(axisDeg) < 0.01f || fabsf(axisDeg - 180.0f) < 0.01f || fabsf(axisDeg + 180.0f) < 0.01f) { + float cosVal = cosf(mathDeg2Rad(axisDeg)); + auto B = cosVal * cosVal * tanVal; + m->e12 += B * m->e11; + m->e22 += B * m->e21; + return; + } else if (fabsf(axisDeg - 90.0f) < 0.01f || fabsf(axisDeg + 90.0f) < 0.01f) { + float sinVal = -sinf(mathDeg2Rad(axisDeg)); + auto C = sinVal * sinVal * tanVal; + m->e11 -= C * m->e12; + m->e21 -= C * m->e22; + return; + } + + auto axis = -mathDeg2Rad(axisDeg); + float cosVal = cosf(axis); + float sinVal = sinf(axis); + auto A = sinVal * cosVal * tanVal; + auto B = cosVal * cosVal * tanVal; + auto C = sinVal * sinVal * tanVal; + + auto e11 = m->e11; + auto e21 = m->e21; + m->e11 = (1.0f - A) * e11 - C * m->e12; + m->e12 = B * e11 + (1.0f + A) * m->e12; + m->e21 = (1.0f - A) * e21 - C * m->e22; + m->e22 = B * e21 + (1.0f + A) * m->e22; +} + + +static bool _updateTransform(LottieTransform* transform, float frameNo, bool autoOrient, Matrix& matrix, uint8_t& opacity, LottieExpressions* exps) +{ + mathIdentity(&matrix); + + if (!transform) { + opacity = 255; + return false; + } + + if (transform->coords) { + mathTranslate(&matrix, transform->coords->x(frameNo), transform->coords->y(frameNo)); + } else { + auto position = transform->position(frameNo, exps); + mathTranslate(&matrix, position.x, position.y); + } + + auto angle = 0.0f; + if (autoOrient) angle = transform->position.angle(frameNo); + _rotationZ(&matrix, transform->rotation(frameNo, exps) + angle); + + if (transform->rotationEx) { + _rotateY(&matrix, transform->rotationEx->y(frameNo, exps)); + _rotateX(&matrix, transform->rotationEx->x(frameNo, exps)); + } + + auto skewAngle = transform->skewAngle(frameNo, exps); + if (skewAngle != 0.0f) { + // For angles where tangent explodes, the shape degenerates into an infinitely thin line. + // This is handled by zeroing out the matrix due to finite numerical precision. + skewAngle = fmod(skewAngle, 180.0f); + if (fabsf(skewAngle - 90.0f) < 0.01f || fabsf(skewAngle + 90.0f) < 0.01f) return false; + _skew(&matrix, skewAngle, transform->skewAxis(frameNo, exps)); + } + + auto scale = transform->scale(frameNo, exps); + mathScaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f); + + //Lottie specific anchor transform. + auto anchor = transform->anchor(frameNo, exps); + mathTranslateR(&matrix, -anchor.x, -anchor.y); + + //invisible just in case. + if (scale.x == 0.0f || scale.y == 0.0f) opacity = 0; + else opacity = transform->opacity(frameNo, exps); + + return true; +} + + +static void _updateTransform(LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + if (!layer || mathEqual(layer->cache.frameNo, frameNo)) return; + + auto transform = layer->transform; + auto parent = layer->parent; + + if (parent) _updateTransform(parent, frameNo, exps); + + auto& matrix = layer->cache.matrix; + + _updateTransform(transform, frameNo, layer->autoOrient, matrix, layer->cache.opacity, exps); + + if (parent) { + if (!mathIdentity((const Matrix*) &parent->cache.matrix)) { + if (mathIdentity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix; + else layer->cache.matrix = mathMultiply(&parent->cache.matrix, &matrix); + } + } + layer->cache.frameNo = frameNo; +} + + +static void _updateTransform(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto transform = static_cast(*child); + if (!transform) return; + + uint8_t opacity; + + if (parent->mergeable()) { + if (!ctx->transform) ctx->transform = (Matrix*)malloc(sizeof(Matrix)); + _updateTransform(transform, frameNo, false, *ctx->transform, opacity, exps); + return; + } + + ctx->merging = nullptr; + + Matrix matrix; + if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; + + auto pmatrix = PP(ctx->propagator)->transform(); + ctx->propagator->transform(pmatrix ? mathMultiply(pmatrix, &matrix) : matrix); + ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity)); + + //FIXME: preserve the stroke width. too workaround, need a better design. + if (P(ctx->propagator)->rs.strokeWidth() > 0.0f) { + auto denominator = sqrtf(matrix.e11 * matrix.e11 + matrix.e12 * matrix.e12); + if (denominator > 1.0f) ctx->propagator->stroke(ctx->propagator->strokeWidth() / denominator); + } +} + + +static void _updateGroup(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& pcontexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto group = static_cast(*child); + + if (group->children.empty()) return; + + //Prepare render data + group->scene = parent->scene; + group->reqFragment |= ctx->reqFragment; + + //generate a merging shape to consolidate partial shapes into a single entity + if (group->mergeable()) _draw(parent, ctx); + + Inlist contexts; + contexts.back(new RenderContext(*ctx, group->mergeable())); + + _updateChildren(group, frameNo, contexts, exps); + + contexts.free(); +} + + +static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext* ctx, LottieExpressions* exps) +{ + ctx->propagator->stroke(stroke->width(frameNo, exps)); + ctx->propagator->stroke(stroke->cap); + ctx->propagator->stroke(stroke->join); + ctx->propagator->strokeMiterlimit(stroke->miterLimit); + + if (stroke->dashattr) { + float dashes[2]; + dashes[0] = stroke->dashSize(frameNo, exps); + dashes[1] = dashes[0] + stroke->dashGap(frameNo, exps); + P(ctx->propagator)->strokeDash(dashes, 2, stroke->dashOffset(frameNo, exps)); + } else { + ctx->propagator->stroke(nullptr, 0); + } +} + + +static bool _fragmented(LottieObject** child, Inlist& contexts, RenderContext* ctx) +{ + if (!ctx->reqFragment) return false; + if (ctx->fragmenting) return true; + + contexts.back(new RenderContext(*ctx)); + auto fragment = contexts.tail; + fragment->begin = child - 1; + ctx->fragmenting = true; + + return false; +} + + +static void _updateSolidStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto stroke = static_cast(*child); + + ctx->merging = nullptr; + auto color = stroke->color(frameNo, exps); + ctx->propagator->stroke(color.rgb[0], color.rgb[1], color.rgb[2], stroke->opacity(frameNo, exps)); + _updateStroke(static_cast(stroke), frameNo, ctx, exps); +} + + +static void _updateGradientStroke(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto stroke = static_cast(*child); + + ctx->merging = nullptr; + ctx->propagator->stroke(unique_ptr(stroke->fill(frameNo, exps))); + _updateStroke(static_cast(stroke), frameNo, ctx, exps); +} + + +static void _updateSolidFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto fill = static_cast(*child); + + ctx->merging = nullptr; + auto color = fill->color(frameNo); + ctx->propagator->fill(color.rgb[0], color.rgb[1], color.rgb[2], fill->opacity(frameNo, exps)); + ctx->propagator->fill(fill->rule); + + if (ctx->propagator->strokeWidth() > 0) ctx->propagator->order(true); +} + + +static void _updateGradientFill(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + if (_fragmented(child, contexts, ctx)) return; + + auto fill = static_cast(*child); + + ctx->merging = nullptr; + //TODO: reuse the fill instance? + ctx->propagator->fill(unique_ptr(fill->fill(frameNo, exps))); + ctx->propagator->fill(fill->rule); + ctx->propagator->opacity(MULTIPLY(fill->opacity(frameNo), PP(ctx->propagator)->opacity)); + + if (ctx->propagator->strokeWidth() > 0) ctx->propagator->order(true); +} + + +static Shape* _draw(LottieGroup* parent, RenderContext* ctx) +{ + if (ctx->merging) return ctx->merging; + + auto shape = cast(ctx->propagator->duplicate()); + ctx->merging = shape.get(); + parent->scene->push(std::move(shape)); + + return ctx->merging; +} + + +//OPTIMIZE: path? +static void _repeat(LottieGroup* parent, unique_ptr path, RenderContext* ctx) +{ + auto repeater = ctx->repeater; + + Array shapes(repeater->cnt); + + for (int i = 0; i < repeater->cnt; ++i) { + auto multiplier = repeater->offset + static_cast(i); + + auto shape = static_cast(ctx->propagator->duplicate()); + P(shape)->rs.path = P(path.get())->rs.path; + + auto opacity = repeater->interpOpacity ? mathLerp(repeater->startOpacity, repeater->endOpacity, static_cast(i + 1) / repeater->cnt) : repeater->startOpacity; + shape->opacity(opacity); + + Matrix m; + mathIdentity(&m); + mathTranslate(&m, repeater->position.x * multiplier + repeater->anchor.x, repeater->position.y * multiplier + repeater->anchor.y); + mathScale(&m, powf(repeater->scale.x * 0.01f, multiplier), powf(repeater->scale.y * 0.01f, multiplier)); + mathRotate(&m, repeater->rotation * multiplier); + mathTranslateR(&m, -repeater->anchor.x, -repeater->anchor.y); + + auto pm = PP(shape)->transform(); + shape->transform(pm ? mathMultiply(&m, pm) : m); + + if (ctx->roundness > 1.0f && P(shape)->rs.stroke) { + TVGERR("LOTTIE", "FIXME: Path roundness should be applied properly!"); + P(shape)->rs.stroke->join = StrokeJoin::Round; + } + + shapes.push(shape); + } + + //push repeat shapes in order. + if (repeater->inorder) { + for (auto shape = shapes.begin(); shape < shapes.end(); ++shape) { + parent->scene->push(cast(*shape)); + } + } else { + for (auto shape = shapes.end() - 1; shape >= shapes.begin(); --shape) { + parent->scene->push(cast(*shape)); + } + } +} + + +static void _appendRect(Shape* shape, float x, float y, float w, float h, float r, Matrix* transform) +{ + //sharp rect + if (mathZero(r)) { + PathCommand commands[] = { + PathCommand::MoveTo, PathCommand::LineTo, PathCommand::LineTo, + PathCommand::LineTo, PathCommand::Close + }; + + Point points[] = {{x + w, y}, {x + w, y + h}, {x, y + h}, {x, y}}; + if (transform) { + for (int i = 0; i < 4; i++) mathTransform(transform, &points[i]); + } + shape->appendPath(commands, 5, points, 4); + //round rect + } else { + PathCommand commands[] = { + PathCommand::MoveTo, PathCommand::LineTo, PathCommand::CubicTo, + PathCommand::LineTo, PathCommand::CubicTo, PathCommand::LineTo, + PathCommand::CubicTo, PathCommand::LineTo, PathCommand::CubicTo, + PathCommand::Close + }; + + auto halfW = w * 0.5f; + auto halfH = h * 0.5f; + auto rx = r > halfW ? halfW : r; + auto ry = r > halfH ? halfH : r; + auto hrx = rx * PATH_KAPPA; + auto hry = ry * PATH_KAPPA; + + constexpr int ptsCnt = 17; + Point points[ptsCnt] = { + {x + w, y + ry}, //moveTo + {x + w, y + h - ry}, //lineTo + {x + w, y + h - ry + hry}, {x + w - rx + hrx, y + h}, {x + w - rx, y + h}, //cubicTo + {x + rx, y + h}, //lineTo + {x + rx - hrx, y + h}, {x, y + h - ry + hry}, {x, y + h - ry}, //cubicTo + {x, y + ry}, //lineTo + {x, y + ry - hry}, {x + rx - hrx, y}, {x + rx, y}, //cubicTo + {x + w - rx, y}, //lineTo + {x + w - rx + hrx, y}, {x + w, y + ry - hry}, {x + w, y + ry} //cubicTo + }; + + if (transform) { + for (int i = 0; i < ptsCnt; i++) mathTransform(transform, &points[i]); + } + shape->appendPath(commands, 10, points, ptsCnt); + } +} + +static void _updateRect(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto rect = static_cast(*child); + + auto position = rect->position(frameNo, exps); + auto size = rect->size(frameNo, exps); + auto roundness = rect->radius(frameNo, exps); + if (ctx->roundness > roundness) roundness = ctx->roundness; + + if (roundness > ROUNDNESS_EPSILON) { + if (roundness > size.x * 0.5f) roundness = size.x * 0.5f; + if (roundness > size.y * 0.5f) roundness = size.y * 0.5f; + } + + if (ctx->repeater) { + auto path = Shape::gen(); + _appendRect(path.get(), position.x - size.x * 0.5f, position.y - size.y * 0.5f, size.x, size.y, roundness, ctx->transform); + _repeat(parent, std::move(path), ctx); + } else { + auto merging = _draw(parent, ctx); + _appendRect(merging, position.x - size.x * 0.5f, position.y - size.y * 0.5f, size.x, size.y, roundness, ctx->transform); + } +} + + +static void _appendCircle(Shape* shape, float cx, float cy, float rx, float ry, Matrix* transform) +{ + auto rxKappa = rx * PATH_KAPPA; + auto ryKappa = ry * PATH_KAPPA; + + constexpr int cmdsCnt = 6; + PathCommand commands[cmdsCnt] = { + PathCommand::MoveTo, PathCommand::CubicTo, PathCommand::CubicTo, + PathCommand::CubicTo, PathCommand::CubicTo, PathCommand::Close + }; + + constexpr int ptsCnt = 13; + Point points[ptsCnt] = { + {cx, cy - ry}, //moveTo + {cx + rxKappa, cy - ry}, {cx + rx, cy - ryKappa}, {cx + rx, cy}, //cubicTo + {cx + rx, cy + ryKappa}, {cx + rxKappa, cy + ry}, {cx, cy + ry}, //cubicTo + {cx - rxKappa, cy + ry}, {cx - rx, cy + ryKappa}, {cx - rx, cy}, //cubicTo + {cx - rx, cy - ryKappa}, {cx - rxKappa, cy - ry}, {cx, cy - ry} //cubicTo + }; + + if (transform) { + for (int i = 0; i < ptsCnt; ++i) mathTransform(transform, &points[i]); + } + + shape->appendPath(commands, cmdsCnt, points, ptsCnt); +} + + +static void _updateEllipse(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto ellipse = static_cast(*child); + + auto position = ellipse->position(frameNo, exps); + auto size = ellipse->size(frameNo, exps); + + if (ctx->repeater) { + auto path = Shape::gen(); + _appendCircle(path.get(), position.x, position.y, size.x * 0.5f, size.y * 0.5f, ctx->transform); + _repeat(parent, std::move(path), ctx); + } else { + auto merging = _draw(parent, ctx); + _appendCircle(merging, position.x, position.y, size.x * 0.5f, size.y * 0.5f, ctx->transform); + } +} + + +static void _updatePath(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto path = static_cast(*child); + + if (ctx->repeater) { + auto p = Shape::gen(); + path->pathset(frameNo, P(p)->rs.path.cmds, P(p)->rs.path.pts, ctx->transform, ctx->roundness, exps); + _repeat(parent, std::move(p), ctx); + } else { + auto merging = _draw(parent, ctx); + if (path->pathset(frameNo, P(merging)->rs.path.cmds, P(merging)->rs.path.pts, ctx->transform, ctx->roundness, exps)) { + P(merging)->update(RenderUpdateFlag::Path); + } + } +} + + +static void _updateText(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, TVG_UNUSED RenderContext* ctx, LottieExpressions* exps) +{ + auto text = static_cast(*child); + auto& doc = text->doc(frameNo); + auto p = doc.text; + + if (!p || !text->font) return; + + auto scale = doc.size * 0.01f; + float spacing = text->spacing(frameNo) / scale; + Point cursor = {0.0f, 0.0f}; + auto scene = Scene::gen(); + int line = 0; + + //text string + while (true) { + //TODO: remove nested scenes. + //end of text, new line of the cursor position + if (*p == 13 || *p == 3 || *p == '\0') { + //text layout position + auto ascent = text->font->ascent * scale; + if (ascent > doc.bbox.size.y) ascent = doc.bbox.size.y; + Point layout = {doc.bbox.pos.x, doc.bbox.pos.y + ascent - doc.shift}; + + //adjust the layout + if (doc.justify == 1) layout.x += doc.bbox.size.x - (cursor.x * scale); //right aligned + else if (doc.justify == 2) layout.x += (doc.bbox.size.x * 0.5f) - (cursor.x * 0.5f * scale); //center aligned + + scene->translate(layout.x, layout.y); + scene->scale(scale); + + parent->scene->push(std::move(scene)); + + if (*p == '\0') break; + ++p; + + //new text group, single scene for each line + scene = Scene::gen(); + cursor.x = 0.0f; + cursor.y = ++line * (doc.height / scale); + } + + //find the glyph + for (auto g = text->font->chars.begin(); g < text->font->chars.end(); ++g) { + auto glyph = *g; + //draw matched glyphs + if (!strncmp(glyph->code, p, glyph->len)) { + //TODO: caching? + auto shape = Shape::gen(); + for (auto g = glyph->children.begin(); g < glyph->children.end(); ++g) { + auto group = static_cast(*g); + for (auto p = group->children.begin(); p < group->children.end(); ++p) { + if (static_cast(*p)->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, 0.0f, exps)) { + P(shape)->update(RenderUpdateFlag::Path); + } + } + } + shape->fill(doc.color.rgb[0], doc.color.rgb[1], doc.color.rgb[2]); + shape->translate(cursor.x, cursor.y); + + if (doc.stroke.render) { + shape->stroke(StrokeJoin::Round); + shape->stroke(doc.stroke.width / scale); + shape->stroke(doc.stroke.color.rgb[0], doc.stroke.color.rgb[1], doc.stroke.color.rgb[2]); + } + + scene->push(std::move(shape)); + + p += glyph->len; + + //advance the cursor position horizontally + cursor.x += glyph->width + spacing + doc.tracking; + break; + } + } + } +} + + +static void _applyRoundedCorner(Shape* star, Shape* merging, float outerRoundness, float roundness, bool hasRoundness) +{ + static constexpr auto ROUNDED_POLYSTAR_MAGIC_NUMBER = 0.47829f; + + auto cmdCnt = star->pathCommands(nullptr); + const Point *pts = nullptr; + auto ptsCnt = star->pathCoords(&pts); + + auto len = mathLength(pts[1] - pts[2]); + auto r = len > 0.0f ? ROUNDED_POLYSTAR_MAGIC_NUMBER * mathMin(len * 0.5f, roundness) / len : 0.0f; + + if (hasRoundness) { + P(merging)->rs.path.cmds.grow((uint32_t)(1.5 * cmdCnt)); + P(merging)->rs.path.pts.grow((uint32_t)(4.5 * cmdCnt)); + + int start = 3 * mathZero(outerRoundness); + merging->moveTo(pts[start].x, pts[start].y); + + for (uint32_t i = 1 + start; i < ptsCnt; i += 6) { + auto& prev = pts[i]; + auto& curr = pts[i + 2]; + auto& next = (i < ptsCnt - start) ? pts[i + 4] : pts[2]; + auto& nextCtrl = (i < ptsCnt - start) ? pts[i + 5] : pts[3]; + auto dNext = r * (curr - next); + auto dPrev = r * (curr - prev); + + auto p0 = curr - 2.0f * dPrev; + auto p1 = curr - dPrev; + auto p2 = curr - dNext; + auto p3 = curr - 2.0f * dNext; + + merging->cubicTo(prev.x, prev.y, p0.x, p0.y, p0.x, p0.y); + merging->cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + merging->cubicTo(p3.x, p3.y, next.x, next.y, nextCtrl.x, nextCtrl.y); + } + } else { + P(merging)->rs.path.cmds.grow(2 * cmdCnt); + P(merging)->rs.path.pts.grow(4 * cmdCnt); + + auto dPrev = r * (pts[1] - pts[0]); + auto p = pts[0] + 2.0f * dPrev; + merging->moveTo(p.x, p.y); + + for (uint32_t i = 1; i < ptsCnt; ++i) { + auto& curr = pts[i]; + auto& next = (i == ptsCnt - 1) ? pts[1] : pts[i + 1]; + auto dNext = r * (curr - next); + + auto p0 = curr - 2.0f * dPrev; + auto p1 = curr - dPrev; + auto p2 = curr - dNext; + auto p3 = curr - 2.0f * dNext; + + merging->lineTo(p0.x, p0.y); + merging->cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + + dPrev = -1.0f * dNext; + } + } + merging->close(); +} + + +static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float roundness, float frameNo, Shape* merging, LottieExpressions* exps) +{ + static constexpr auto POLYSTAR_MAGIC_NUMBER = 0.47829f / 0.28f; + + auto ptsCnt = star->ptsCnt(frameNo, exps); + auto innerRadius = star->innerRadius(frameNo, exps); + auto outerRadius = star->outerRadius(frameNo, exps); + auto innerRoundness = star->innerRoundness(frameNo, exps) * 0.01f; + auto outerRoundness = star->outerRoundness(frameNo, exps) * 0.01f; + + auto angle = mathDeg2Rad(-90.0f); + auto partialPointRadius = 0.0f; + auto anglePerPoint = (2.0f * MATH_PI / ptsCnt); + auto halfAnglePerPoint = anglePerPoint * 0.5f; + auto partialPointAmount = ptsCnt - floorf(ptsCnt); + auto longSegment = false; + auto numPoints = size_t(ceilf(ptsCnt) * 2); + auto direction = (star->direction == 0) ? 1.0f : -1.0f; + auto hasRoundness = false; + bool roundedCorner = (roundness > ROUNDNESS_EPSILON) && (mathZero(innerRoundness) || mathZero(outerRoundness)); + //TODO: we can use PathCommand / PathCoord directly. + auto shape = roundedCorner ? Shape::gen().release() : merging; + + float x, y; + + if (!mathZero(partialPointAmount)) { + angle += halfAnglePerPoint * (1.0f - partialPointAmount) * direction; + } + + if (!mathZero(partialPointAmount)) { + partialPointRadius = innerRadius + partialPointAmount * (outerRadius - innerRadius); + x = partialPointRadius * cosf(angle); + y = partialPointRadius * sinf(angle); + angle += anglePerPoint * partialPointAmount * 0.5f * direction; + } else { + x = outerRadius * cosf(angle); + y = outerRadius * sinf(angle); + angle += halfAnglePerPoint * direction; + } + + if (mathZero(innerRoundness) && mathZero(outerRoundness)) { + P(shape)->rs.path.pts.reserve(numPoints + 2); + P(shape)->rs.path.cmds.reserve(numPoints + 3); + } else { + P(shape)->rs.path.pts.reserve(numPoints * 3 + 2); + P(shape)->rs.path.cmds.reserve(numPoints + 3); + hasRoundness = true; + } + + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + shape->moveTo(in.x, in.y); + + for (size_t i = 0; i < numPoints; i++) { + auto radius = longSegment ? outerRadius : innerRadius; + auto dTheta = halfAnglePerPoint; + if (!mathZero(partialPointRadius) && i == numPoints - 2) { + dTheta = anglePerPoint * partialPointAmount * 0.5f; + } + if (!mathZero(partialPointRadius) && i == numPoints - 1) { + radius = partialPointRadius; + } + auto previousX = x; + auto previousY = y; + x = radius * cosf(angle); + y = radius * sinf(angle); + + if (hasRoundness) { + auto cp1Theta = (atan2f(previousY, previousX) - MATH_PI2 * direction); + auto cp1Dx = cosf(cp1Theta); + auto cp1Dy = sinf(cp1Theta); + auto cp2Theta = (atan2f(y, x) - MATH_PI2 * direction); + auto cp2Dx = cosf(cp2Theta); + auto cp2Dy = sinf(cp2Theta); + + auto cp1Roundness = longSegment ? innerRoundness : outerRoundness; + auto cp2Roundness = longSegment ? outerRoundness : innerRoundness; + auto cp1Radius = longSegment ? innerRadius : outerRadius; + auto cp2Radius = longSegment ? outerRadius : innerRadius; + + auto cp1x = cp1Radius * cp1Roundness * POLYSTAR_MAGIC_NUMBER * cp1Dx / ptsCnt; + auto cp1y = cp1Radius * cp1Roundness * POLYSTAR_MAGIC_NUMBER * cp1Dy / ptsCnt; + auto cp2x = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * cp2Dx / ptsCnt; + auto cp2y = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * cp2Dy / ptsCnt; + + if (!mathZero(partialPointAmount) && ((i == 0) || (i == numPoints - 1))) { + cp1x *= partialPointAmount; + cp1y *= partialPointAmount; + cp2x *= partialPointAmount; + cp2y *= partialPointAmount; + } + Point in2 = {previousX - cp1x, previousY - cp1y}; + Point in3 = {x + cp2x, y + cp2y}; + Point in4 = {x, y}; + if (transform) { + mathTransform(transform, &in2); + mathTransform(transform, &in3); + mathTransform(transform, &in4); + } + shape->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); + } else { + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + shape->lineTo(in.x, in.y); + } + angle += dTheta * direction; + longSegment = !longSegment; + } + shape->close(); + + if (roundedCorner) { + _applyRoundedCorner(shape, merging, outerRoundness, roundness, hasRoundness); + delete(shape); + } +} + + +static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* transform, float frameNo, Shape* merging, LottieExpressions* exps) +{ + static constexpr auto POLYGON_MAGIC_NUMBER = 0.25f; + + auto ptsCnt = size_t(floor(star->ptsCnt(frameNo, exps))); + auto radius = star->outerRadius(frameNo, exps); + auto roundness = star->outerRoundness(frameNo, exps) * 0.01f; + + auto angle = mathDeg2Rad(-90.0f); + auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt); + auto direction = (star->direction == 0) ? 1.0f : -1.0f; + auto hasRoundness = false; + auto x = radius * cosf(angle); + auto y = radius * sinf(angle); + + angle += anglePerPoint * direction; + + if (mathZero(roundness)) { + P(merging)->rs.path.pts.reserve(ptsCnt + 2); + P(merging)->rs.path.cmds.reserve(ptsCnt + 3); + } else { + P(merging)->rs.path.pts.reserve(ptsCnt * 3 + 2); + P(merging)->rs.path.cmds.reserve(ptsCnt + 3); + hasRoundness = true; + } + + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + merging->moveTo(in.x, in.y); + + for (size_t i = 0; i < ptsCnt; i++) { + auto previousX = x; + auto previousY = y; + x = (radius * cosf(angle)); + y = (radius * sinf(angle)); + + if (hasRoundness) { + auto cp1Theta = atan2f(previousY, previousX) - MATH_PI2 * direction; + auto cp1Dx = cosf(cp1Theta); + auto cp1Dy = sinf(cp1Theta); + auto cp2Theta = atan2f(y, x) - MATH_PI2 * direction; + auto cp2Dx = cosf(cp2Theta); + auto cp2Dy = sinf(cp2Theta); + + auto cp1x = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dx; + auto cp1y = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dy; + auto cp2x = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dx; + auto cp2y = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dy; + + Point in2 = {previousX - cp1x, previousY - cp1y}; + Point in3 = {x + cp2x, y + cp2y}; + Point in4 = {x, y}; + if (transform) { + mathTransform(transform, &in2); + mathTransform(transform, &in3); + mathTransform(transform, &in4); + } + merging->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); + } else { + Point in = {x, y}; + if (transform) mathTransform(transform, &in); + merging->lineTo(in.x, in.y); + } + angle += anglePerPoint * direction; + } + merging->close(); +} + + +static void _updatePolystar(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto star= static_cast(*child); + + //Optimize: Can we skip the individual coords transform? + Matrix matrix; + mathIdentity(&matrix); + auto position = star->position(frameNo, exps); + mathTranslate(&matrix, position.x, position.y); + mathRotate(&matrix, star->rotation(frameNo, exps)); + + if (ctx->transform) matrix = mathMultiply(ctx->transform, &matrix); + + auto identity = mathIdentity((const Matrix*)&matrix); + + if (ctx->repeater) { + auto p = Shape::gen(); + if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, p.get(), exps); + else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, p.get(), exps); + _repeat(parent, std::move(p), ctx); + } else { + auto merging = _draw(parent, ctx); + if (star->type == LottiePolyStar::Star) _updateStar(parent, star, identity ? nullptr : &matrix, ctx->roundness, frameNo, merging, exps); + else _updatePolygon(parent, star, identity ? nullptr : &matrix, frameNo, merging, exps); + P(merging)->update(RenderUpdateFlag::Path); + } +} + + +static void _updateImage(LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx) +{ + auto image = static_cast(*child); + auto picture = image->picture; + + if (!picture) { + picture = Picture::gen().release(); + + //force to load a picture on the same thread + TaskScheduler::async(false); + + if (image->size > 0) { + if (picture->load((const char*)image->b64Data, image->size, image->mimeType, false) != Result::Success) { + delete(picture); + return; + } + } else { + if (picture->load(image->path) != Result::Success) { + delete(picture); + return; + } + } + + TaskScheduler::async(true); + + image->picture = picture; + PP(picture)->ref(); + } + + if (ctx->propagator) { + if (auto matrix = PP(ctx->propagator)->transform()) { + picture->transform(*matrix); + } + picture->opacity(PP(ctx->propagator)->opacity); + } + parent->scene->push(cast(picture)); +} + + +static void _updateRoundedCorner(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto roundedCorner= static_cast(*child); + auto roundness = roundedCorner->radius(frameNo, exps); + if (ctx->roundness < roundness) ctx->roundness = roundness; +} + + +static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto repeater= static_cast(*child); + + if (!ctx->repeater) ctx->repeater = new RenderRepeater(); + ctx->repeater->cnt = static_cast(repeater->copies(frameNo, exps)); + ctx->repeater->offset = repeater->offset(frameNo, exps); + ctx->repeater->position = repeater->position(frameNo, exps); + ctx->repeater->anchor = repeater->anchor(frameNo, exps); + ctx->repeater->scale = repeater->scale(frameNo, exps); + ctx->repeater->rotation = repeater->rotation(frameNo, exps); + ctx->repeater->startOpacity = repeater->startOpacity(frameNo, exps); + ctx->repeater->endOpacity = repeater->endOpacity(frameNo, exps); + ctx->repeater->inorder = repeater->inorder; + ctx->repeater->interpOpacity = (ctx->repeater->startOpacity == ctx->repeater->endOpacity) ? false : true; + + ctx->merging = nullptr; +} + + +static void _updateTrimpath(TVG_UNUSED LottieGroup* parent, LottieObject** child, float frameNo, TVG_UNUSED Inlist& contexts, RenderContext* ctx, LottieExpressions* exps) +{ + auto trimpath= static_cast(*child); + + float begin, end; + trimpath->segment(frameNo, begin, end, exps); + + if (P(ctx->propagator)->rs.stroke) { + auto pbegin = P(ctx->propagator)->rs.stroke->trim.begin; + auto pend = P(ctx->propagator)->rs.stroke->trim.end; + auto length = fabsf(pend - pbegin); + begin = (length * begin) + pbegin; + end = (length * end) + pbegin; + } + + P(ctx->propagator)->strokeTrim(begin, end, trimpath->type == LottieTrimpath::Type::Individual ? true : false); +} + + +static void _updateChildren(LottieGroup* parent, float frameNo, Inlist& contexts, LottieExpressions* exps) +{ + contexts.head->begin = parent->children.end() - 1; + + while (!contexts.empty()) { + auto ctx = contexts.front(); + ctx->reqFragment = parent->reqFragment; + for (auto child = ctx->begin; child >= parent->children.data; --child) { + //Here switch-case statements are more performant than virtual methods. + switch ((*child)->type) { + case LottieObject::Group: { + _updateGroup(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Transform: { + _updateTransform(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::SolidFill: { + _updateSolidFill(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::SolidStroke: { + _updateSolidStroke(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::GradientFill: { + _updateGradientFill(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::GradientStroke: { + _updateGradientStroke(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Rect: { + _updateRect(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Ellipse: { + _updateEllipse(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Path: { + _updatePath(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Polystar: { + _updatePolystar(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Image: { + _updateImage(parent, child, frameNo, contexts, ctx); + break; + } + case LottieObject::Trimpath: { + _updateTrimpath(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Text: { + _updateText(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::Repeater: { + _updateRepeater(parent, child, frameNo, contexts, ctx, exps); + break; + } + case LottieObject::RoundedCorner: { + _updateRoundedCorner(parent, child, frameNo, contexts, ctx, exps); + break; + } + default: break; + } + } + delete(ctx); + } +} + + +static void _updatePrecomp(LottieLayer* precomp, float frameNo, LottieExpressions* exps) +{ + if (precomp->children.empty()) return; + + frameNo = precomp->remap(frameNo, exps); + + for (auto child = precomp->children.end() - 1; child >= precomp->children.begin(); --child) { + _updateLayer(precomp, static_cast(*child), frameNo, exps); + } + + //clip the layer viewport + if (precomp->w > 0 && precomp->h > 0) { + auto clipper = Shape::gen().release(); + clipper->appendRect(0, 0, static_cast(precomp->w), static_cast(precomp->h)); + clipper->transform(precomp->cache.matrix); + + //TODO: remove the intermediate scene.... + auto cscene = Scene::gen(); + cscene->composite(cast(clipper), CompositeMethod::ClipPath); + cscene->push(cast(precomp->scene)); + precomp->scene = cscene.release(); + } +} + + +static void _updateSolid(LottieLayer* layer) +{ + auto shape = Shape::gen(); + shape->appendRect(0, 0, static_cast(layer->w), static_cast(layer->h)); + shape->fill(layer->color.rgb[0], layer->color.rgb[1], layer->color.rgb[2], layer->cache.opacity); + layer->scene->push(std::move(shape)); +} + + +static void _updateMaskings(LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + if (layer->masks.count == 0) return; + + //maskings + Shape* pmask = nullptr; + auto pmethod = CompositeMethod::AlphaMask; + + for (auto m = layer->masks.begin(); m < layer->masks.end(); ++m) { + auto mask = static_cast(*m); + auto shape = Shape::gen().release(); + shape->fill(255, 255, 255, mask->opacity(frameNo)); + shape->transform(layer->cache.matrix); + if (mask->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, 0.0f, exps)) { + P(shape)->update(RenderUpdateFlag::Path); + } + auto method = mask->method; + if (pmask) { + //false of false is true. invert. + if (method == CompositeMethod::SubtractMask && pmethod == method) { + method = CompositeMethod::AddMask; + } else if (pmethod == CompositeMethod::DifferenceMask && pmethod == method) { + method = CompositeMethod::IntersectMask; + } + pmask->composite(cast(shape), method); + } else { + if (method == CompositeMethod::SubtractMask) method = CompositeMethod::InvAlphaMask; + else if (method == CompositeMethod::AddMask) method = CompositeMethod::AlphaMask; + else if (method == CompositeMethod::IntersectMask) method = CompositeMethod::AlphaMask; + else if (method == CompositeMethod::DifferenceMask) method = CompositeMethod::AlphaMask; //does this correct? + layer->scene->composite(cast(shape), method); + } + pmethod = mask->method; + pmask = shape; + } +} + + +static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + auto target = layer->matte.target; + if (!target) return true; + + _updateLayer(root, target, frameNo, exps); + + if (target->scene) { + layer->scene->composite(cast(target->scene), layer->matte.type); + } else if (layer->matte.type == CompositeMethod::AlphaMask || layer->matte.type == CompositeMethod::LumaMask) { + //matte target is not exist. alpha blending definitely bring an invisible result + delete(layer->scene); + layer->scene = nullptr; + return false; + } + return true; +} + + +static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps) +{ + layer->scene = nullptr; + + //visibility + if (frameNo < layer->inFrame || frameNo >= layer->outFrame) return; + + _updateTransform(layer, frameNo, exps); + + //full transparent scene. no need to perform + if (layer->type != LottieLayer::Null && layer->cache.opacity == 0) return; + + //Prepare render data + layer->scene = Scene::gen().release(); + + //ignore opacity when Null layer? + if (layer->type != LottieLayer::Null) layer->scene->opacity(layer->cache.opacity); + + layer->scene->transform(layer->cache.matrix); + + if (layer->matte.target && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??"); + + if (!_updateMatte(root, layer, frameNo, exps)) return; + + _updateMaskings(layer, frameNo, exps); + + switch (layer->type) { + case LottieLayer::Precomp: { + _updatePrecomp(layer, frameNo, exps); + break; + } + case LottieLayer::Solid: { + _updateSolid(layer); + break; + } + default: { + if (!layer->children.empty()) { + Inlist contexts; + contexts.back(new RenderContext); + _updateChildren(layer, frameNo, contexts, exps); + contexts.free(); + } + break; + } + } + + layer->scene->blend(layer->blendMethod); + + //the given matte source was composited by the target earlier. + if (!layer->matteSrc) root->scene->push(cast(layer->scene)); +} + + +static void _buildReference(LottieComposition* comp, LottieLayer* layer) +{ + for (auto asset = comp->assets.begin(); asset < comp->assets.end(); ++asset) { + if (strcmp(layer->refId, (*asset)->name)) continue; + if (layer->type == LottieLayer::Precomp) { + auto assetLayer = static_cast(*asset); + if (_buildComposition(comp, assetLayer)) { + layer->children = assetLayer->children; + layer->reqFragment = assetLayer->reqFragment; + } + } else if (layer->type == LottieLayer::Image) { + layer->children.push(*asset); + } + break; + } +} + + +static void _buildHierarchy(LottieGroup* parent, LottieLayer* child) +{ + if (child->pid == -1) return; + + if (child->matte.target && child->pid == child->matte.target->id) { + child->parent = child->matte.target; + return; + } + + for (auto p = parent->children.begin(); p < parent->children.end(); ++p) { + auto parent = static_cast(*p); + if (child == parent) continue; + if (child->pid == parent->id) { + child->parent = parent; + break; + } + if (parent->matte.target && parent->matte.target->id == child->pid) { + child->parent = parent->matte.target; + break; + } + } +} + + +static void _attachFont(LottieComposition* comp, LottieLayer* parent) +{ + //TODO: Consider to migrate this attachment to the frame update time. + for (auto c = parent->children.begin(); c < parent->children.end(); ++c) { + auto text = static_cast(*c); + auto& doc = text->doc(0); + if (!doc.name) continue; + auto len = strlen(doc.name); + for (uint32_t i = 0; i < comp->fonts.count; ++i) { + auto font = comp->fonts[i]; + auto len2 = strlen(font->name); + if (!strncmp(font->name, doc.name, len < len2 ? len : len2)) { + text->font = font; + break; + } + } + } +} + + +static bool _buildComposition(LottieComposition* comp, LottieGroup* parent) +{ + if (parent->children.count == 0) return false; + if (parent->buildDone) return true; + parent->buildDone = true; + + for (auto c = parent->children.begin(); c < parent->children.end(); ++c) { + auto child = static_cast(*c); + + //attach the precomp layer. + if (child->refId) _buildReference(comp, child); + + if (child->matte.target) { + //parenting + _buildHierarchy(parent, child->matte.target); + //precomp referencing + if (child->matte.target->refId) _buildReference(comp, child->matte.target); + } + _buildHierarchy(parent, child); + + //attach the necessary font data + if (child->type == LottieLayer::Text) _attachFont(comp, child); + } + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool LottieBuilder::update(LottieComposition* comp, float frameNo) +{ + if (comp->root->children.empty()) return false; + + frameNo += comp->startFrame; + if (frameNo < comp->startFrame) frameNo = comp->startFrame; + if (frameNo >= comp->endFrame) frameNo = (comp->endFrame - 1); + + //update children layers + auto root = comp->root; + root->scene->clear(); + + if (exps && comp->expressions) exps->update(comp->timeAtFrame(frameNo)); + + for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) { + _updateLayer(root, static_cast(*child), frameNo, exps); + } + + return true; +} + + +void LottieBuilder::build(LottieComposition* comp) +{ + if (!comp) return; + + comp->root->scene = Scene::gen().release(); + if (!comp->root->scene) return; + + _buildComposition(comp, comp->root); + + if (!update(comp, 0)) return; + + //viewport clip + auto clip = Shape::gen(); + clip->appendRect(0, 0, static_cast(comp->w), static_cast(comp->h)); + comp->root->scene->composite(std::move(clip), CompositeMethod::ClipPath); +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.h new file mode 100644 index 000000000..690fa85ac --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieBuilder.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL +#ifndef _TVG_LOTTIE_BUILDER_H_ +#define _TVG_LOTTIE_BUILDER_H_ + +#include "tvgCommon.h" +#include "tvgLottieExpressions.h" + +struct LottieComposition; + +struct LottieBuilder +{ + LottieExpressions* exps = nullptr; + + LottieBuilder() + { + exps = LottieExpressions::instance(); + } + + ~LottieBuilder() + { + LottieExpressions::retrieve(exps); + } + + bool update(LottieComposition* comp, float progress); + void build(LottieComposition* comp); +}; + +#endif //_TVG_LOTTIE_BUILDER_H + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.cpp new file mode 100644 index 000000000..aa6c9b13b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.cpp @@ -0,0 +1,1298 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgMath.h" +#include "tvgLottieModel.h" +#include "tvgLottieExpressions.h" + +#ifdef THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct ExpContent +{ + LottieObject* obj; + float frameNo; +}; + + +//reserved expressions specifiers +static const char* EXP_NAME = "name"; +static const char* EXP_CONTENT = "content"; +static const char* EXP_WIDTH = "width"; +static const char* EXP_HEIGHT = "height"; +static const char* EXP_CYCLE = "cycle"; +static const char* EXP_PINGPONG = "pingpong"; +static const char* EXP_OFFSET = "offset"; +static const char* EXP_CONTINUE = "continue"; +static const char* EXP_TIME = "time"; +static const char* EXP_VALUE = "value"; +static const char* EXP_INDEX = "index"; +static const char* EXP_EFFECT= "effect"; + +static LottieExpressions* exps = nullptr; //singleton instance engine + + +static void contentFree(void *native_p, struct jerry_object_native_info_t *info_p) +{ + free(native_p); +} + +static jerry_object_native_info_t freeCb {contentFree, 0, 0}; +static uint32_t engineRefCnt = 0; //Expressions Engine reference count + + +static char* _name(jerry_value_t args) +{ + auto arg0 = jerry_value_to_string(args); + auto len = jerry_string_length(arg0); + auto name = (jerry_char_t*)malloc(len * sizeof(jerry_char_t) + 1); + jerry_string_to_buffer(arg0, JERRY_ENCODING_UTF8, name, len); + name[len] = '\0'; + jerry_value_free(arg0); + return (char*) name; +} + + +static jerry_value_t _toComp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + TVGERR("LOTTIE", "toComp is not supported in expressions!"); + + return jerry_undefined(); +} + + +static void _buildTransform(jerry_value_t context, LottieTransform* transform) +{ + if (!transform) return; + + auto obj = jerry_object(); + jerry_object_set_sz(context, "transform", obj); + + auto anchorPoint = jerry_object(); + jerry_object_set_native_ptr(anchorPoint, nullptr, &transform->anchor); + jerry_object_set_sz(obj, "anchorPoint", anchorPoint); + jerry_value_free(anchorPoint); + + auto position = jerry_object(); + jerry_object_set_native_ptr(position, nullptr, &transform->position); + jerry_object_set_sz(obj, "position", position); + jerry_value_free(position); + + auto scale = jerry_object(); + jerry_object_set_native_ptr(scale, nullptr, &transform->scale); + jerry_object_set_sz(obj, "scale", scale); + jerry_value_free(scale); + + auto rotation = jerry_object(); + jerry_object_set_native_ptr(rotation, nullptr, &transform->rotation); + jerry_object_set_sz(obj, "rotation", rotation); + jerry_value_free(rotation); + + auto opacity = jerry_object(); + jerry_object_set_native_ptr(opacity, nullptr, &transform->opacity); + jerry_object_set_sz(obj, "opacity", opacity); + jerry_value_free(opacity); + + jerry_value_free(obj); +} + + +static void _buildLayer(jerry_value_t context, LottieLayer* layer, LottieComposition* comp) +{ + auto width = jerry_number(layer->w); + jerry_object_set_sz(context, EXP_WIDTH, width); + jerry_value_free(width); + + auto height = jerry_number(layer->h); + jerry_object_set_sz(context, EXP_HEIGHT, height); + jerry_value_free(height); + + auto index = jerry_number(layer->id); + jerry_object_set_sz(context, EXP_INDEX, index); + jerry_value_free(index); + + auto parent = jerry_object(); + jerry_object_set_native_ptr(parent, nullptr, layer->parent); + jerry_object_set_sz(context, "parent", parent); + jerry_value_free(parent); + + auto hasParent = jerry_boolean(layer->parent ? true : false); + jerry_object_set_sz(context, "hasParent", hasParent); + jerry_value_free(hasParent); + + auto inPoint = jerry_number(layer->inFrame); + jerry_object_set_sz(context, "inPoint", inPoint); + jerry_value_free(inPoint); + + auto outPoint = jerry_number(layer->outFrame); + jerry_object_set_sz(context, "outPoint", outPoint); + jerry_value_free(outPoint); + + auto startTime = jerry_number(comp->timeAtFrame(layer->startFrame)); + jerry_object_set_sz(context, "startTime", startTime); + jerry_value_free(startTime); + + auto hasVideo = jerry_boolean(false); + jerry_object_set_sz(context, "hasVideo", hasVideo); + jerry_value_free(hasVideo); + + auto hasAudio = jerry_boolean(false); + jerry_object_set_sz(context, "hasAudio", hasAudio); + jerry_value_free(hasAudio); + + //active, #current in the animation range? + + auto enabled = jerry_boolean(!layer->hidden); + jerry_object_set_sz(context, "enabled", enabled); + jerry_value_free(enabled); + + auto audioActive = jerry_boolean(false); + jerry_object_set_sz(context, "audioActive", audioActive); + jerry_value_free(audioActive); + + //sampleImage(point, radius = [.5, .5], postEffect=true, t=time) + + _buildTransform(context, layer->transform); + + //audioLevels, #the value of the Audio Levels property of the layer in decibels + + auto timeRemap = jerry_object(); + jerry_object_set_native_ptr(timeRemap, nullptr, &layer->timeRemap); + jerry_object_set_sz(context, "timeRemap", timeRemap); + jerry_value_free(timeRemap); + + //marker.key(index) + //marker.key(name) + //marker.nearestKey(t) + //marker.numKeys + + auto name = jerry_string_sz(layer->name); + jerry_object_set_sz(context, EXP_NAME, name); + jerry_value_free(name); + + auto toComp = jerry_function_external(_toComp); + jerry_object_set_sz(context, "toComp", toComp); + jerry_object_set_native_ptr(toComp, nullptr, comp); + jerry_value_free(toComp); +} + + +static jerry_value_t _value(float frameNo, LottieExpression* exp) +{ + switch (exp->type) { + case LottieProperty::Type::Point: { + auto value = jerry_object(); + auto pos = (*static_cast(exp->property))(frameNo); + auto val1 = jerry_number(pos.x); + auto val2 = jerry_number(pos.y); + jerry_object_set_index(value, 0, val1); + jerry_object_set_index(value, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + return value; + } + case LottieProperty::Type::Float: { + return jerry_number((*static_cast(exp->property))(frameNo)); + } + case LottieProperty::Type::Opacity: { + return jerry_number((*static_cast(exp->property))(frameNo)); + } + case LottieProperty::Type::PathSet: { + auto value = jerry_object(); + jerry_object_set_native_ptr(value, nullptr, exp->property); + return value; + } + case LottieProperty::Type::Position: { + auto value = jerry_object(); + auto pos = (*static_cast(exp->property))(frameNo); + auto val1 = jerry_number(pos.x); + auto val2 = jerry_number(pos.y); + jerry_object_set_index(value, 0, val1); + jerry_object_set_index(value, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + return value; + } + default: { + TVGERR("LOTTIE", "Non supported type for value? = %d", (int) exp->type); + } + } + return jerry_undefined(); +} + + +static jerry_value_t _addsub(const jerry_value_t args[], float addsub) +{ + //1d + if (jerry_value_is_number(args[0])) return jerry_number(jerry_value_as_number(args[0]) + addsub * jerry_value_as_number(args[1])); + + //2d + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + auto x = jerry_value_as_number(val1) + addsub * jerry_value_as_number(val3); + auto y = jerry_value_as_number(val2) + addsub * jerry_value_as_number(val4); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + auto obj = jerry_object(); + val1 = jerry_number(x); + val2 = jerry_number(y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _muldiv(const jerry_value_t arg1, float arg2) +{ + //1d + if (jerry_value_is_number(arg1)) return jerry_number(jerry_value_as_number(arg1) * arg2); + + //2d + auto val1 = jerry_object_get_index(arg1, 0); + auto val2 = jerry_object_get_index(arg1, 1); + auto x = jerry_value_as_number(val1) * arg2; + auto y = jerry_value_as_number(val2) * arg2; + + jerry_value_free(val1); + jerry_value_free(val2); + + auto obj = jerry_object(); + val1 = jerry_number(x); + val2 = jerry_number(y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _add(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _addsub(args, 1.0f); +} + + +static jerry_value_t _sub(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _addsub(args, -1.0f); +} + + +static jerry_value_t _mul(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _muldiv(args[0], jerry_value_as_number(args[1])); +} + + +static jerry_value_t _div(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return _muldiv(args[0], 1.0f / jerry_value_as_number(args[1])); +} + + +static jerry_value_t _interp(float t, const jerry_value_t args[], int argsCnt) +{ + auto tMin = 0.0f; + auto tMax = 1.0f; + int idx = 0; + + if (argsCnt > 3) { + tMin = jerry_value_as_number(args[1]); + tMax = jerry_value_as_number(args[2]); + idx += 2; + } + + //2d + if (jerry_value_is_object(args[idx + 1]) && jerry_value_is_object(args[idx + 2])) { + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + + Point pt1 = {(float)jerry_value_as_number(val1), (float)jerry_value_as_number(val2)}; + Point pt2 = {(float)jerry_value_as_number(val3), (float)jerry_value_as_number(val4)}; + Point ret; + if (t <= tMin) ret = pt1; + else if (t >= tMax) ret = pt2; + else ret = mathLerp(pt1, pt2, t); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + auto obj = jerry_object(); + val1 = jerry_number(ret.x); + val2 = jerry_number(ret.y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; + } + + //1d + auto val1 = (float) jerry_value_as_number(args[idx + 1]); + if (t <= tMin) jerry_number(val1); + auto val2 = (float) jerry_value_as_number(args[idx + 2]); + if (t >= tMax) jerry_number(val2); + return jerry_number(mathLerp(val1, val2, t)); +} + + +static jerry_value_t _linear(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + +static jerry_value_t _ease(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + t = (t < 0.5) ? (4 * t * t * t) : (1.0f - pow(-2.0f * t + 2.0f, 3) * 0.5f); + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + + +static jerry_value_t _easeIn(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + t = t * t * t; + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + +static jerry_value_t _easeOut(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto t = (float) jerry_value_as_number(args[0]); + t = 1.0f - pow(1.0f - t, 3); + return _interp(t, args, jerry_value_as_uint32(argsCnt)); +} + + +static jerry_value_t _clamp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto num = jerry_value_as_number(args[0]); + auto limit1 = jerry_value_as_number(args[1]); + auto limit2 = jerry_value_as_number(args[2]); + + //clamping + if (num < limit1) num = limit1; + if (num > limit2) num = limit2; + + return jerry_number(num); +} + + +static jerry_value_t _dot(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + + auto x = jerry_value_as_number(val1) * jerry_value_as_number(val3); + auto y = jerry_value_as_number(val2) * jerry_value_as_number(val4); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + return jerry_number(x + y); +} + + +static jerry_value_t _cross(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto val3 = jerry_object_get_index(args[1], 0); + auto val4 = jerry_object_get_index(args[1], 1); + + auto x = jerry_value_as_number(val1) * jerry_value_as_number(val4); + auto y = jerry_value_as_number(val2) * jerry_value_as_number(val3); + + jerry_value_free(val1); + jerry_value_free(val2); + jerry_value_free(val3); + jerry_value_free(val4); + + return jerry_number(x - y); +} + + +static jerry_value_t _normalize(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto x = jerry_value_as_number(val1); + auto y = jerry_value_as_number(val2); + + jerry_value_free(val1); + jerry_value_free(val2); + + auto length = sqrtf(x * x + y * y); + + x /= length; + y /= length; + + auto obj = jerry_object(); + val1 = jerry_number(x); + val2 = jerry_number(y); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 0, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _length(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val1 = jerry_object_get_index(args[0], 0); + auto val2 = jerry_object_get_index(args[0], 1); + auto x = jerry_value_as_number(val1); + auto y = jerry_value_as_number(val2); + + jerry_value_free(val1); + jerry_value_free(val2); + + return jerry_number(sqrtf(x * x + y * y)); +} + + +static jerry_value_t _random(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto val = (float)(rand() % 10000001); + return jerry_number(val * 0.0000001f); +} + + +static jerry_value_t _deg2rad(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return jerry_number(mathDeg2Rad((float)jerry_value_as_number(args[0]))); +} + + +static jerry_value_t _rad2deg(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + return jerry_number(mathRad2Deg((float)jerry_value_as_number(args[0]))); +} + + +static jerry_value_t _effect(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + TVGERR("LOTTIE", "effect is not supported in expressions!"); + + return jerry_undefined(); +} + + +static jerry_value_t _fromCompToSurface(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + TVGERR("LOTTIE", "fromCompToSurface is not supported in expressions!"); + + return jerry_undefined(); +} + + +static jerry_value_t _content(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto name = _name(args[0]); + auto data = static_cast(jerry_object_get_native_ptr(info->function, &freeCb)); + auto group = static_cast(data->obj); + auto target = group->content((char*)name); + free(name); + if (!target) return jerry_undefined(); + + //find the a path property(sh) in the group layer? + switch (target->type) { + case LottieObject::Group: { + auto group = static_cast(target); + auto obj = jerry_function_external(_content); + + //attach a transform + for (auto c = group->children.begin(); c < group->children.end(); ++c) { + if ((*c)->type == LottieObject::Type::Transform) { + _buildTransform(obj, static_cast(*c)); + break; + } + } + auto data2 = (ExpContent*)malloc(sizeof(ExpContent)); + data2->obj = group; + data2->frameNo = data->frameNo; + jerry_object_set_native_ptr(obj, &freeCb, data2); + jerry_object_set_sz(obj, EXP_CONTENT, obj); + return obj; + } + case LottieObject::Path: { + jerry_value_t obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, &static_cast(target)->pathset); + jerry_object_set_sz(obj, "path", obj); + return obj; + } + case LottieObject::Trimpath: { + auto trimpath = static_cast(target); + jerry_value_t obj = jerry_object(); + auto start = jerry_number(trimpath->start(data->frameNo)); + jerry_object_set_sz(obj, "start", start); + jerry_value_free(start); + auto end = jerry_number(trimpath->end(data->frameNo)); + jerry_object_set_sz(obj, "end", end); + jerry_value_free(end); + auto offset = jerry_number(trimpath->offset(data->frameNo)); + jerry_object_set_sz(obj, "offset", end); + jerry_value_free(offset); + return obj; + } + default: break; + } + return jerry_undefined(); +} + + +static jerry_value_t _layer(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto comp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + LottieLayer* layer; + + //layer index + if (jerry_value_is_number(args[0])) { + auto idx = (uint16_t)jerry_value_as_int32(args[0]); + layer = comp->layer(idx); + jerry_value_free(idx); + //layer name + } else { + auto name = _name(args[0]); + layer = comp->layer((char*)name); + free(name); + } + + if (!layer) return jerry_undefined(); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, layer); + _buildLayer(obj, layer, comp); + + return obj; +} + + +static jerry_value_t _nearestKey(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + auto index = jerry_number(exp->property->nearest(frameNo)); + + auto obj = jerry_object(); + jerry_object_set_sz(obj, EXP_INDEX, index); + jerry_value_free(index); + + return obj; +} + + +static jerry_value_t _valueAtTime(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + return _value(frameNo, exp); +} + + +static jerry_value_t _velocityAtTime(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + auto key = exp->property->nearest(frameNo); + auto pframe = exp->property->frameNo(key - 1); + auto cframe = exp->property->frameNo(key); + auto elapsed = (cframe - pframe) / (exp->comp->frameRate); + + Point cur, prv; + + //compute the velocity + switch (exp->type) { + case LottieProperty::Type::Point: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + case LottieProperty::Type::Position: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + default: { + TVGERR("LOTTIE", "Non supported type for velocityAtTime?"); + return jerry_undefined(); + } + } + + float velocity[] = {(cur.x - prv.x) / elapsed, (cur.y - prv.y) / elapsed}; + + auto obj = jerry_object(); + auto val1 = jerry_number(velocity[0]); + auto val2 = jerry_number(velocity[1]); + jerry_object_set_index(obj, 0, val1); + jerry_object_set_index(obj, 1, val2); + jerry_value_free(val1); + jerry_value_free(val2); + + return obj; +} + + +static jerry_value_t _speedAtTime(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto time = jerry_value_as_number(args[0]); + auto frameNo = exp->comp->frameAtTime(time); + auto key = exp->property->nearest(frameNo); + auto pframe = exp->property->frameNo(key - 1); + auto cframe = exp->property->frameNo(key); + auto elapsed = (cframe - pframe) / (exp->comp->frameRate); + + Point cur, prv; + + //compute the velocity + switch (exp->type) { + case LottieProperty::Type::Point: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + case LottieProperty::Type::Position: { + prv = (*static_cast(exp->property))(pframe); + cur = (*static_cast(exp->property))(cframe); + break; + } + default: { + TVGERR("LOTTIE", "Non supported type for speedAtTime?"); + return jerry_undefined(); + } + } + + auto speed = sqrtf(pow(cur.x - prv.x, 2) + pow(cur.y - prv.y, 2)) / elapsed; + auto obj = jerry_number(speed); + return obj; +} + + +static bool _loopOutCommon(LottieExpression* exp, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + exp->loop.mode = LottieExpression::LoopMode::OutCycle; + + if (argsCnt > 0) { + auto name = _name(args[0]); + if (!strcmp(name, EXP_CYCLE)) exp->loop.mode = LottieExpression::LoopMode::OutCycle; + else if (!strcmp(name, EXP_PINGPONG)) exp->loop.mode = LottieExpression::LoopMode::OutPingPong; + else if (!strcmp(name, EXP_OFFSET)) exp->loop.mode = LottieExpression::LoopMode::OutOffset; + else if (!strcmp(name, EXP_CONTINUE)) exp->loop.mode = LottieExpression::LoopMode::OutContinue; + free(name); + } + + if (exp->loop.mode != LottieExpression::LoopMode::OutCycle) { + TVGERR("hermet", "Not supported loopOut type = %d", exp->loop.mode); + return false; + } + + return true; +} + + +static jerry_value_t _loopOut(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (!_loopOutCommon(exp, args, argsCnt)) return jerry_undefined(); + + if (argsCnt > 1) exp->loop.key = jerry_value_as_int32(args[1]); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static jerry_value_t _loopOutDuration(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (!_loopOutCommon(exp, args, argsCnt)) return jerry_undefined(); + + if (argsCnt > 1) { + exp->loop.in = exp->comp->frameAtTime((float)jerry_value_as_int32(args[1])); + } + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static bool _loopInCommon(LottieExpression* exp, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + exp->loop.mode = LottieExpression::LoopMode::InCycle; + + if (argsCnt > 0) { + auto name = _name(args[0]); + if (!strcmp(name, EXP_CYCLE)) exp->loop.mode = LottieExpression::LoopMode::InCycle; + else if (!strcmp(name, EXP_PINGPONG)) exp->loop.mode = LottieExpression::LoopMode::InPingPong; + else if (!strcmp(name, EXP_OFFSET)) exp->loop.mode = LottieExpression::LoopMode::InOffset; + else if (!strcmp(name, EXP_CONTINUE)) exp->loop.mode = LottieExpression::LoopMode::InContinue; + free(name); + } + + if (exp->loop.mode != LottieExpression::LoopMode::InCycle) { + TVGERR("hermet", "Not supported loopOut type = %d", exp->loop.mode); + return false; + } + + return true; +} + +static jerry_value_t _loopIn(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (!_loopInCommon(exp, args, argsCnt)) return jerry_undefined(); + + if (argsCnt > 1) { + exp->loop.in = exp->comp->frameAtTime((float)jerry_value_as_int32(args[1])); + } + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static jerry_value_t _loopInDuration(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + if (argsCnt > 1) { + exp->loop.in = exp->comp->frameAtTime((float)jerry_value_as_int32(args[1])); + } + + if (!_loopInCommon(exp, args, argsCnt)) return jerry_undefined(); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, exp->property); + return obj; +} + + +static jerry_value_t _key(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto exp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + auto key = jerry_value_as_int32(args[0]); + auto frameNo = exp->property->frameNo(key); + auto time = jerry_number(exp->comp->timeAtFrame(frameNo)); + auto value = _value(frameNo, exp); + + auto obj = jerry_object(); + jerry_object_set_sz(obj, EXP_TIME, time); + jerry_object_set_sz(obj, EXP_INDEX, args[0]); + jerry_object_set_sz(obj, EXP_VALUE, value); + + jerry_value_free(time); + jerry_value_free(value); + + return obj; +} + + + +static jerry_value_t _createPath(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + //TODO: arg1: points, arg2: inTangents, arg3: outTangents, arg4: isClosed + auto arg1 = jerry_value_to_object(args[0]); + auto pathset = jerry_object_get_native_ptr(arg1, nullptr); + if (!pathset) { + TVGERR("LOTTIE", "failed createPath()"); + return jerry_undefined(); + } + + jerry_value_free(arg1); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, pathset); + return obj; +} + + +static jerry_value_t _uniformPath(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto pathset = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + + /* TODO: ThorVG prebuilds the path data for performance. + It actually need to constructs the Array for points, inTangents, outTangents and then return here... */ + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, pathset); + return obj; +} + + +static jerry_value_t _isClosed(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + //TODO: Not used + return jerry_boolean(true); +} + + +static void _buildPath(jerry_value_t context, LottieExpression* exp) +{ + //Trick for fast building path. + auto points = jerry_function_external(_uniformPath); + jerry_object_set_native_ptr(points, nullptr, exp->property); + jerry_object_set_sz(context, "points", points); + jerry_value_free(points); + + auto inTangents = jerry_function_external(_uniformPath); + jerry_object_set_native_ptr(inTangents, nullptr, exp->property); + jerry_object_set_sz(context, "inTangents", inTangents); + jerry_value_free(inTangents); + + auto outTangents = jerry_function_external(_uniformPath); + jerry_object_set_native_ptr(outTangents, nullptr, exp->property); + jerry_object_set_sz(context, "outTangents", outTangents); + jerry_value_free(outTangents); + + auto isClosed = jerry_function_external(_isClosed); + jerry_object_set_native_ptr(isClosed, nullptr, exp->property); + jerry_object_set_sz(context, "isClosed", isClosed); + jerry_value_free(isClosed); + +} + + +static void _buildProperty(float frameNo, jerry_value_t context, LottieExpression* exp) +{ + auto value = _value(frameNo, exp); + jerry_object_set_sz(context, EXP_VALUE, value); + jerry_value_free(value); + + auto valueAtTime = jerry_function_external(_valueAtTime); + jerry_object_set_sz(context, "valueAtTime", valueAtTime); + jerry_object_set_native_ptr(valueAtTime, nullptr, exp); + jerry_value_free(valueAtTime); + + auto velocity = jerry_number(0.0f); + jerry_object_set_sz(context, "velocity", velocity); + jerry_value_free(velocity); + + auto velocityAtTime = jerry_function_external(_velocityAtTime); + jerry_object_set_sz(context, "velocityAtTime", velocityAtTime); + jerry_object_set_native_ptr(velocityAtTime, nullptr, exp); + jerry_value_free(velocityAtTime); + + auto speed = jerry_number(0.0f); + jerry_object_set_sz(context, "speed", speed); + jerry_value_free(speed); + + auto speedAtTime = jerry_function_external(_speedAtTime); + jerry_object_set_sz(context, "speedAtTime", speedAtTime); + jerry_object_set_native_ptr(speedAtTime, nullptr, exp); + jerry_value_free(speedAtTime); + + //wiggle(freq, amp, octaves=1, amp_mult=.5, t=time) + //temporalWiggle(freq, amp, octaves=1, amp_mult=.5, t=time) + //smooth(width=.2, samples=5, t=time) + + auto loopIn = jerry_function_external(_loopIn); + jerry_object_set_sz(context, "loopIn", loopIn); + jerry_object_set_native_ptr(loopIn, nullptr, exp); + jerry_value_free(loopIn); + + auto loopOut = jerry_function_external(_loopOut); + jerry_object_set_sz(context, "loopOut", loopOut); + jerry_object_set_native_ptr(loopOut, nullptr, exp); + jerry_value_free(loopOut); + + auto loopInDuration = jerry_function_external(_loopInDuration); + jerry_object_set_sz(context, "loopInDuration", loopInDuration); + jerry_object_set_native_ptr(loopInDuration, nullptr, exp); + jerry_value_free(loopInDuration); + + auto loopOutDuration = jerry_function_external(_loopOutDuration); + jerry_object_set_sz(context, "loopOutDuration", loopOutDuration); + jerry_object_set_native_ptr(loopOutDuration, nullptr, exp); + jerry_value_free(loopOutDuration); + + auto key = jerry_function_external(_key); + jerry_object_set_sz(context, "key", key); + jerry_object_set_native_ptr(key, nullptr, exp); + jerry_value_free(key); + + //key(markerName) + + auto nearestKey = jerry_function_external(_nearestKey); + jerry_object_set_native_ptr(nearestKey, nullptr, exp); + jerry_object_set_sz(context, "nearestKey", nearestKey); + jerry_value_free(nearestKey); + + auto numKeys = jerry_number(exp->property->frameCnt()); + jerry_object_set_sz(context, "numKeys", numKeys); + jerry_value_free(numKeys); + + //propertyGroup(countUp = 1) + //propertyIndex + //name + + //content("name"), #look for the named property from a layer + auto data = (ExpContent*)malloc(sizeof(ExpContent)); + data->obj = exp->layer; + data->frameNo = frameNo; + + auto content = jerry_function_external(_content); + jerry_object_set_sz(context, EXP_CONTENT, content); + jerry_object_set_native_ptr(content, &freeCb, data); + jerry_value_free(content); +} + + +static jerry_value_t _comp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) +{ + auto comp = static_cast(jerry_object_get_native_ptr(info->function, nullptr)); + LottieLayer* layer; + + auto arg0 = jerry_value_to_string(args[0]); + auto len = jerry_string_length(arg0); + auto name = (jerry_char_t*)alloca(len * sizeof(jerry_char_t) + 1); + jerry_string_to_buffer(arg0, JERRY_ENCODING_UTF8, name, len); + name[len] = '\0'; + + jerry_value_free(arg0); + + layer = comp->asset((char*)name); + + if (!layer) return jerry_undefined(); + + auto obj = jerry_object(); + jerry_object_set_native_ptr(obj, nullptr, layer); + _buildLayer(obj, layer, comp); + + return obj; +} + + +static void _buildMath(jerry_value_t context) +{ + auto bm_mul = jerry_function_external(_mul); + jerry_object_set_sz(context, "$bm_mul", bm_mul); + jerry_value_free(bm_mul); + + auto bm_sum = jerry_function_external(_add); + jerry_object_set_sz(context, "$bm_sum", bm_sum); + jerry_value_free(bm_sum); + + auto bm_add = jerry_function_external(_add); + jerry_object_set_sz(context, "$bm_add", bm_add); + jerry_value_free(bm_add); + + auto bm_sub = jerry_function_external(_sub); + jerry_object_set_sz(context, "$bm_sub", bm_sub); + jerry_value_free(bm_sub); + + auto bm_div = jerry_function_external(_div); + jerry_object_set_sz(context, "$bm_div", bm_div); + jerry_value_free(bm_div); + + auto mul = jerry_function_external(_mul); + jerry_object_set_sz(context, "mul", mul); + jerry_value_free(mul); + + auto sum = jerry_function_external(_add); + jerry_object_set_sz(context, "sum", sum); + jerry_value_free(sum); + + auto add = jerry_function_external(_add); + jerry_object_set_sz(context, "add", add); + jerry_value_free(add); + + auto sub = jerry_function_external(_sub); + jerry_object_set_sz(context, "sub", sub); + jerry_value_free(sub); + + auto div = jerry_function_external(_div); + jerry_object_set_sz(context, "div", div); + jerry_value_free(div); + + auto clamp = jerry_function_external(_clamp); + jerry_object_set_sz(context, "clamp", clamp); + jerry_value_free(clamp); + + auto dot = jerry_function_external(_dot); + jerry_object_set_sz(context, "dot", dot); + jerry_value_free(dot); + + auto cross = jerry_function_external(_cross); + jerry_object_set_sz(context, "cross", cross); + jerry_value_free(cross); + + auto normalize = jerry_function_external(_normalize); + jerry_object_set_sz(context, "normalize", normalize); + jerry_value_free(normalize); + + auto length = jerry_function_external(_length); + jerry_object_set_sz(context, "length", length); + jerry_value_free(length); + + auto random = jerry_function_external(_random); + jerry_object_set_sz(context, "random", random); + jerry_value_free(random); + + auto deg2rad = jerry_function_external(_deg2rad); + jerry_object_set_sz(context, "degreesToRadians", deg2rad); + jerry_value_free(deg2rad); + + auto rad2deg = jerry_function_external(_rad2deg); + jerry_object_set_sz(context, "radiansToDegrees", rad2deg); + jerry_value_free(rad2deg); + + auto linear = jerry_function_external(_linear); + jerry_object_set_sz(context, "linear", linear); + jerry_value_free(linear); + + auto ease = jerry_function_external(_ease); + jerry_object_set_sz(context, "ease", ease); + jerry_value_free(ease); + + auto easeIn = jerry_function_external(_easeIn); + jerry_object_set_sz(context, "easeIn", easeIn); + jerry_value_free(easeIn); + + auto easeOut = jerry_function_external(_easeOut); + jerry_object_set_sz(context, "easeOut", easeOut); + jerry_value_free(easeOut); + + //lookAt +} + + +void LottieExpressions::buildComp(LottieComposition* comp) +{ + jerry_object_set_native_ptr(this->comp, nullptr, comp); + jerry_object_set_native_ptr(thisComp, nullptr, comp); + jerry_object_set_native_ptr(layer, nullptr, comp); + + //marker + //marker.key(index) + //marker.key(name) + //marker.nearestKey(t) + //marker.numKeys + + auto numLayers = jerry_number(comp->root->children.count); + jerry_object_set_sz(thisComp, "numLayers", numLayers); + jerry_value_free(numLayers); + + //activeCamera + + auto width = jerry_number(comp->w); + jerry_object_set_sz(thisComp, EXP_WIDTH, width); + jerry_value_free(width); + + auto height = jerry_number(comp->h); + jerry_object_set_sz(thisComp, EXP_HEIGHT, height); + jerry_value_free(height); + + auto duration = jerry_number(comp->duration()); + jerry_object_set_sz(thisComp, "duration", duration); + jerry_value_free(duration); + + //ntscDropFrame + //displayStartTime + + auto frameDuration = jerry_number(1.0f / comp->frameRate); + jerry_object_set_sz(thisComp, "frameDuration", frameDuration); + jerry_value_free(frameDuration); + + //shutterAngle + //shutterPhase + //bgColor + //pixelAspect + + auto name = jerry_string((jerry_char_t*)comp->name, strlen(comp->name), JERRY_ENCODING_UTF8); + jerry_object_set_sz(thisComp, EXP_NAME, name); + jerry_value_free(name); +} + + +jerry_value_t LottieExpressions::buildGlobal() +{ + global = jerry_current_realm(); + + //comp(name) + comp = jerry_function_external(_comp); + jerry_object_set_sz(global, "comp", comp); + + //footage(name) + + thisComp = jerry_object(); + jerry_object_set_sz(global, "thisComp", thisComp); + + //layer(index) / layer(name) / layer(otherLayer, reIndex) + layer = jerry_function_external(_layer); + jerry_object_set_sz(thisComp, "layer", layer); + + thisLayer = jerry_object(); + jerry_object_set_sz(global, "thisLayer", thisLayer); + + thisProperty = jerry_object(); + jerry_object_set_sz(global, "thisProperty", thisProperty); + + auto effect = jerry_function_external(_effect); + jerry_object_set_sz(global, EXP_EFFECT, effect); + jerry_value_free(effect); + + auto fromCompToSurface = jerry_function_external(_fromCompToSurface); + jerry_object_set_sz(global, "fromCompToSurface", fromCompToSurface); + jerry_value_free(fromCompToSurface); + + auto createPath = jerry_function_external(_createPath); + jerry_object_set_sz(global, "createPath", createPath); + jerry_value_free(createPath); + + //posterizeTime(framesPerSecond) + //value + + return global; +} + + +jerry_value_t LottieExpressions::evaluate(float frameNo, LottieExpression* exp) +{ + buildComp(exp->comp); + + //update global context values + jerry_object_set_native_ptr(thisLayer, nullptr, exp->layer); + _buildLayer(thisLayer, exp->layer, exp->comp); + + jerry_object_set_native_ptr(thisProperty, nullptr, exp->property); + _buildProperty(frameNo, global, exp); + + if (exp->type == LottieProperty::Type::PathSet) _buildPath(thisProperty, exp); + if (exp->object->type == LottieObject::Transform) _buildTransform(global, static_cast(exp->object)); + + //evaluate the code + auto eval = jerry_eval((jerry_char_t *) exp->code, strlen(exp->code), JERRY_PARSE_NO_OPTS); + + if (jerry_value_is_exception(eval) || jerry_value_is_undefined(eval)) { + exp->enabled = false; // The feature is experimental, it will be forcefully turned off if it's incompatible. + return jerry_undefined(); + } + + jerry_value_free(eval); + + return jerry_object_get_sz(global, "$bm_rt"); +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LottieExpressions::~LottieExpressions() +{ + jerry_value_free(thisProperty); + jerry_value_free(thisLayer); + jerry_value_free(layer); + jerry_value_free(thisComp); + jerry_value_free(comp); + jerry_value_free(global); + jerry_cleanup(); +} + + +LottieExpressions::LottieExpressions() +{ + jerry_init(JERRY_INIT_EMPTY); + _buildMath(buildGlobal()); +} + + +void LottieExpressions::update(float curTime) +{ + //time, #current time in seconds + auto time = jerry_number(curTime); + jerry_object_set_sz(global, EXP_TIME, time); + jerry_value_free(time); +} + + +//FIXME: Threads support +#include "tvgTaskScheduler.h" + +LottieExpressions* LottieExpressions::instance() +{ + //FIXME: Threads support + if (TaskScheduler::threads() > 1) { + TVGLOG("LOTTIE", "Lottie Expressions are not supported with tvg threads"); + return nullptr; + } + + if (!exps) exps = new LottieExpressions; + ++engineRefCnt; + return exps; +} + + +void LottieExpressions::retrieve(LottieExpressions* instance) +{ + if (--engineRefCnt == 0) { + delete(instance); + exps = nullptr; + } +} + + +#endif //THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.h new file mode 100644 index 000000000..14819a8fe --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieExpressions.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_EXPRESSIONS_H_ +#define _TVG_LOTTIE_EXPRESSIONS_H_ + +#include "tvgCommon.h" + +struct LottieExpression; +struct LottieComposition; +struct RGB24; + +#ifdef THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +#include "jerryscript.h" + + +struct LottieExpressions +{ +public: + template + bool result(float frameNo, NumType& out, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto prop = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + out = (*prop)(frameNo); + } else if (jerry_value_is_number(bm_rt)) { + out = (NumType) jerry_value_as_number(bm_rt); + } else { + TVGERR("LOTTIE", "Failed dispatching a Value!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, Point& out, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (jerry_value_is_object(bm_rt)) { + if (auto prop = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + out = (*prop)(frameNo); + } else { + auto x = jerry_object_get_index(bm_rt, 0); + auto y = jerry_object_get_index(bm_rt, 1); + out.x = jerry_value_as_number(x); + out.y = jerry_value_as_number(y); + jerry_value_free(x); + jerry_value_free(y); + } + } else { + TVGERR("LOTTIE", "Failed dispatching Point!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, RGB24& out, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto color = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + out = (*color)(frameNo); + } else { + TVGERR("LOTTIE", "Failed dispatching Color!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, Fill* fill, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto colorStop = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + (*colorStop)(frameNo, fill, this); + } else { + TVGERR("LOTTIE", "Failed dispatching ColorStop!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + template + bool result(float frameNo, Array& cmds, Array& pts, Matrix* transform, float roundness, LottieExpression* exp) + { + auto bm_rt = evaluate(frameNo, exp); + + if (auto pathset = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { + (*pathset)(frameNo, cmds, pts, transform, roundness); + } else { + TVGERR("LOTTIE", "Failed dispatching PathSet!"); + return false; + } + jerry_value_free(bm_rt); + return true; + } + + void update(float curTime); + + //singleton (no thread safety) + static LottieExpressions* instance(); + static void retrieve(LottieExpressions* instance); + +private: + LottieExpressions(); + ~LottieExpressions(); + + jerry_value_t evaluate(float frameNo, LottieExpression* exp); + jerry_value_t buildGlobal(); + void buildComp(LottieComposition* comp); + + //global object, attributes, methods + jerry_value_t global; + jerry_value_t comp; + jerry_value_t layer; + jerry_value_t thisComp; + jerry_value_t thisLayer; + jerry_value_t thisProperty; +}; + +#else + +struct LottieExpressions +{ + template bool result(TVG_UNUSED float, TVG_UNUSED NumType&, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED Point&, LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED RGB24&, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED Fill*, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED Array&, TVG_UNUSED Array&, TVG_UNUSED Matrix* transform, TVG_UNUSED float, TVG_UNUSED LottieExpression*) { return false; } + void update(TVG_UNUSED float) {} + static LottieExpressions* instance() { return nullptr; } + static void retrieve(TVG_UNUSED LottieExpressions* instance) {} +}; + +#endif //THORVG_LOTTIE_EXPRESSIONS_SUPPORT + +#endif //_TVG_LOTTIE_EXPRESSIONS_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.cpp new file mode 100644 index 000000000..c92bfb6e8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "tvgCommon.h" +#include "tvgMath.h" +#include "tvgLottieInterpolator.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define NEWTON_MIN_SLOPE 0.02f +#define NEWTON_ITERATIONS 4 +#define SUBDIVISION_PRECISION 0.0000001f +#define SUBDIVISION_MAX_ITERATIONS 10 + + +static inline float _constA(float aA1, float aA2) { return 1.0f - 3.0f * aA2 + 3.0f * aA1; } +static inline float _constB(float aA1, float aA2) { return 3.0f * aA2 - 6.0f * aA1; } +static inline float _constC(float aA1) { return 3.0f * aA1; } + + +static inline float _getSlope(float t, float aA1, float aA2) +{ + return 3.0f * _constA(aA1, aA2) * t * t + 2.0f * _constB(aA1, aA2) * t + _constC(aA1); +} + + +static inline float _calcBezier(float t, float aA1, float aA2) +{ + return ((_constA(aA1, aA2) * t + _constB(aA1, aA2)) * t + _constC(aA1)) * t; +} + + +float LottieInterpolator::getTForX(float aX) +{ + //Find interval where t lies + auto intervalStart = 0.0f; + auto currentSample = &samples[1]; + auto lastSample = &samples[SPLINE_TABLE_SIZE - 1]; + + for (; currentSample != lastSample && *currentSample <= aX; ++currentSample) { + intervalStart += SAMPLE_STEP_SIZE; + } + + --currentSample; // t now lies between *currentSample and *currentSample+1 + + // Interpolate to provide an initial guess for t + auto dist = (aX - *currentSample) / (*(currentSample + 1) - *currentSample); + auto guessForT = intervalStart + dist * SAMPLE_STEP_SIZE; + + // Check the slope to see what strategy to use. If the slope is too small + // Newton-Raphson iteration won't converge on a root so we use bisection + // instead. + auto initialSlope = _getSlope(guessForT, outTangent.x, inTangent.x); + if (initialSlope >= NEWTON_MIN_SLOPE) return NewtonRaphsonIterate(aX, guessForT); + else if (initialSlope == 0.0) return guessForT; + else return binarySubdivide(aX, intervalStart, intervalStart + SAMPLE_STEP_SIZE); +} + + +float LottieInterpolator::binarySubdivide(float aX, float aA, float aB) +{ + float x, t; + int i = 0; + + do { + t = aA + (aB - aA) / 2.0f; + x = _calcBezier(t, outTangent.x, inTangent.x) - aX; + if (x > 0.0f) aB = t; + else aA = t; + } while (fabsf(x) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + return t; +} + + +float LottieInterpolator::NewtonRaphsonIterate(float aX, float aGuessT) +{ + // Refine guess with Newton-Raphson iteration + for (int i = 0; i < NEWTON_ITERATIONS; ++i) { + // We're trying to find where f(t) = aX, + // so we're actually looking for a root for: CalcBezier(t) - aX + auto currentX = _calcBezier(aGuessT, outTangent.x, inTangent.x) - aX; + auto currentSlope = _getSlope(aGuessT, outTangent.x, inTangent.x); + if (currentSlope == 0.0f) return aGuessT; + aGuessT -= currentX / currentSlope; + } + return aGuessT; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +float LottieInterpolator::progress(float t) +{ + if (outTangent.x == outTangent.y && inTangent.x == inTangent.y) return t; + return _calcBezier(getTForX(t), outTangent.y, inTangent.y); +} + + +void LottieInterpolator::set(const char* key, Point& inTangent, Point& outTangent) +{ + this->key = strdup(key); + this->inTangent = inTangent; + this->outTangent = outTangent; + + if (outTangent.x == outTangent.y && inTangent.x == inTangent.y) return; + + //calculates sample values + for (int i = 0; i < SPLINE_TABLE_SIZE; ++i) { + samples[i] = _calcBezier(float(i) * SAMPLE_STEP_SIZE, outTangent.x, inTangent.x); + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.h new file mode 100644 index 000000000..c7d07d47d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieInterpolator.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_INTERPOLATOR_H_ +#define _TVG_LOTTIE_INTERPOLATOR_H_ + +#define SPLINE_TABLE_SIZE 11 + +struct LottieInterpolator +{ + char* key; + Point outTangent, inTangent; + + float progress(float t); + void set(const char* key, Point& inTangent, Point& outTangent); + +private: + static constexpr float SAMPLE_STEP_SIZE = 1.0f / float(SPLINE_TABLE_SIZE - 1); + float samples[SPLINE_TABLE_SIZE]; + + float getTForX(float aX); + float binarySubdivide(float aX, float aA, float aB); + float NewtonRaphsonIterate(float aX, float aGuessT); +}; + +#endif //_TVG_LOTTIE_INTERPOLATOR_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.cpp new file mode 100644 index 000000000..8230211a6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.cpp @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgLottieLoader.h" +#include "tvgLottieModel.h" +#include "tvgLottieParser.h" +#include "tvgLottieBuilder.h" +#include "tvgStr.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +void LottieLoader::run(unsigned tid) +{ + //update frame + if (comp) { + builder->update(comp, frameNo); + //initial loading + } else { + LottieParser parser(content, dirName); + if (!parser.parse()) return; + comp = parser.comp; + builder->build(comp); + } + rebuild = false; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +LottieLoader::LottieLoader() : FrameModule(FileType::Lottie), builder(new LottieBuilder) +{ + +} + + +LottieLoader::~LottieLoader() +{ + this->done(); + + if (copy) free((char*)content); + free(dirName); + + //TODO: correct position? + delete(comp); + delete(builder); +} + + +bool LottieLoader::header() +{ + //A single thread doesn't need to perform intensive tasks. + if (TaskScheduler::threads() == 0) { + run(0); + if (comp) { + w = static_cast(comp->w); + h = static_cast(comp->h); + frameDuration = comp->duration(); + frameCnt = comp->frameCnt(); + return true; + } else { + return false; + } + } + + //Quickly validate the given Lottie file without parsing in order to get the animation info. + auto startFrame = 0.0f; + auto endFrame = 0.0f; + auto frameRate = 0.0f; + uint32_t depth = 0; + + auto p = content; + + while (*p != '\0') { + if (*p == '{') { + ++depth; + ++p; + continue; + } + if (*p == '}') { + --depth; + ++p; + continue; + } + if (depth != 1) { + ++p; + continue; + } + //version. + if (!strncmp(p, "\"v\":", 4)) { + p += 4; + continue; + } + + //framerate + if (!strncmp(p, "\"fr\":", 5)) { + p += 5; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + frameRate = strToFloat(p, nullptr); + p = e; + continue; + } + + //start frame + if (!strncmp(p, "\"ip\":", 5)) { + p += 5; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + startFrame = strToFloat(p, nullptr); + p = e; + continue; + } + + //end frame + if (!strncmp(p, "\"op\":", 5)) { + p += 5; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + endFrame = strToFloat(p, nullptr); + p = e; + continue; + } + + //width + if (!strncmp(p, "\"w\":", 4)) { + p += 4; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + w = strToFloat(p, nullptr); + p = e; + continue; + } + //height + if (!strncmp(p, "\"h\":", 4)) { + p += 4; + auto e = strstr(p, ","); + if (!e) e = strstr(p, "}"); + h = strToFloat(p, nullptr); + p = e; + continue; + } + ++p; + } + + if (frameRate < FLOAT_EPSILON) { + TVGLOG("LOTTIE", "Not a Lottie file? Frame rate is 0!"); + return false; + } + + frameCnt = (endFrame - startFrame); + frameDuration = frameCnt / frameRate; + + TVGLOG("LOTTIE", "info: frame rate = %f, duration = %f size = %f x %f", frameRate, frameDuration, w, h); + + return true; +} + + +bool LottieLoader::open(const char* data, uint32_t size, bool copy) +{ + if (copy) { + content = (char*)malloc(size); + if (!content) return false; + memcpy((char*)content, data, size); + } else content = data; + + this->size = size; + this->copy = copy; + + return header(); +} + + +bool LottieLoader::open(const string& path) +{ + auto f = fopen(path.c_str(), "r"); + if (!f) return false; + + fseek(f, 0, SEEK_END); + + size = ftell(f); + if (size == 0) { + fclose(f); + return false; + } + + auto content = (char*)(malloc(sizeof(char) * size + 1)); + fseek(f, 0, SEEK_SET); + auto ret = fread(content, sizeof(char), size, f); + if (ret < size) { + fclose(f); + return false; + } + content[size] = '\0'; + + fclose(f); + + this->dirName = strDirname(path.c_str()); + this->content = content; + this->copy = true; + + return header(); +} + + +bool LottieLoader::resize(Paint* paint, float w, float h) +{ + if (!paint) return false; + + auto sx = w / this->w; + auto sy = h / this->h; + Matrix m = {sx, 0, 0, 0, sy, 0, 0, 0, 1}; + paint->transform(m); + + //apply the scale to the base clipper + const Paint* clipper; + paint->composite(&clipper); + if (clipper) const_cast(clipper)->transform(m); + + return true; +} + + +bool LottieLoader::read() +{ + if (!content || size == 0) return false; + + //the loading has been already completed + if (comp || !LoadModule::read()) return true; + + TaskScheduler::request(this); + + return true; +} + + +Paint* LottieLoader::paint() +{ + done(); + + if (!comp) return nullptr; + comp->initiated = true; + return comp->root->scene; +} + + +bool LottieLoader::override(const char* slot) +{ + if (!comp) done(); + + if (!comp || comp->slots.count == 0) return false; + + auto success = true; + + //override slots + if (slot) { + //Copy the input data because the JSON parser will encode the data immediately. + auto temp = strdup(slot); + + //parsing slot json + LottieParser parser(temp, dirName); + + auto idx = 0; + while (auto sid = parser.sid(idx == 0)) { + for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) { + if (strcmp((*s)->sid, sid)) continue; + if (!parser.apply(*s)) success = false; + break; + } + ++idx; + } + + if (idx < 1) success = false; + free(temp); + rebuild = overridden = success; + //reset slots + } else if (overridden) { + for (auto s = comp->slots.begin(); s < comp->slots.end(); ++s) { + (*s)->reset(); + } + overridden = false; + rebuild = true; + } + return success; +} + + +bool LottieLoader::frame(float no) +{ + auto frameNo = no + startFrame(); + + //This ensures that the target frame number is reached. + frameNo *= 10000.0f; + frameNo = roundf(frameNo); + frameNo *= 0.0001f; + + //Skip update if frame diff is too small. + if (fabsf(this->frameNo - frameNo) <= 0.0009f) return false; + + this->done(); + + this->frameNo = frameNo; + + TaskScheduler::request(this); + + return true; +} + + +float LottieLoader::startFrame() +{ + return frameCnt * segmentBegin; +} + + +float LottieLoader::totalFrame() +{ + return (segmentEnd - segmentBegin) * frameCnt; +} + + +float LottieLoader::curFrame() +{ + return frameNo - startFrame(); +} + + +float LottieLoader::duration() +{ + if (segmentBegin == 0.0f && segmentEnd == 1.0f) return frameDuration; + + if (!comp) done(); + if (!comp) return 0.0f; + + return frameCnt * (segmentEnd - segmentBegin) / comp->frameRate; +} + + +void LottieLoader::sync() +{ + this->done(); + + if (rebuild) run(0); +} + + +uint32_t LottieLoader::markersCnt() +{ + if (!comp) done(); + if (!comp) return 0; + return comp->markers.count; +} + + +const char* LottieLoader::markers(uint32_t index) +{ + if (!comp) done(); + if (!comp || index >= comp->markers.count) return nullptr; + auto marker = comp->markers.begin() + index; + return (*marker)->name; +} + + +bool LottieLoader::segment(const char* marker, float& begin, float& end) +{ + if (!comp) done(); + if (!comp) return false; + + for (auto m = comp->markers.begin(); m < comp->markers.end(); ++m) { + if (!strcmp(marker, (*m)->name)) { + begin = (*m)->time / frameCnt; + end = ((*m)->time + (*m)->duration) / frameCnt; + return true; + } + } + return false; +} + + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.h new file mode 100644 index 000000000..57ad9b7f2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieLoader.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_LOADER_H_ +#define _TVG_LOTTIE_LOADER_H_ + +#include "tvgCommon.h" +#include "tvgFrameModule.h" +#include "tvgTaskScheduler.h" + +struct LottieComposition; +struct LottieBuilder; + +class LottieLoader : public FrameModule, public Task +{ +public: + const char* content = nullptr; //lottie file data + uint32_t size = 0; //lottie data size + float frameNo = 0.0f; //current frame number + float frameCnt = 0.0f; + float frameDuration = 0.0f; + + LottieBuilder* builder; + LottieComposition* comp = nullptr; + + char* dirName = nullptr; //base resource directory + bool copy = false; //"content" is owned by this loader + bool overridden = false; //overridden properties with slots + bool rebuild = false; //require building the lottie scene + + LottieLoader(); + ~LottieLoader(); + + bool open(const string& path) override; + bool open(const char* data, uint32_t size, bool copy) override; + bool resize(Paint* paint, float w, float h) override; + bool read() override; + Paint* paint() override; + bool override(const char* slot); + + //Frame Controls + bool frame(float no) override; + float totalFrame() override; + float curFrame() override; + float duration() override; + void sync() override; + + //Marker Supports + uint32_t markersCnt(); + const char* markers(uint32_t index); + bool segment(const char* marker, float& begin, float& end); + +private: + bool header(); + void clear(); + float startFrame(); + void run(unsigned tid) override; +}; + + +#endif //_TVG_LOTTIELOADER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.cpp new file mode 100644 index 000000000..5230adb4b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.cpp @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgPaint.h" +#include "tvgFill.h" +#include "tvgLottieModel.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void LottieSlot::reset() +{ + if (!overridden) return; + + for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { + switch (type) { + case LottieProperty::Type::ColorStop: { + static_cast(pair->obj)->colorStops.release(); + static_cast(pair->obj)->colorStops = *static_cast(pair->prop); + static_cast(pair->prop)->frames = nullptr; + break; + } + case LottieProperty::Type::Color: { + static_cast(pair->obj)->color.release(); + static_cast(pair->obj)->color = *static_cast(pair->prop); + static_cast(pair->prop)->frames = nullptr; + break; + } + case LottieProperty::Type::TextDoc: { + static_cast(pair->obj)->doc.release(); + static_cast(pair->obj)->doc = *static_cast(pair->prop); + static_cast(pair->prop)->frames = nullptr; + break; + } + default: break; + } + delete(pair->prop); + pair->prop = nullptr; + } + overridden = false; +} + + +void LottieSlot::assign(LottieObject* target) +{ + //apply slot object to all targets + for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { + //backup the original properties before overwriting + switch (type) { + case LottieProperty::Type::ColorStop: { + if (!overridden) { + pair->prop = new LottieColorStop; + *static_cast(pair->prop) = static_cast(pair->obj)->colorStops; + } + + pair->obj->override(&static_cast(target)->colorStops); + break; + } + case LottieProperty::Type::Color: { + if (!overridden) { + pair->prop = new LottieColor; + *static_cast(pair->prop) = static_cast(pair->obj)->color; + } + + pair->obj->override(&static_cast(target)->color); + break; + } + case LottieProperty::Type::TextDoc: { + if (!overridden) { + pair->prop = new LottieTextDoc; + *static_cast(pair->prop) = static_cast(pair->obj)->doc; + } + + pair->obj->override(&static_cast(target)->doc); + break; + } + default: break; + } + } + overridden = true; +} + + +LottieImage::~LottieImage() +{ + free(b64Data); + free(mimeType); + + if (picture && PP(picture)->unref() == 0) { + delete(picture); + } +} + + +void LottieTrimpath::segment(float frameNo, float& start, float& end, LottieExpressions* exps) +{ + auto s = this->start(frameNo, exps) * 0.01f; + auto e = this->end(frameNo, exps) * 0.01f; + auto o = fmodf(this->offset(frameNo, exps), 360.0f) / 360.0f; //0 ~ 1 + + auto diff = fabs(s - e); + if (mathZero(diff)) { + start = 0.0f; + end = 0.0f; + return; + } + if (mathEqual(diff, 1.0f) || mathEqual(diff, 2.0f)) { + start = 0.0f; + end = 1.0f; + return; + } + + s += o; + e += o; + + auto loop = true; + + //no loop + if (s > 1.0f && e > 1.0f) loop = false; + if (s < 0.0f && e < 0.0f) loop = false; + if (s >= 0.0f && s <= 1.0f && e >= 0.0f && e <= 1.0f) loop = false; + + if (s > 1.0f) s -= 1.0f; + if (s < 0.0f) s += 1.0f; + if (e > 1.0f) e -= 1.0f; + if (e < 0.0f) e += 1.0f; + + if (loop) { + start = s > e ? s : e; + end = s < e ? s : e; + } else { + start = s < e ? s : e; + end = s > e ? s : e; + } +} + + +uint32_t LottieGradient::populate(ColorStop& color) +{ + colorStops.populated = true; + if (!color.input) return 0; + + uint32_t alphaCnt = (color.input->count - (colorStops.count * 4)) / 2; + Array output(colorStops.count + alphaCnt); + uint32_t cidx = 0; //color count + uint32_t clast = colorStops.count * 4; + if (clast > color.input->count) clast = color.input->count; + uint32_t aidx = clast; //alpha count + Fill::ColorStop cs; + + //merge color stops. + for (uint32_t i = 0; i < color.input->count; ++i) { + if (cidx == clast || aidx == color.input->count) break; + if ((*color.input)[cidx] == (*color.input)[aidx]) { + cs.offset = (*color.input)[cidx]; + cs.r = lroundf((*color.input)[cidx + 1] * 255.0f); + cs.g = lroundf((*color.input)[cidx + 2] * 255.0f); + cs.b = lroundf((*color.input)[cidx + 3] * 255.0f); + cs.a = lroundf((*color.input)[aidx + 1] * 255.0f); + cidx += 4; + aidx += 2; + } else if ((*color.input)[cidx] < (*color.input)[aidx]) { + cs.offset = (*color.input)[cidx]; + cs.r = lroundf((*color.input)[cidx + 1] * 255.0f); + cs.g = lroundf((*color.input)[cidx + 2] * 255.0f); + cs.b = lroundf((*color.input)[cidx + 3] * 255.0f); + //generate alpha value + if (output.count > 0) { + auto p = ((*color.input)[cidx] - output.last().offset) / ((*color.input)[aidx] - output.last().offset); + cs.a = mathLerp(output.last().a, lroundf((*color.input)[aidx + 1] * 255.0f), p); + } else cs.a = 255; + cidx += 4; + } else { + cs.offset = (*color.input)[aidx]; + cs.a = lroundf((*color.input)[aidx + 1] * 255.0f); + //generate color value + if (output.count > 0) { + auto p = ((*color.input)[aidx] - output.last().offset) / ((*color.input)[cidx] - output.last().offset); + cs.r = mathLerp(output.last().r, lroundf((*color.input)[cidx + 1] * 255.0f), p); + cs.g = mathLerp(output.last().g, lroundf((*color.input)[cidx + 2] * 255.0f), p); + cs.b = mathLerp(output.last().b, lroundf((*color.input)[cidx + 3] * 255.0f), p); + } else cs.r = cs.g = cs.b = 255; + aidx += 2; + } + output.push(cs); + } + + //color remains + while (cidx + 3 < clast) { + cs.offset = (*color.input)[cidx]; + cs.r = lroundf((*color.input)[cidx + 1] * 255.0f); + cs.g = lroundf((*color.input)[cidx + 2] * 255.0f); + cs.b = lroundf((*color.input)[cidx + 3] * 255.0f); + cs.a = (output.count > 0) ? output.last().a : 255; + output.push(cs); + cidx += 4; + } + + //alpha remains + while (aidx < color.input->count) { + cs.offset = (*color.input)[aidx]; + cs.a = lroundf((*color.input)[aidx + 1] * 255.0f); + if (output.count > 0) { + cs.r = output.last().r; + cs.g = output.last().g; + cs.b = output.last().b; + } else cs.r = cs.g = cs.b = 255; + output.push(cs); + aidx += 2; + } + + color.data = output.data; + output.data = nullptr; + + color.input->reset(); + delete(color.input); + + return output.count; +} + + +Fill* LottieGradient::fill(float frameNo, LottieExpressions* exps) +{ + Fill* fill = nullptr; + auto s = start(frameNo, exps); + auto e = end(frameNo, exps); + + //Linear Gradient + if (id == 1) { + fill = LinearGradient::gen().release(); + static_cast(fill)->linear(s.x, s.y, e.x, e.y); + } + //Radial Gradient + if (id == 2) { + fill = RadialGradient::gen().release(); + + auto w = fabsf(e.x - s.x); + auto h = fabsf(e.y - s.y); + auto r = (w > h) ? (w + 0.375f * h) : (h + 0.375f * w); + auto progress = this->height(frameNo, exps) * 0.01f; + + if (mathZero(progress)) { + P(static_cast(fill))->radial(s.x, s.y, r, s.x, s.y, 0.0f); + } else { + if (mathEqual(progress, 1.0f)) progress = 0.99f; + auto startAngle = mathRad2Deg(atan2(e.y - s.y, e.x - s.x)); + auto angle = mathDeg2Rad((startAngle + this->angle(frameNo, exps))); + auto fx = s.x + cos(angle) * progress * r; + auto fy = s.y + sin(angle) * progress * r; + // Lottie doesn't have any focal radius concept + P(static_cast(fill))->radial(s.x, s.y, r, fx, fy, 0.0f); + } + } + + if (!fill) return nullptr; + + colorStops(frameNo, fill, exps); + + return fill; +} + + +void LottieGroup::prepare(LottieObject::Type type) +{ + LottieObject::type = type; + + if (children.count == 0) return; + + size_t strokeCnt = 0; + size_t fillCnt = 0; + + for (auto c = children.end() - 1; c >= children.begin(); --c) { + auto child = static_cast(*c); + + if (child->type == LottieObject::Type::Trimpath) trimpath = true; + + /* Figure out if this group is a simple path drawing. + In that case, the rendering context can be sharable with the parent's. */ + if (allowMerge && (child->type == LottieObject::Group || !child->mergeable())) allowMerge = false; + + if (reqFragment) continue; + + /* Figure out if the rendering context should be fragmented. + Multiple stroking or grouping with a stroking would occur this. + This fragment resolves the overlapped stroke outlines. */ + if (child->type == LottieObject::Group && !child->mergeable()) { + if (strokeCnt > 0 || fillCnt > 0) reqFragment = true; + } else if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) { + if (strokeCnt > 0) reqFragment = true; + else ++strokeCnt; + } else if (child->type == LottieObject::SolidFill || child->type == LottieObject::GradientFill) { + if (fillCnt > 0) reqFragment = true; + else ++fillCnt; + } + } + + //Reverse the drawing order if this group has a trimpath. + if (!trimpath) return; + + for (uint32_t i = 0; i < children.count - 1; ) { + auto child2 = children[i + 1]; + if (!child2->mergeable() || child2->type == LottieObject::Transform) { + i += 2; + continue; + } + auto child = children[i]; + if (!child->mergeable() || child->type == LottieObject::Transform) { + i++; + continue; + } + children[i] = child2; + children[i + 1] = child; + i++; + } +} + + +LottieLayer::~LottieLayer() +{ + if (refId) { + //No need to free assets children because the Composition owns them. + children.clear(); + free(refId); + } + + for (auto m = masks.begin(); m < masks.end(); ++m) { + delete(*m); + } + + delete(matte.target); + delete(transform); +} + +void LottieLayer::prepare() +{ + /* if layer is hidden, only useful data is its transform matrix. + so force it to be a Null Layer and release all resource. */ + if (hidden) { + type = LottieLayer::Null; + for (auto p = children.begin(); p < children.end(); ++p) delete(*p); + children.reset(); + return; + } + LottieGroup::prepare(LottieObject::Layer); +} + + +float LottieLayer::remap(float frameNo, LottieExpressions* exp) +{ + if (timeRemap.frames || timeRemap.value) { + frameNo = comp->frameAtTime(timeRemap(frameNo, exp)); + } else { + frameNo -= startFrame; + } + return (frameNo / timeStretch); +} + + +LottieComposition::~LottieComposition() +{ + if (!initiated && root) delete(root->scene); + + delete(root); + free(version); + free(name); + + //delete interpolators + for (auto i = interpolators.begin(); i < interpolators.end(); ++i) { + free((*i)->key); + free(*i); + } + + //delete assets + for (auto a = assets.begin(); a < assets.end(); ++a) { + delete(*a); + } + + //delete fonts + for (auto f = fonts.begin(); f < fonts.end(); ++f) { + delete(*f); + } + + //delete slots + for (auto s = slots.begin(); s < slots.end(); ++s) { + delete(*s); + } + + for (auto m = markers.begin(); m < markers.end(); ++m) { + delete(*m); + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.h new file mode 100644 index 000000000..6ba92de1c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModel.h @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_MODEL_H_ +#define _TVG_LOTTIE_MODEL_H_ + +#include + +#include "tvgCommon.h" +#include "tvgRender.h" +#include "tvgLottieProperty.h" + + +struct LottieComposition; + +struct LottieStroke +{ + struct DashAttr + { + //0: offset, 1: dash, 2: gap + LottieFloat value[3] = {0.0f, 0.0f, 0.0f}; + }; + + virtual ~LottieStroke() + { + delete(dashattr); + } + + LottieFloat& dash(int no) + { + if (!dashattr) dashattr = new DashAttr; + return dashattr->value[no]; + } + + float dashOffset(float frameNo, LottieExpressions* exps) + { + return dash(0)(frameNo, exps); + } + + float dashGap(float frameNo, LottieExpressions* exps) + { + return dash(2)(frameNo, exps); + } + + float dashSize(float frameNo, LottieExpressions* exps) + { + auto d = dash(1)(frameNo, exps); + if (d == 0.0f) return 0.1f; + else return d; + } + + LottieFloat width = 0.0f; + DashAttr* dashattr = nullptr; + float miterLimit = 0; + StrokeCap cap = StrokeCap::Round; + StrokeJoin join = StrokeJoin::Round; +}; + + +struct LottieMask +{ + LottiePathSet pathset; + LottieOpacity opacity = 255; + CompositeMethod method; + bool inverse = false; +}; + + +struct LottieObject +{ + enum Type : uint8_t + { + Composition = 0, + Layer, + Group, + Transform, + SolidFill, + SolidStroke, + GradientFill, + GradientStroke, + Rect, + Ellipse, + Path, + Polystar, + Image, + Trimpath, + Text, + Repeater, + RoundedCorner + }; + + virtual ~LottieObject() + { + free(name); + } + + virtual void override(LottieProperty* prop) + { + TVGERR("LOTTIE", "Unsupported slot type"); + } + + virtual bool mergeable() { return false; } + + char* name = nullptr; + Type type; + bool hidden = false; //remove? +}; + + +struct LottieGlyph +{ + Array children; //glyph shapes. + float width; + char* code; + char* family = nullptr; + char* style = nullptr; + uint16_t size; + uint8_t len; + + void prepare() + { + len = strlen(code); + } + + ~LottieGlyph() + { + for (auto p = children.begin(); p < children.end(); ++p) delete(*p); + free(code); + } +}; + + +struct LottieFont +{ + enum Origin : uint8_t { Local = 0, CssURL, ScriptURL, FontURL, Embedded }; + + ~LottieFont() + { + for (auto c = chars.begin(); c < chars.end(); ++c) delete(*c); + free(style); + free(family); + free(name); + } + + Array chars; + char* name = nullptr; + char* family = nullptr; + char* style = nullptr; + float ascent = 0.0f; + Origin origin = Embedded; +}; + +struct LottieMarker +{ + char* name = nullptr; + float time = 0.0f; + float duration = 0.0f; + + ~LottieMarker() + { + free(name); + } +}; + +struct LottieText : LottieObject +{ + void prepare() + { + LottieObject::type = LottieObject::Text; + } + + void override(LottieProperty* prop) override + { + this->doc = *static_cast(prop); + this->prepare(); + } + + LottieTextDoc doc; + LottieFont* font; + LottieFloat spacing = 0.0f; //letter spacing +}; + + +struct LottieTrimpath : LottieObject +{ + enum Type : uint8_t { Simultaneous = 1, Individual = 2 }; + + void prepare() + { + LottieObject::type = LottieObject::Trimpath; + } + + bool mergeable() override + { + if (!start.frames && start.value == 0.0f && !end.frames && end.value == 100.0f && !offset.frames && offset.value == 0.0f) return true; + return false; + } + + void segment(float frameNo, float& start, float& end, LottieExpressions* exps); + + LottieFloat start = 0.0f; + LottieFloat end = 100.0f; + LottieFloat offset = 0.0f; + Type type = Simultaneous; +}; + + +struct LottieShape : LottieObject +{ + virtual ~LottieShape() {} + uint8_t direction = 0; //0: clockwise, 2: counter-clockwise, 3: xor(?) + + bool mergeable() override + { + return true; + } +}; + + +struct LottieRoundedCorner : LottieObject +{ + void prepare() + { + LottieObject::type = LottieObject::RoundedCorner; + } + LottieFloat radius = 0.0f; +}; + + +struct LottiePath : LottieShape +{ + void prepare() + { + LottieObject::type = LottieObject::Path; + } + + LottiePathSet pathset; +}; + + +struct LottieRect : LottieShape +{ + void prepare() + { + LottieObject::type = LottieObject::Rect; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottiePoint size = Point{0.0f, 0.0f}; + LottieFloat radius = 0.0f; //rounded corner radius +}; + + +struct LottiePolyStar : LottieShape +{ + enum Type : uint8_t {Star = 1, Polygon}; + + void prepare() + { + LottieObject::type = LottieObject::Polystar; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottieFloat innerRadius = 0.0f; + LottieFloat outerRadius = 0.0f; + LottieFloat innerRoundness = 0.0f; + LottieFloat outerRoundness = 0.0f; + LottieFloat rotation = 0.0f; + LottieFloat ptsCnt = 0.0f; + Type type = Polygon; +}; + + +struct LottieEllipse : LottieShape +{ + void prepare() + { + LottieObject::type = LottieObject::Ellipse; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottiePoint size = Point{0.0f, 0.0f}; +}; + + +struct LottieTransform : LottieObject +{ + struct SeparateCoord + { + LottieFloat x = 0.0f; + LottieFloat y = 0.0f; + }; + + struct RotationEx + { + LottieFloat x = 0.0f; + LottieFloat y = 0.0f; + }; + + ~LottieTransform() + { + delete(coords); + delete(rotationEx); + } + + void prepare() + { + LottieObject::type = LottieObject::Transform; + } + + bool mergeable() override + { + if (!opacity.frames && opacity.value == 255) return true; + return false; + } + + LottiePosition position = Point{0.0f, 0.0f}; + LottieFloat rotation = 0.0f; //z rotation + LottiePoint scale = Point{100.0f, 100.0f}; + LottiePoint anchor = Point{0.0f, 0.0f}; + LottieOpacity opacity = 255; + LottieFloat skewAngle = 0.0f; + LottieFloat skewAxis = 0.0f; + + SeparateCoord* coords = nullptr; //either a position or separate coordinates + RotationEx* rotationEx = nullptr; //extension for 3d rotation +}; + + +struct LottieSolid : LottieObject +{ + LottieColor color = RGB24{255, 255, 255}; + LottieOpacity opacity = 255; +}; + + +struct LottieSolidStroke : LottieSolid, LottieStroke +{ + void prepare() + { + LottieObject::type = LottieObject::SolidStroke; + } + + void override(LottieProperty* prop) override + { + this->color = *static_cast(prop); + this->prepare(); + } +}; + + +struct LottieSolidFill : LottieSolid +{ + void prepare() + { + LottieObject::type = LottieObject::SolidFill; + } + + void override(LottieProperty* prop) override + { + this->color = *static_cast(prop); + this->prepare(); + } + + FillRule rule = FillRule::Winding; +}; + + +struct LottieGradient : LottieObject +{ + bool prepare() + { + if (!colorStops.populated) { + if (colorStops.frames) { + for (auto v = colorStops.frames->begin(); v < colorStops.frames->end(); ++v) { + colorStops.count = populate(v->value); + } + } else { + colorStops.count = populate(colorStops.value); + } + } + if (start.frames || end.frames || height.frames || angle.frames || opacity.frames || colorStops.frames) return true; + return false; + } + + uint32_t populate(ColorStop& color); + Fill* fill(float frameNo, LottieExpressions* exps); + + LottiePoint start = Point{0.0f, 0.0f}; + LottiePoint end = Point{0.0f, 0.0f}; + LottieFloat height = 0.0f; + LottieFloat angle = 0.0f; + LottieOpacity opacity = 255; + LottieColorStop colorStops; + uint8_t id = 0; //1: linear, 2: radial +}; + + +struct LottieGradientFill : LottieGradient +{ + void prepare() + { + LottieObject::type = LottieObject::GradientFill; + LottieGradient::prepare(); + } + + void override(LottieProperty* prop) override + { + this->colorStops = *static_cast(prop); + this->prepare(); + } + + FillRule rule = FillRule::Winding; +}; + + +struct LottieGradientStroke : LottieGradient, LottieStroke +{ + void prepare() + { + LottieObject::type = LottieObject::GradientStroke; + LottieGradient::prepare(); + } + + void override(LottieProperty* prop) override + { + this->colorStops = *static_cast(prop); + this->prepare(); + } +}; + + +struct LottieImage : LottieObject +{ + union { + char* b64Data = nullptr; + char* path; + }; + char* mimeType = nullptr; + uint32_t size = 0; + + Picture* picture = nullptr; //tvg render data + + ~LottieImage(); + + void prepare() + { + LottieObject::type = LottieObject::Image; + } +}; + + +struct LottieRepeater : LottieObject +{ + void prepare() + { + LottieObject::type = LottieObject::Repeater; + } + + LottieFloat copies = 0.0f; + LottieFloat offset = 0.0f; + + //Transform + LottiePosition position = Point{0.0f, 0.0f}; + LottieFloat rotation = 0.0f; + LottiePoint scale = Point{100.0f, 100.0f}; + LottiePoint anchor = Point{0.0f, 0.0f}; + LottieOpacity startOpacity = 255; + LottieOpacity endOpacity = 255; + bool inorder = true; //true: higher, false: lower +}; + + +struct LottieGroup : LottieObject +{ + virtual ~LottieGroup() + { + for (auto p = children.begin(); p < children.end(); ++p) delete(*p); + } + + void prepare(LottieObject::Type type = LottieObject::Group); + bool mergeable() override { return allowMerge; } + + LottieObject* content(const char* id) + { + if (name && !strcmp(name, id)) return this; + + //source has children, find recursively. + for (auto c = children.begin(); c < children.end(); ++c) { + auto child = *c; + if (child->type == LottieObject::Type::Group || child->type == LottieObject::Type::Layer) { + if (auto ret = static_cast(child)->content(id)) return ret; + } else if (child->name && !strcmp(child->name, id)) return child; + } + return nullptr; + } + + Scene* scene = nullptr; //tvg render data + Array children; + + bool reqFragment = false; //requirement to fragment the render context + bool buildDone = false; //completed in building the composition. + bool allowMerge = true; //if this group is consisted of simple (transformed) shapes. + bool trimpath = false; //this group has a trimpath. +}; + + +struct LottieLayer : LottieGroup +{ + enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text}; + + ~LottieLayer(); + + uint8_t opacity(float frameNo) + { + //return zero if the visibility is false. + if (type == Null) return 255; + return transform->opacity(frameNo); + } + + bool mergeable() override { return false; } + + void prepare(); + float remap(float frameNo, LottieExpressions* exp); + + struct { + CompositeMethod type = CompositeMethod::None; + LottieLayer* target = nullptr; + } matte; + + BlendMethod blendMethod = BlendMethod::Normal; + LottieLayer* parent = nullptr; + LottieFloat timeRemap = 0.0f; + LottieComposition* comp = nullptr; + LottieTransform* transform = nullptr; + Array masks; + RGB24 color; //used by Solid layer + + float timeStretch = 1.0f; + float w = 0.0f, h = 0.0f; + float inFrame = 0.0f; + float outFrame = 0.0f; + float startFrame = 0.0f; + char* refId = nullptr; //pre-composition reference. + int16_t pid = -1; //id of the parent layer. + int16_t id = -1; //id of the current layer. + + //cached data + struct { + float frameNo = -1.0f; + Matrix matrix; + uint8_t opacity; + } cache; + + Type type = Null; + bool autoOrient = false; + bool matteSrc = false; +}; + + +struct LottieSlot +{ + struct Pair { + LottieObject* obj; + LottieProperty* prop; + }; + + void assign(LottieObject* target); + void reset(); + + LottieSlot(char* sid, LottieObject* obj, LottieProperty::Type type) : sid(sid), type(type) + { + pairs.push({obj, 0}); + } + + ~LottieSlot() + { + free(sid); + if (!overridden) return; + for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { + delete(pair->prop); + } + } + + char* sid; + Array pairs; + LottieProperty::Type type; + bool overridden = false; +}; + + +struct LottieComposition +{ + ~LottieComposition(); + + float duration() const + { + return frameCnt() / frameRate; // in second + } + + float frameAtTime(float timeInSec) const + { + auto p = timeInSec / duration(); + if (p < 0.0f) p = 0.0f; + return p * frameCnt(); + } + + float timeAtFrame(float frameNo) + { + return (frameNo - startFrame) / frameRate; + } + + float frameCnt() const + { + return endFrame - startFrame; + } + + LottieLayer* layer(const char* name) + { + for (auto child = root->children.begin(); child < root->children.end(); ++child) { + auto layer = static_cast(*child); + if (layer->name && !strcmp(layer->name, name)) return layer; + } + return nullptr; + } + + LottieLayer* layer(int16_t id) + { + for (auto child = root->children.begin(); child < root->children.end(); ++child) { + auto layer = static_cast(*child); + if (layer->id == id) return layer; + } + return nullptr; + } + + LottieLayer* asset(const char* name) + { + for (auto asset = assets.begin(); asset < assets.end(); ++asset) { + auto layer = static_cast(*asset); + if (layer->name && !strcmp(layer->name, name)) return layer; + } + return nullptr; + } + + LottieLayer* root = nullptr; + char* version = nullptr; + char* name = nullptr; + float w, h; + float startFrame, endFrame; + float frameRate; + Array assets; + Array interpolators; + Array fonts; + Array slots; + Array markers; + bool expressions = false; + bool initiated = false; +}; + +#endif //_TVG_LOTTIE_MODEL_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.cpp new file mode 100644 index 000000000..17e43b09e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.cpp @@ -0,0 +1,1405 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgStr.h" +#include "tvgCompressor.h" +#include "tvgLottieModel.h" +#include "tvgLottieParser.h" +#include "tvgLottieExpressions.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +#define KEY_AS(name) !strcmp(key, name) + + +static LottieExpression* _expression(char* code, LottieComposition* comp, LottieLayer* layer, LottieObject* object, LottieProperty* property, LottieProperty::Type type) +{ + if (!comp->expressions) comp->expressions = true; + + auto inst = new LottieExpression; + inst->code = code; + inst->comp = comp; + inst->layer = layer; + inst->object = object; + inst->property = property; + inst->type = type; + inst->enabled = true; + + return inst; +} + + +static char* _int2str(int num) +{ + char str[20]; + snprintf(str, 20, "%d", num); + return strdup(str); +} + + +CompositeMethod LottieParser::getMaskMethod(bool inversed) +{ + auto mode = getString(); + if (!mode) return CompositeMethod::None; + + switch (mode[0]) { + case 'a': { + if (inversed) return CompositeMethod::InvAlphaMask; + else return CompositeMethod::AddMask; + } + case 's': return CompositeMethod::SubtractMask; + case 'i': return CompositeMethod::IntersectMask; + case 'f': return CompositeMethod::DifferenceMask; + default: return CompositeMethod::None; + } +} + + +BlendMethod LottieParser::getBlendMethod() +{ + switch (getInt()) { + case 0: return BlendMethod::Normal; + case 1: return BlendMethod::Multiply; + case 2: return BlendMethod::Screen; + case 3: return BlendMethod::Overlay; + case 4: return BlendMethod::Darken; + case 5: return BlendMethod::Lighten; + case 6: return BlendMethod::ColorDodge; + case 7: return BlendMethod::ColorBurn; + case 8: return BlendMethod::HardLight; + case 9: return BlendMethod::SoftLight; + case 10: return BlendMethod::Difference; + case 11: return BlendMethod::Exclusion; + //case 12: return BlendMethod::Hue: + //case 13: return BlendMethod::Saturation: + //case 14: return BlendMethod::Color: + //case 15: return BlendMethod::Luminosity: + case 16: return BlendMethod::Add; + //case 17: return BlendMethod::HardMix: + default: { + TVGERR("LOTTIE", "Non-Supported Blend Mode"); + return BlendMethod::Normal; + } + } +} + + +RGB24 LottieParser::getColor(const char *str) +{ + RGB24 color = {0, 0, 0}; + + if (!str) return color; + + auto len = strlen(str); + + // some resource has empty color string, return a default color for those cases. + if (len != 7 || str[0] != '#') return color; + + char tmp[3] = {'\0', '\0', '\0'}; + tmp[0] = str[1]; + tmp[1] = str[2]; + color.rgb[0] = uint8_t(strtol(tmp, nullptr, 16)); + + tmp[0] = str[3]; + tmp[1] = str[4]; + color.rgb[1] = uint8_t(strtol(tmp, nullptr, 16)); + + tmp[0] = str[5]; + tmp[1] = str[6]; + color.rgb[2] = uint8_t(strtol(tmp, nullptr, 16)); + + return color; +} + + +FillRule LottieParser::getFillRule() +{ + switch (getInt()) { + case 1: return FillRule::Winding; + default: return FillRule::EvenOdd; + } +} + + +CompositeMethod LottieParser::getMatteType() +{ + switch (getInt()) { + case 1: return CompositeMethod::AlphaMask; + case 2: return CompositeMethod::InvAlphaMask; + case 3: return CompositeMethod::LumaMask; + case 4: return CompositeMethod::InvLumaMask; + default: return CompositeMethod::None; + } +} + + +StrokeCap LottieParser::getStrokeCap() +{ + switch (getInt()) { + case 1: return StrokeCap::Butt; + case 2: return StrokeCap::Round; + default: return StrokeCap::Square; + } +} + + +StrokeJoin LottieParser::getStrokeJoin() +{ + switch (getInt()) { + case 1: return StrokeJoin::Miter; + case 2: return StrokeJoin::Round; + default: return StrokeJoin::Bevel; + } +} + + +void LottieParser::getValue(TextDocument& doc) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("s")) doc.size = getFloat(); + else if (KEY_AS("f")) doc.name = getStringCopy(); + else if (KEY_AS("t")) doc.text = getStringCopy(); + else if (KEY_AS("j")) doc.justify = getInt(); + else if (KEY_AS("tr")) doc.tracking = getFloat() * 0.1f; + else if (KEY_AS("lh")) doc.height = getFloat(); + else if (KEY_AS("ls")) doc.shift = getFloat(); + else if (KEY_AS("fc")) getValue(doc.color); + else if (KEY_AS("ps")) getValue(doc.bbox.pos); + else if (KEY_AS("sz")) getValue(doc.bbox.size); + else if (KEY_AS("sc")) getValue(doc.stroke.color); + else if (KEY_AS("sw")) doc.stroke.width = getFloat(); + else if (KEY_AS("of")) doc.stroke.render = getBool(); + else skip(key); + } +} + + +void LottieParser::getValue(PathSet& path) +{ + Array outs, ins, pts; + bool closed = false; + + /* The shape object could be wrapped by a array + if its part of the keyframe object */ + auto arrayWrapper = (peekType() == kArrayType) ? true : false; + if (arrayWrapper) enterArray(); + + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("i")) getValue(ins); + else if (KEY_AS("o")) getValue(outs); + else if (KEY_AS("v")) getValue(pts); + else if (KEY_AS("c")) closed = getBool(); + else skip(key); + } + + //exit properly from the array + if (arrayWrapper) nextArrayValue(); + + //valid path data? + if (ins.empty() || outs.empty() || pts.empty()) return; + if (ins.count != outs.count || outs.count != pts.count) return; + + //convert path + auto out = outs.begin(); + auto in = ins.begin(); + auto pt = pts.begin(); + + //Store manipulated results + Array outPts; + Array outCmds; + + //Reuse the buffers + outPts.data = path.pts; + outPts.reserved = path.ptsCnt; + outCmds.data = path.cmds; + outCmds.reserved = path.cmdsCnt; + + size_t extra = closed ? 3 : 0; + outPts.reserve(pts.count * 3 + 1 + extra); + outCmds.reserve(pts.count + 2); + + outCmds.push(PathCommand::MoveTo); + outPts.push(*pt); + + for (++pt, ++out, ++in; pt < pts.end(); ++pt, ++out, ++in) { + outCmds.push(PathCommand::CubicTo); + outPts.push(*(pt - 1) + *(out - 1)); + outPts.push(*pt + *in); + outPts.push(*pt); + } + + if (closed) { + outPts.push(pts.last() + outs.last()); + outPts.push(pts.first() + ins.first()); + outPts.push(pts.first()); + outCmds.push(PathCommand::CubicTo); + outCmds.push(PathCommand::Close); + } + + path.pts = outPts.data; + path.cmds = outCmds.data; + path.ptsCnt = outPts.count; + path.cmdsCnt = outCmds.count; + + outPts.data = nullptr; + outCmds.data = nullptr; +} + + +void LottieParser::getValue(ColorStop& color) +{ + if (peekType() == kArrayType) enterArray(); + + color.input = new Array(static_cast(context.parent)->colorStops.count); + + while (nextArrayValue()) color.input->push(getFloat()); +} + + +void LottieParser::getValue(Array& pts) +{ + enterArray(); + while (nextArrayValue()) { + enterArray(); + Point pt; + getValue(pt); + pts.push(pt); + } +} + + +void LottieParser::getValue(uint8_t& val) +{ + if (peekType() == kArrayType) { + enterArray(); + if (nextArrayValue()) val = (uint8_t)(getFloat() * 2.55f); + //discard rest + while (nextArrayValue()) getFloat(); + } else { + val = (uint8_t)(getFloat() * 2.55f); + } +} + + +void LottieParser::getValue(float& val) +{ + if (peekType() == kArrayType) { + enterArray(); + if (nextArrayValue()) val = getFloat(); + //discard rest + while (nextArrayValue()) getFloat(); + } else { + val = getFloat(); + } +} + + +void LottieParser::getValue(Point& pt) +{ + int i = 0; + auto ptr = (float*)(&pt); + + if (peekType() == kArrayType) enterArray(); + + while (nextArrayValue()) { + auto val = getFloat(); + if (i < 2) ptr[i++] = val; + } +} + + +void LottieParser::getValue(RGB24& color) +{ + int i = 0; + + if (peekType() == kArrayType) enterArray(); + + while (nextArrayValue()) { + auto val = getFloat(); + if (i < 3) color.rgb[i++] = int32_t(lroundf(val * 255.0f)); + } + + //TODO: color filter? +} + + +void LottieParser::getInterpolatorPoint(Point& pt) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("x")) getValue(pt.x); + else if (KEY_AS("y")) getValue(pt.y); + } +} + + +template +void LottieParser::parseSlotProperty(T& prop) +{ + while (auto key = nextObjectKey()) { + if (KEY_AS("p")) parseProperty(prop); + else skip(key); + } +} + + +template +bool LottieParser::parseTangent(const char *key, LottieVectorFrame& value) +{ + if (KEY_AS("ti")) { + value.hasTangent = true; + getValue(value.inTangent); + } else if (KEY_AS("to")) { + value.hasTangent = true; + getValue(value.outTangent); + } else return false; + + return true; +} + + +template +bool LottieParser::parseTangent(const char *key, LottieScalarFrame& value) +{ + return false; +} + + +LottieInterpolator* LottieParser::getInterpolator(const char* key, Point& in, Point& out) +{ + char buf[20]; + + if (!key) { + snprintf(buf, sizeof(buf), "%.2f_%.2f_%.2f_%.2f", in.x, in.y, out.x, out.y); + key = buf; + } + + LottieInterpolator* interpolator = nullptr; + + //get a cached interpolator if it has any. + for (auto i = comp->interpolators.begin(); i < comp->interpolators.end(); ++i) { + if (!strncmp((*i)->key, key, sizeof(buf))) interpolator = *i; + } + + //new interpolator + if (!interpolator) { + interpolator = static_cast(malloc(sizeof(LottieInterpolator))); + interpolator->set(key, in, out); + comp->interpolators.push(interpolator); + } + + return interpolator; +} + + +template +void LottieParser::parseKeyFrame(T& prop) +{ + Point inTangent, outTangent; + const char* interpolatorKey = nullptr; + auto& frame = prop.newFrame(); + auto interpolator = false; + + enterObject(); + + while (auto key = nextObjectKey()) { + if (KEY_AS("i")) { + interpolator = true; + getInterpolatorPoint(inTangent); + } else if (KEY_AS("o")) { + getInterpolatorPoint(outTangent); + } else if (KEY_AS("n")) { + if (peekType() == kStringType) { + interpolatorKey = getString(); + } else { + enterArray(); + while (nextArrayValue()) { + if (!interpolatorKey) interpolatorKey = getString(); + else skip(nullptr); + } + } + } else if (KEY_AS("t")) { + frame.no = getFloat(); + } else if (KEY_AS("s")) { + getValue(frame.value); + } else if (KEY_AS("e")) { + //current end frame and the next start frame is duplicated, + //We propagate the end value to the next frame to avoid having duplicated values. + auto& frame2 = prop.nextFrame(); + getValue(frame2.value); + } else if (parseTangent(key, frame)) { + continue; + } else if (KEY_AS("h")) { + frame.hold = getInt(); + } else skip(key); + } + + if (interpolator) { + frame.interpolator = getInterpolator(interpolatorKey, inTangent, outTangent); + } +} + +template +void LottieParser::parsePropertyInternal(T& prop) +{ + //single value property + if (peekType() == kNumberType) { + getValue(prop.value); + //multi value property + } else { + //TODO: Here might be a single frame. + //Can we figure out the frame number in advance? + enterArray(); + while (nextArrayValue()) { + //keyframes value + if (peekType() == kObjectType) { + parseKeyFrame(prop); + //multi value property with no keyframes + } else { + getValue(prop.value); + break; + } + } + prop.prepare(); + } +} + + +template +void LottieParser::parseProperty(T& prop, LottieObject* obj) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) parsePropertyInternal(prop); + else if (obj && KEY_AS("sid")) { + auto sid = getStringCopy(); + //append object if the slot already exists. + for (auto slot = comp->slots.begin(); slot < comp->slots.end(); ++slot) { + if (strcmp((*slot)->sid, sid)) continue; + (*slot)->pairs.push({obj, 0}); + return; + } + comp->slots.push(new LottieSlot(sid, obj, type)); + } else if (!strcmp(key, "x")) { + prop.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &prop, type); + } + else skip(key); + } +} + + +LottieRect* LottieParser::parseRect() +{ + auto rect = new LottieRect; + if (!rect) return nullptr; + + context.parent = rect; + + while (auto key = nextObjectKey()) { + if (KEY_AS("s")) parseProperty(rect->size); + else if (KEY_AS("p"))parseProperty(rect->position); + else if (KEY_AS("r")) parseProperty(rect->radius); + else if (KEY_AS("nm")) rect->name = getStringCopy(); + else if (KEY_AS("hd")) rect->hidden = getBool(); + else skip(key); + } + rect->prepare(); + return rect; +} + + +LottieEllipse* LottieParser::parseEllipse() +{ + auto ellipse = new LottieEllipse; + if (!ellipse) return nullptr; + + context.parent = ellipse; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) ellipse->name = getStringCopy(); + else if (KEY_AS("p")) parseProperty(ellipse->position); + else if (KEY_AS("s")) parseProperty(ellipse->size); + else if (KEY_AS("hd")) ellipse->hidden = getBool(); + else skip(key); + } + ellipse->prepare(); + return ellipse; +} + + +LottieTransform* LottieParser::parseTransform(bool ddd) +{ + auto transform = new LottieTransform; + if (!transform) return nullptr; + + context.parent = transform; + + if (ddd) { + transform->rotationEx = new LottieTransform::RotationEx; + TVGLOG("LOTTIE", "3D transform(ddd) is not totally compatible."); + } + + while (auto key = nextObjectKey()) { + if (KEY_AS("p")) + { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) parsePropertyInternal(transform->position); + else if (KEY_AS("s") && getBool()) transform->coords = new LottieTransform::SeparateCoord; + //check separateCoord to figure out whether "x(expression)" / "x(coord)" + else if (transform->coords && KEY_AS("x")) parseProperty(transform->coords->x); + else if (transform->coords && KEY_AS("y")) parseProperty(transform->coords->y); + else if (KEY_AS("x")) transform->position.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &transform->position, LottieProperty::Type::Position); + else skip(key); + } + } + else if (KEY_AS("a")) parseProperty(transform->anchor); + else if (KEY_AS("s")) parseProperty(transform->scale); + else if (KEY_AS("r")) parseProperty(transform->rotation); + else if (KEY_AS("o")) parseProperty(transform->opacity); + else if (transform->rotationEx && KEY_AS("rx")) parseProperty(transform->rotationEx->x); + else if (transform->rotationEx && KEY_AS("ry")) parseProperty(transform->rotationEx->y); + else if (transform->rotationEx && KEY_AS("rz")) parseProperty(transform->rotation); + else if (KEY_AS("nm")) transform->name = getStringCopy(); + else if (KEY_AS("sk")) parseProperty(transform->skewAngle); + else if (KEY_AS("sa")) parseProperty(transform->skewAxis); + else skip(key); + } + transform->prepare(); + return transform; +} + + +LottieSolidFill* LottieParser::parseSolidFill() +{ + auto fill = new LottieSolidFill; + if (!fill) return nullptr; + + context.parent = fill; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) fill->name = getStringCopy(); + else if (KEY_AS("c")) parseProperty(fill->color, fill); + else if (KEY_AS("o")) parseProperty(fill->opacity, fill); + else if (KEY_AS("fillEnabled")) fill->hidden |= !getBool(); + else if (KEY_AS("r")) fill->rule = getFillRule(); + else if (KEY_AS("hd")) fill->hidden = getBool(); + else skip(key); + } + fill->prepare(); + return fill; +} + + +void LottieParser::parseStrokeDash(LottieStroke* stroke) +{ + enterArray(); + while (nextArrayValue()) { + enterObject(); + int idx = 0; + while (auto key = nextObjectKey()) { + if (KEY_AS("n")) { + auto style = getString(); + if (!strcmp("o", style)) idx = 0; //offset + else if (!strcmp("d", style)) idx = 1; //dash + else if (!strcmp("g", style)) idx = 2; //gap + } else if (KEY_AS("v")) { + parseProperty(stroke->dash(idx)); + } else skip(key); + } + } +} + + +LottieSolidStroke* LottieParser::parseSolidStroke() +{ + auto stroke = new LottieSolidStroke; + if (!stroke) return nullptr; + + context.parent = stroke; + + while (auto key = nextObjectKey()) { + if (KEY_AS("c")) parseProperty(stroke->color, stroke); + else if (KEY_AS("o")) parseProperty(stroke->opacity, stroke); + else if (KEY_AS("w")) parseProperty(stroke->width, stroke); + else if (KEY_AS("lc")) stroke->cap = getStrokeCap(); + else if (KEY_AS("lj")) stroke->join = getStrokeJoin(); + else if (KEY_AS("ml")) stroke->miterLimit = getFloat(); + else if (KEY_AS("nm")) stroke->name = getStringCopy(); + else if (KEY_AS("hd")) stroke->hidden = getBool(); + else if (KEY_AS("fillEnabled")) stroke->hidden |= !getBool(); + else if (KEY_AS("d")) parseStrokeDash(stroke); + else skip(key); + } + stroke->prepare(); + return stroke; +} + + +void LottieParser::getPathSet(LottiePathSet& path) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("k")) { + if (peekType() == kArrayType) { + enterArray(); + while (nextArrayValue()) parseKeyFrame(path); + } else { + getValue(path.value); + } + } else if (!strcmp(key, "x")) { + path.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &path, LottieProperty::Type::PathSet); + } else skip(key); + } +} + + +LottiePath* LottieParser::parsePath() +{ + auto path = new LottiePath; + if (!path) return nullptr; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) path->name = getStringCopy(); + else if (KEY_AS("ks")) getPathSet(path->pathset); + else if (KEY_AS("hd")) path->hidden = getBool(); + else skip(key); + } + path->prepare(); + return path; +} + + +LottiePolyStar* LottieParser::parsePolyStar() +{ + auto star = new LottiePolyStar; + if (!star) return nullptr; + + context.parent = star; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) star->name = getStringCopy(); + else if (KEY_AS("p")) parseProperty(star->position); + else if (KEY_AS("pt")) parseProperty(star->ptsCnt); + else if (KEY_AS("ir")) parseProperty(star->innerRadius); + else if (KEY_AS("is")) parseProperty(star->innerRoundness); + else if (KEY_AS("or")) parseProperty(star->outerRadius); + else if (KEY_AS("os")) parseProperty(star->outerRoundness); + else if (KEY_AS("r")) parseProperty(star->rotation); + else if (KEY_AS("sy")) star->type = (LottiePolyStar::Type) getInt(); + else if (KEY_AS("hd")) star->hidden = getBool(); + else skip(key); + } + star->prepare(); + return star; +} + + +LottieRoundedCorner* LottieParser::parseRoundedCorner() +{ + auto corner = new LottieRoundedCorner; + if (!corner) return nullptr; + + context.parent = corner; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) corner->name = getStringCopy(); + else if (KEY_AS("r")) parseProperty(corner->radius); + else if (KEY_AS("hd")) corner->hidden = getBool(); + else skip(key); + } + corner->prepare(); + return corner; +} + + +void LottieParser::parseGradient(LottieGradient* gradient, const char* key) +{ + if (KEY_AS("t")) gradient->id = getInt(); + else if (KEY_AS("o")) parseProperty(gradient->opacity, gradient); + else if (KEY_AS("g")) + { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("p")) gradient->colorStops.count = getInt(); + else if (KEY_AS("k")) parseProperty(gradient->colorStops, gradient); + else skip(key); + } + } + else if (KEY_AS("s")) parseProperty(gradient->start, gradient); + else if (KEY_AS("e")) parseProperty(gradient->end, gradient); + else if (KEY_AS("h")) parseProperty(gradient->height, gradient); + else if (KEY_AS("a")) parseProperty(gradient->angle, gradient); + else skip(key); +} + + +LottieGradientFill* LottieParser::parseGradientFill() +{ + auto fill = new LottieGradientFill; + if (!fill) return nullptr; + + context.parent = fill; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) fill->name = getStringCopy(); + else if (KEY_AS("r")) fill->rule = getFillRule(); + else if (KEY_AS("hd")) fill->hidden = getBool(); + else parseGradient(fill, key); + } + + fill->prepare(); + + return fill; +} + + +LottieGradientStroke* LottieParser::parseGradientStroke() +{ + auto stroke = new LottieGradientStroke; + if (!stroke) return nullptr; + + context.parent = stroke; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) stroke->name = getStringCopy(); + else if (KEY_AS("lc")) stroke->cap = getStrokeCap(); + else if (KEY_AS("lj")) stroke->join = getStrokeJoin(); + else if (KEY_AS("ml")) stroke->miterLimit = getFloat(); + else if (KEY_AS("hd")) stroke->hidden = getBool(); + else if (KEY_AS("w")) parseProperty(stroke->width); + else if (KEY_AS("d")) parseStrokeDash(stroke); + else parseGradient(stroke, key); + } + stroke->prepare(); + + return stroke; +} + + +LottieTrimpath* LottieParser::parseTrimpath() +{ + auto trim = new LottieTrimpath; + if (!trim) return nullptr; + + context.parent = trim; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) trim->name = getStringCopy(); + else if (KEY_AS("s")) parseProperty(trim->start); + else if (KEY_AS("e")) parseProperty(trim->end); + else if (KEY_AS("o")) parseProperty(trim->offset); + else if (KEY_AS("m")) trim->type = static_cast(getInt()); + else if (KEY_AS("hd")) trim->hidden = getBool(); + else skip(key); + } + trim->prepare(); + + return trim; +} + + +LottieRepeater* LottieParser::parseRepeater() +{ + auto repeater = new LottieRepeater; + if (!repeater) return nullptr; + + context.parent = repeater; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) repeater->name = getStringCopy(); + else if (KEY_AS("c")) parseProperty(repeater->copies); + else if (KEY_AS("o")) parseProperty(repeater->offset); + else if (KEY_AS("m")) repeater->inorder = getInt(); + else if (KEY_AS("tr")) + { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("a")) parseProperty(repeater->anchor); + else if (KEY_AS("p")) parseProperty(repeater->position); + else if (KEY_AS("r")) parseProperty(repeater->rotation); + else if (KEY_AS("s")) parseProperty(repeater->scale); + else if (KEY_AS("so")) parseProperty(repeater->startOpacity); + else if (KEY_AS("eo")) parseProperty(repeater->endOpacity); + else skip(key); + } + } + else if (KEY_AS("hd")) repeater->hidden = getBool(); + else skip(key); + } + repeater->prepare(); + + return repeater; +} + + +LottieObject* LottieParser::parseObject() +{ + auto type = getString(); + if (!type) return nullptr; + + if (!strcmp(type, "gr")) return parseGroup(); + else if (!strcmp(type, "rc")) return parseRect(); + else if (!strcmp(type, "el")) return parseEllipse(); + else if (!strcmp(type, "tr")) return parseTransform(); + else if (!strcmp(type, "fl")) return parseSolidFill(); + else if (!strcmp(type, "st")) return parseSolidStroke(); + else if (!strcmp(type, "sh")) return parsePath(); + else if (!strcmp(type, "sr")) return parsePolyStar(); + else if (!strcmp(type, "rd")) return parseRoundedCorner(); + else if (!strcmp(type, "gf")) return parseGradientFill(); + else if (!strcmp(type, "gs")) return parseGradientStroke(); + else if (!strcmp(type, "tm")) return parseTrimpath(); + else if (!strcmp(type, "rp")) return parseRepeater(); + else if (!strcmp(type, "mm")) TVGERR("LOTTIE", "MergePath(mm) is not supported yet"); + else if (!strcmp(type, "pb")) TVGERR("LOTTIE", "Puker/Bloat(pb) is not supported yet"); + else if (!strcmp(type, "tw")) TVGERR("LOTTIE", "Twist(tw) is not supported yet"); + else if (!strcmp(type, "op")) TVGERR("LOTTIE", "Offset Path(op) is not supported yet"); + else if (!strcmp(type, "zz")) TVGERR("LOTTIE", "Zig Zag(zz) is not supported yet"); + return nullptr; +} + + +void LottieParser::parseObject(Array& parent) +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("ty")) { + if (auto child = parseObject()) { + if (child->hidden) delete(child); + else parent.push(child); + } + } else skip(key); + } +} + + +LottieImage* LottieParser::parseImage(const char* data, const char* subPath, bool embedded) +{ + //Used for Image Asset + auto image = new LottieImage; + + //embedded image resource. should start with "data:" + //header look like "data:image/png;base64," so need to skip till ','. + if (embedded && !strncmp(data, "data:", 5)) { + //figure out the mimetype + auto mimeType = data + 11; + auto needle = strstr(mimeType, ";"); + image->mimeType = strDuplicate(mimeType, needle - mimeType); + //b64 data + auto b64Data = strstr(data, ",") + 1; + size_t length = strlen(data) - (b64Data - data); + image->size = b64Decode(b64Data, length, &image->b64Data); + //external image resource + } else { + auto len = strlen(dirName) + strlen(subPath) + strlen(data) + 1; + image->path = static_cast(malloc(len)); + snprintf(image->path, len, "%s%s%s", dirName, subPath, data); + } + + image->prepare(); + + return image; +} + + +LottieObject* LottieParser::parseAsset() +{ + enterObject(); + + LottieObject* obj = nullptr; + char *id = nullptr; + + //Used for Image Asset + const char* data = nullptr; + const char* subPath = nullptr; + auto embedded = false; + + while (auto key = nextObjectKey()) { + if (KEY_AS("id")) + { + if (peekType() == kStringType) { + id = getStringCopy(); + } else { + id = _int2str(getInt()); + } + } + else if (KEY_AS("layers")) obj = parseLayers(); + else if (KEY_AS("u")) subPath = getString(); + else if (KEY_AS("p")) data = getString(); + else if (KEY_AS("e")) embedded = getInt(); + else skip(key); + } + if (data) obj = parseImage(data, subPath, embedded); + if (obj) obj->name = id; + else free(id); + return obj; +} + + +LottieFont* LottieParser::parseFont() +{ + enterObject(); + + auto font = new LottieFont; + + while (auto key = nextObjectKey()) { + if (KEY_AS("fName")) font->name = getStringCopy(); + else if (KEY_AS("fFamily")) font->family = getStringCopy(); + else if (KEY_AS("fStyle")) font->style = getStringCopy(); + else if (KEY_AS("ascent")) font->ascent = getFloat(); + else if (KEY_AS("origin")) font->origin = (LottieFont::Origin) getInt(); + else skip(key); + } + return font; +} + + +void LottieParser::parseAssets() +{ + enterArray(); + while (nextArrayValue()) { + auto asset = parseAsset(); + if (asset) comp->assets.push(asset); + else TVGERR("LOTTIE", "Invalid Asset!"); + } +} + +LottieMarker* LottieParser::parseMarker() +{ + enterObject(); + + auto marker = new LottieMarker; + + while (auto key = nextObjectKey()) { + if (KEY_AS("cm")) marker->name = getStringCopy(); + else if (KEY_AS("tm")) marker->time = getFloat(); + else if (KEY_AS("dr")) marker->duration = getFloat(); + else skip(key); + } + + return marker; +} + +void LottieParser::parseMarkers() +{ + enterArray(); + while (nextArrayValue()) { + comp->markers.push(parseMarker()); + } +} + +void LottieParser::parseChars(Array& glyphs) +{ + enterArray(); + while (nextArrayValue()) { + enterObject(); + //a new glyph + auto glyph = new LottieGlyph; + while (auto key = nextObjectKey()) { + if (KEY_AS("ch")) glyph->code = getStringCopy(); + else if (KEY_AS("size")) glyph->size = static_cast(getFloat()); + else if (KEY_AS("style")) glyph->style = getStringCopy(); + else if (KEY_AS("w")) glyph->width = getFloat(); + else if (KEY_AS("fFamily")) glyph->family = getStringCopy(); + else if (KEY_AS("data")) + { //glyph shapes + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("shapes")) parseShapes(glyph->children); + } + } else skip(key); + } + glyph->prepare(); + glyphs.push(glyph); + } +} + +void LottieParser::parseFonts() +{ + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("list")) { + enterArray(); + while (nextArrayValue()) { + comp->fonts.push(parseFont()); + } + } else skip(key); + } +} + + +LottieObject* LottieParser::parseGroup() +{ + auto group = new LottieGroup; + if (!group) return nullptr; + + while (auto key = nextObjectKey()) { + if (KEY_AS("nm")) { + group->name = getStringCopy(); + } else if (KEY_AS("it")) { + enterArray(); + while (nextArrayValue()) parseObject(group->children); + } else skip(key); + } + if (group->children.empty()) { + delete(group); + return nullptr; + } + group->prepare(); + + return group; +} + + +void LottieParser::parseTimeRemap(LottieLayer* layer) +{ + parseProperty(layer->timeRemap); +} + + +uint8_t LottieParser::getDirection() +{ + auto v = getInt(); + if (v == 1) return 0; + if (v == 2) return 3; + if (v == 3) return 2; + return 0; +} + +void LottieParser::parseShapes(Array& parent) +{ + uint8_t direction; + + enterArray(); + while (nextArrayValue()) { + direction = 0; + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("it")) { + enterArray(); + while (nextArrayValue()) parseObject(parent); + } else if (KEY_AS("d")) { + direction = getDirection(); + } else if (KEY_AS("ty")) { + if (auto child = parseObject()) { + if (child->hidden) delete(child); + else parent.push(child); + if (direction > 0) static_cast(child)->direction = direction; + } + } else skip(key); + } + } +} + + +void LottieParser::parseTextRange(LottieText* text) +{ + enterArray(); + while (nextArrayValue()) { + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("a")) { //text style + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("t")) parseProperty(text->spacing); + else skip(key); + } + } else skip(key); + } + } +} + + +void LottieParser::parseText(Array& parent) +{ + enterObject(); + + auto text = new LottieText; + + while (auto key = nextObjectKey()) { + if (KEY_AS("d")) parseProperty(text->doc, text); + else if (KEY_AS("a")) parseTextRange(text); + //else if (KEY_AS("p")) TVGLOG("LOTTIE", "Text Follow Path (p) is not supported"); + //else if (KEY_AS("m")) TVGLOG("LOTTIE", "Text Alignment Option (m) is not supported"); + else skip(key); + } + + text->prepare(); + parent.push(text); +} + + +void LottieParser::getLayerSize(float& val) +{ + if (val == 0.0f) { + val = getFloat(); + } else { + //layer might have both w(width) & sw(solid color width) + //override one if the a new size is smaller. + auto w = getFloat(); + if (w < val) val = w; + } +} + +LottieMask* LottieParser::parseMask() +{ + auto mask = new LottieMask; + if (!mask) return nullptr; + + enterObject(); + while (auto key = nextObjectKey()) { + if (KEY_AS("inv")) mask->inverse = getBool(); + else if (KEY_AS("mode")) mask->method = getMaskMethod(mask->inverse); + else if (KEY_AS("pt")) getPathSet(mask->pathset); + else if (KEY_AS("o")) parseProperty(mask->opacity); + else skip(key); + } + + return mask; +} + + +void LottieParser::parseMasks(LottieLayer* layer) +{ + enterArray(); + while (nextArrayValue()) { + auto mask = parseMask(); + layer->masks.push(mask); + } +} + + +LottieLayer* LottieParser::parseLayer() +{ + auto layer = new LottieLayer; + if (!layer) return nullptr; + + layer->comp = comp; + context.layer = layer; + + auto ddd = false; + + enterObject(); + + while (auto key = nextObjectKey()) { + if (KEY_AS("ddd")) ddd = getInt(); //3d layer + else if (KEY_AS("ind")) layer->id = getInt(); + else if (KEY_AS("ty")) layer->type = (LottieLayer::Type) getInt(); + else if (KEY_AS("nm")) layer->name = getStringCopy(); + else if (KEY_AS("sr")) layer->timeStretch = getFloat(); + else if (KEY_AS("ks")) + { + enterObject(); + layer->transform = parseTransform(ddd); + } + else if (KEY_AS("ao")) layer->autoOrient = getInt(); + else if (KEY_AS("shapes")) parseShapes(layer->children); + else if (KEY_AS("ip")) layer->inFrame = getFloat(); + else if (KEY_AS("op")) layer->outFrame = getFloat(); + else if (KEY_AS("st")) layer->startFrame = getFloat(); + else if (KEY_AS("bm")) layer->blendMethod = getBlendMethod(); + else if (KEY_AS("parent")) layer->pid = getInt(); + else if (KEY_AS("tm")) parseTimeRemap(layer); + else if (KEY_AS("w") || KEY_AS("sw")) getLayerSize(layer->w); + else if (KEY_AS("h") || KEY_AS("sh")) getLayerSize(layer->h); + else if (KEY_AS("sc")) layer->color = getColor(getString()); + else if (KEY_AS("tt")) layer->matte.type = getMatteType(); + else if (KEY_AS("masksProperties")) parseMasks(layer); + else if (KEY_AS("hd")) layer->hidden = getBool(); + else if (KEY_AS("refId")) layer->refId = getStringCopy(); + else if (KEY_AS("td")) layer->matteSrc = getInt(); //used for matte layer + else if (KEY_AS("t")) parseText(layer->children); + else if (KEY_AS("ef")) + { + TVGERR("LOTTIE", "layer effect(ef) is not supported!"); + skip(key); + } + else skip(key); + } + + //Not a valid layer + if (!layer->transform) { + delete(layer); + return nullptr; + } + + layer->prepare(); + + return layer; +} + + +LottieLayer* LottieParser::parseLayers() +{ + auto root = new LottieLayer; + if (!root) return nullptr; + + root->type = LottieLayer::Precomp; + root->comp = comp; + + enterArray(); + while (nextArrayValue()) { + if (auto layer = parseLayer()) { + if (layer->matte.type == CompositeMethod::None) { + root->children.push(layer); + } else { + //matte source must be located in the right previous. + auto matte = static_cast(root->children.last()); + if (matte->matteSrc) { + layer->matte.target = matte; + } else { + TVGLOG("LOTTIE", "Matte Source(%s) is not designated?", matte->name); + } + root->children.last() = layer; + } + } + } + root->prepare(); + return root; +} + + +void LottieParser::postProcess(Array& glyphs) +{ + //aggregate font characters + for (uint32_t g = 0; g < glyphs.count; ++g) { + auto glyph = glyphs[g]; + for (uint32_t i = 0; i < comp->fonts.count; ++i) { + auto& font = comp->fonts[i]; + if (!strcmp(font->family, glyph->family) && !strcmp(font->style, glyph->style)) { + font->chars.push(glyph); + free(glyph->family); + free(glyph->style); + break; + } + } + } +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +const char* LottieParser::sid(bool first) +{ + if (first) { + //verify json + if (!parseNext()) return nullptr; + enterObject(); + } + return nextObjectKey(); +} + + +bool LottieParser::apply(LottieSlot* slot) +{ + enterObject(); + + //OPTIMIZE: we can create the property directly, without object + LottieObject* obj = nullptr; //slot object + + switch (slot->type) { + case LottieProperty::Type::ColorStop: { + obj = new LottieGradient; + context.parent = obj; + parseSlotProperty(static_cast(obj)->colorStops); + break; + } + case LottieProperty::Type::Color: { + obj = new LottieSolid; + context.parent = obj; + parseSlotProperty(static_cast(obj)->color); + break; + } + case LottieProperty::Type::TextDoc: { + obj = new LottieText; + context.parent = obj; + parseSlotProperty(static_cast(obj)->doc); + break; + } + default: break; + } + + if (!obj || Invalid()) return false; + + slot->assign(obj); + + delete(obj); + + return true; +} + + +bool LottieParser::parse() +{ + //verify json. + if (!parseNext()) return false; + + enterObject(); + + if (comp) delete(comp); + comp = new LottieComposition; + if (!comp) return false; + + Array glyphs; + + while (auto key = nextObjectKey()) { + if (KEY_AS("v")) comp->version = getStringCopy(); + else if (KEY_AS("fr")) comp->frameRate = getFloat(); + else if (KEY_AS("ip")) comp->startFrame = getFloat(); + else if (KEY_AS("op")) comp->endFrame = getFloat(); + else if (KEY_AS("w")) comp->w = getFloat(); + else if (KEY_AS("h")) comp->h = getFloat(); + else if (KEY_AS("nm")) comp->name = getStringCopy(); + else if (KEY_AS("assets")) parseAssets(); + else if (KEY_AS("layers")) comp->root = parseLayers(); + else if (KEY_AS("fonts")) parseFonts(); + else if (KEY_AS("chars")) parseChars(glyphs); + else if (KEY_AS("markers")) parseMarkers(); + else skip(key); + } + + if (Invalid() || !comp->root) { + delete(comp); + return false; + } + + comp->root->inFrame = comp->startFrame; + comp->root->outFrame = comp->endFrame; + + postProcess(glyphs); + + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.h new file mode 100644 index 000000000..a8b6b0d9f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParser.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_PARSER_H_ +#define _TVG_LOTTIE_PARSER_H_ + +#include "tvgCommon.h" +#include "tvgLottieParserHandler.h" +#include "tvgLottieProperty.h" + +struct LottieParser : LookaheadParserHandler +{ +public: + LottieParser(const char *str, const char* dirName) : LookaheadParserHandler(str) + { + this->dirName = dirName; + } + + bool parse(); + bool apply(LottieSlot* slot); + const char* sid(bool first = false); + + LottieComposition* comp = nullptr; + const char* dirName = nullptr; //base resource directory + +private: + BlendMethod getBlendMethod(); + RGB24 getColor(const char *str); + CompositeMethod getMatteType(); + FillRule getFillRule(); + StrokeCap getStrokeCap(); + StrokeJoin getStrokeJoin(); + CompositeMethod getMaskMethod(bool inversed); + LottieInterpolator* getInterpolator(const char* key, Point& in, Point& out); + uint8_t getDirection(); + + void getInterpolatorPoint(Point& pt); + void getPathSet(LottiePathSet& path); + void getLayerSize(float& val); + void getValue(TextDocument& doc); + void getValue(PathSet& path); + void getValue(Array& pts); + void getValue(ColorStop& color); + void getValue(float& val); + void getValue(uint8_t& val); + void getValue(Point& pt); + void getValue(RGB24& color); + + template bool parseTangent(const char *key, LottieVectorFrame& value); + template bool parseTangent(const char *key, LottieScalarFrame& value); + template void parseKeyFrame(T& prop); + template void parsePropertyInternal(T& prop); + template void parseProperty(T& prop, LottieObject* obj = nullptr); + template void parseSlotProperty(T& prop); + + LottieObject* parseObject(); + LottieObject* parseAsset(); + LottieImage* parseImage(const char* data, const char* subPath, bool embedded); + LottieLayer* parseLayer(); + LottieObject* parseGroup(); + LottieRect* parseRect(); + LottieEllipse* parseEllipse(); + LottieSolidFill* parseSolidFill(); + LottieTransform* parseTransform(bool ddd = false); + LottieSolidStroke* parseSolidStroke(); + LottieGradientStroke* parseGradientStroke(); + LottiePath* parsePath(); + LottiePolyStar* parsePolyStar(); + LottieRoundedCorner* parseRoundedCorner(); + LottieGradientFill* parseGradientFill(); + LottieLayer* parseLayers(); + LottieMask* parseMask(); + LottieTrimpath* parseTrimpath(); + LottieRepeater* parseRepeater(); + LottieFont* parseFont(); + LottieMarker* parseMarker(); + + void parseObject(Array& parent); + void parseShapes(Array& parent); + void parseText(Array& parent); + void parseMasks(LottieLayer* layer); + void parseTimeRemap(LottieLayer* layer); + void parseStrokeDash(LottieStroke* stroke); + void parseGradient(LottieGradient* gradient, const char* key); + void parseTextRange(LottieText* text); + void parseAssets(); + void parseFonts(); + void parseChars(Array& glyphs); + void parseMarkers(); + void postProcess(Array& glyphs); + + //Current parsing context + struct Context { + LottieLayer* layer = nullptr; + LottieObject* parent = nullptr; + } context; +}; + +#endif //_TVG_LOTTIE_PARSER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.cpp new file mode 100644 index 000000000..4d00441b8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tvgLottieParserHandler.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static const int PARSE_FLAGS = kParseDefaultFlags | kParseInsituFlag; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +bool LookaheadParserHandler::enterArray() +{ + if (state != kEnteringArray) { + Error(); + return false; + } + parseNext(); + return true; +} + + +bool LookaheadParserHandler::nextArrayValue() +{ + if (state == kExitingArray) { + parseNext(); + return false; + } + //SPECIAL CASE: same as nextObjectKey() + if (state == kExitingObject) return false; + if (state == kError || state == kHasKey) { + Error(); + return false; + } + return true; +} + + +int LookaheadParserHandler::getInt() +{ + if (state != kHasNumber || !val.IsInt()) { + Error(); + return 0; + } + auto result = val.GetInt(); + parseNext(); + return result; +} + + +float LookaheadParserHandler::getFloat() +{ + if (state != kHasNumber) { + Error(); + return 0; + } + auto result = val.GetFloat(); + parseNext(); + return result; +} + + +const char* LookaheadParserHandler::getString() +{ + if (state != kHasString) { + Error(); + return nullptr; + } + auto result = val.GetString(); + parseNext(); + return result; +} + + +char* LookaheadParserHandler::getStringCopy() +{ + auto str = getString(); + if (str) return strdup(str); + return nullptr; +} + + +bool LookaheadParserHandler::getBool() +{ + if (state != kHasBool) { + Error(); + return false; + } + auto result = val.GetBool(); + parseNext(); + return result; +} + + +void LookaheadParserHandler::getNull() +{ + if (state != kHasNull) { + Error(); + return; + } + parseNext(); +} + + +bool LookaheadParserHandler::parseNext() +{ + if (reader.HasParseError()) { + Error(); + return false; + } + if (!reader.IterativeParseNext(iss, *this)) { + Error(); + return false; + } + return true; +} + + +bool LookaheadParserHandler::enterObject() +{ + if (state != kEnteringObject) { + Error(); + return false; + } + parseNext(); + return true; +} + + +int LookaheadParserHandler::peekType() +{ + if (state >= kHasNull && state <= kHasKey) return val.GetType(); + if (state == kEnteringArray) return kArrayType; + if (state == kEnteringObject) return kObjectType; + return -1; +} + + +void LookaheadParserHandler::skipOut(int depth) +{ + do { + if (state == kEnteringArray || state == kEnteringObject) ++depth; + else if (state == kExitingArray || state == kExitingObject) --depth; + else if (state == kError) return; + parseNext(); + } while (depth > 0); +} + + +const char* LookaheadParserHandler::nextObjectKey() +{ + if (state == kHasKey) { + auto result = val.GetString(); + parseNext(); + return result; + } + + /* SPECIAL CASE: The parser works with a predefined rule that it will be only + while (nextObjectKey()) for each object but in case of our nested group + object we can call multiple time nextObjectKey() while exiting the object + so ignore those and don't put parser in the error state. */ + if (state == kExitingArray || state == kEnteringObject) return nullptr; + + if (state != kExitingObject) { + Error(); + return nullptr; + } + + parseNext(); + return nullptr; +} + + +void LookaheadParserHandler::skip(const char* key) +{ + //if (key) TVGLOG("LOTTIE", "Skipped parsing value = %s", key); + + if (peekType() == kArrayType) { + enterArray(); + skipOut(1); + } else if (peekType() == kObjectType) { + enterObject(); + skipOut(1); + } else { + skipOut(0); + } +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.h new file mode 100644 index 000000000..65b4545a2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieParserHandler.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_LOTTIE_PARSER_HANDLER_H_ +#define _TVG_LOTTIE_PARSER_HANDLER_H_ + +#include "rapidjson/document.h" +#include "tvgCommon.h" + + +using namespace rapidjson; + + +struct LookaheadParserHandler +{ + enum LookaheadParsingState { + kInit = 0, + kError, + kHasNull, + kHasBool, + kHasNumber, + kHasString, + kHasKey, + kEnteringObject, + kExitingObject, + kEnteringArray, + kExitingArray + }; + + Value val; + LookaheadParsingState state = kInit; + Reader reader; + InsituStringStream iss; + + LookaheadParserHandler(const char *str) : iss((char*)str) + { + reader.IterativeParseInit(); + } + + bool Null() + { + state = kHasNull; + val.SetNull(); + return true; + } + + bool Bool(bool b) + { + state = kHasBool; + val.SetBool(b); + return true; + } + + bool Int(int i) + { + state = kHasNumber; + val.SetInt(i); + return true; + } + + bool Uint(unsigned u) + { + state = kHasNumber; + val.SetUint(u); + return true; + } + + bool Int64(int64_t i) + { + state = kHasNumber; + val.SetInt64(i); + return true; + } + + bool Uint64(int64_t u) + { + state = kHasNumber; + val.SetUint64(u); + return true; + } + + bool Double(double d) + { + state = kHasNumber; + val.SetDouble(d); + return true; + } + + bool RawNumber(const char *, SizeType, TVG_UNUSED bool) + { + return false; + } + + bool String(const char *str, SizeType length, TVG_UNUSED bool) + { + state = kHasString; + val.SetString(str, length); + return true; + } + + bool StartObject() + { + state = kEnteringObject; + return true; + } + + bool Key(const char *str, SizeType length, TVG_UNUSED bool) + { + state = kHasKey; + val.SetString(str, length); + return true; + } + + bool EndObject(SizeType) + { + state = kExitingObject; + return true; + } + + bool StartArray() + { + state = kEnteringArray; + return true; + } + + bool EndArray(SizeType) + { + state = kExitingArray; + return true; + } + + void Error() + { + TVGERR("LOTTIE", "Parsing Error!"); + state = kError; + } + + bool Invalid() + { + return state == kError; + } + + bool enterObject(); + bool enterArray(); + bool nextArrayValue(); + int getInt(); + float getFloat(); + const char* getString(); + char* getStringCopy(); + bool getBool(); + void getNull(); + bool parseNext(); + const char* nextObjectKey(); + void skip(const char* key); + void skipOut(int depth); + int peekType(); +}; + +#endif //_TVG_LOTTIE_PARSER_HANDLER_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieProperty.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieProperty.h new file mode 100644 index 000000000..19df89529 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieProperty.h @@ -0,0 +1,935 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_LOTTIE_PROPERTY_H_ +#define _TVG_LOTTIE_PROPERTY_H_ + +#include "tvgCommon.h" +#include "tvgArray.h" +#include "tvgMath.h" +#include "tvgLines.h" +#include "tvgLottieInterpolator.h" +#include "tvgLottieExpressions.h" + +#define ROUNDNESS_EPSILON 1.0f + +struct LottieFont; +struct LottieLayer; +struct LottieObject; + + +struct PathSet +{ + Point* pts = nullptr; + PathCommand* cmds = nullptr; + uint16_t ptsCnt = 0; + uint16_t cmdsCnt = 0; +}; + + +struct RGB24 +{ + int32_t rgb[3]; +}; + + +struct ColorStop +{ + Fill::ColorStop* data = nullptr; + Array* input = nullptr; +}; + + +struct TextDocument +{ + char* text = nullptr; + float height; + float shift; + RGB24 color; + struct { + Point pos; + Point size; + } bbox; + struct { + RGB24 color; + float width; + bool render = false; + } stroke; + char* name = nullptr; + float size; + float tracking = 0.0f; + uint8_t justify; +}; + + +static inline RGB24 operator-(const RGB24& lhs, const RGB24& rhs) +{ + return {lhs.rgb[0] - rhs.rgb[0], lhs.rgb[1] - rhs.rgb[1], lhs.rgb[2] - rhs.rgb[2]}; +} + + +static inline RGB24 operator+(const RGB24& lhs, const RGB24& rhs) +{ + return {lhs.rgb[0] + rhs.rgb[0], lhs.rgb[1] + rhs.rgb[1], lhs.rgb[2] + rhs.rgb[2]}; +} + + +static inline RGB24 operator*(const RGB24& lhs, float rhs) +{ + return {(int32_t)lroundf(lhs.rgb[0] * rhs), (int32_t)lroundf(lhs.rgb[1] * rhs), (int32_t)lroundf(lhs.rgb[2] * rhs)}; +} + + +template +struct LottieScalarFrame +{ + T value; //keyframe value + float no; //frame number + LottieInterpolator* interpolator; + bool hold = false; //do not interpolate. + + T interpolate(LottieScalarFrame* next, float frameNo) + { + auto t = (frameNo - no) / (next->no - no); + if (interpolator) t = interpolator->progress(t); + + if (hold) { + if (t < 1.0f) return value; + else return next->value; + } + return mathLerp(value, next->value, t); + } +}; + + +template +struct LottieVectorFrame +{ + T value; //keyframe value + float no; //frame number + LottieInterpolator* interpolator; + T outTangent, inTangent; + float length; + bool hasTangent = false; + bool hold = false; + + T interpolate(LottieVectorFrame* next, float frameNo) + { + auto t = (frameNo - no) / (next->no - no); + if (interpolator) t = interpolator->progress(t); + + if (hold) { + if (t < 1.0f) return value; + else return next->value; + } + + if (hasTangent) { + Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; + t = bezAtApprox(bz, t * length, length); + return bezPointAt(bz, t); + } else { + return mathLerp(value, next->value, t); + } + } + + float angle(LottieVectorFrame* next, float frameNo) + { + if (!hasTangent) return 0; + auto t = (frameNo - no) / (next->no - no); + if (interpolator) t = interpolator->progress(t); + Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; + t = bezAtApprox(bz, t * length, length); + return -bezAngleAt(bz, t); + } + + void prepare(LottieVectorFrame* next) + { + Bezier bz = {value, value + outTangent, next->value + inTangent, next->value}; + length = bezLengthApprox(bz); + } +}; + + +//Property would have an either keyframes or single value. +struct LottieProperty +{ + enum class Type : uint8_t { Point = 0, Float, Opacity, Color, PathSet, ColorStop, Position, TextDoc, Invalid }; + virtual ~LottieProperty() {} + + LottieExpression* exp = nullptr; + + //TODO: Apply common bodies? + virtual uint32_t frameCnt() = 0; + virtual uint32_t nearest(float time) = 0; + virtual float frameNo(int32_t key) = 0; +}; + + +struct LottieExpression +{ + enum LoopMode : uint8_t { None = 0, InCycle = 1, InPingPong, InOffset, InContinue, OutCycle, OutPingPong, OutOffset, OutContinue }; + + char* code; + LottieComposition* comp; + LottieLayer* layer; + LottieObject* object; + LottieProperty* property; + LottieProperty::Type type; + + bool enabled; + + struct { + uint32_t key = 0; //the keyframe number repeating to + float in = FLT_MAX; //looping duration in frame number + LoopMode mode = None; + } loop; +; + ~LottieExpression() + { + free(code); + } +}; + + +static void _copy(PathSet* pathset, Array& outPts, Matrix* transform) +{ + Array inPts; + + if (transform) { + for (int i = 0; i < pathset->ptsCnt; ++i) { + Point pt = pathset->pts[i]; + mathMultiply(&pt, transform); + outPts.push(pt); + } + } else { + inPts.data = pathset->pts; + inPts.count = pathset->ptsCnt; + outPts.push(inPts); + inPts.data = nullptr; + } +} + + +static void _copy(PathSet* pathset, Array& outCmds) +{ + Array inCmds; + inCmds.data = pathset->cmds; + inCmds.count = pathset->cmdsCnt; + outCmds.push(inCmds); + inCmds.data = nullptr; +} + + +static void _roundCorner(Array& cmds, Array& pts, const Point& prev, const Point& curr, const Point& next, float roundness) +{ + auto lenPrev = mathLength(prev - curr); + auto rPrev = lenPrev > 0.0f ? 0.5f * mathMin(lenPrev * 0.5f, roundness) / lenPrev : 0.0f; + auto lenNext = mathLength(next - curr); + auto rNext = lenNext > 0.0f ? 0.5f * mathMin(lenNext * 0.5f, roundness) / lenNext : 0.0f; + + auto dPrev = rPrev * (curr - prev); + auto dNext = rNext * (curr - next); + + pts.push(curr - 2.0f * dPrev); + pts.push(curr - dPrev); + pts.push(curr - dNext); + pts.push(curr - 2.0f * dNext); + cmds.push(PathCommand::LineTo); + cmds.push(PathCommand::CubicTo); +} + + +static bool _modifier(Point* inputPts, uint32_t inputPtsCnt, PathCommand* inputCmds, uint32_t inputCmdsCnt, Array& cmds, Array& pts, Matrix* transform, float roundness) +{ + cmds.reserve(inputCmdsCnt * 2); + pts.reserve((uint16_t)(inputPtsCnt * 1.5)); + auto ptsCnt = pts.count; + + auto startIndex = 0; + for (uint32_t iCmds = 0, iPts = 0; iCmds < inputCmdsCnt; ++iCmds) { + switch (inputCmds[iCmds]) { + case PathCommand::MoveTo: { + startIndex = pts.count; + cmds.push(PathCommand::MoveTo); + pts.push(inputPts[iPts++]); + break; + } + case PathCommand::CubicTo: { + auto& prev = inputPts[iPts - 1]; + auto& curr = inputPts[iPts + 2]; + if (iCmds < inputCmdsCnt - 1 && + mathZero(inputPts[iPts - 1] - inputPts[iPts]) && + mathZero(inputPts[iPts + 1] - inputPts[iPts + 2])) { + if (inputCmds[iCmds + 1] == PathCommand::CubicTo && + mathZero(inputPts[iPts + 2] - inputPts[iPts + 3]) && + mathZero(inputPts[iPts + 4] - inputPts[iPts + 5])) { + _roundCorner(cmds, pts, prev, curr, inputPts[iPts + 5], roundness); + iPts += 3; + break; + } else if (inputCmds[iCmds + 1] == PathCommand::Close) { + _roundCorner(cmds, pts, prev, curr, inputPts[2], roundness); + pts[startIndex] = pts.last(); + iPts += 3; + break; + } + } + cmds.push(PathCommand::CubicTo); + pts.push(inputPts[iPts++]); + pts.push(inputPts[iPts++]); + pts.push(inputPts[iPts++]); + break; + } + case PathCommand::Close: { + cmds.push(PathCommand::Close); + break; + } + default: break; + } + } + if (transform) { + for (auto i = ptsCnt; i < pts.count; ++i) + mathTransform(transform, &pts[i]); + } + return true; +} + + +template +uint32_t _bsearch(T* frames, float frameNo) +{ + int32_t low = 0; + int32_t high = int32_t(frames->count) - 1; + + while (low <= high) { + auto mid = low + (high - low) / 2; + auto frame = frames->data + mid; + if (frameNo < frame->no) high = mid - 1; + else low = mid + 1; + } + if (high < low) low = high; + if (low < 0) low = 0; + return low; +} + + +template +uint32_t _nearest(T* frames, float frameNo) +{ + if (frames) { + auto key = _bsearch(frames, frameNo); + if (key == frames->count - 1) return key; + return (fabsf(frames->data[key].no - frameNo) < fabsf(frames->data[key + 1].no - frameNo)) ? key : (key + 1); + } + return 0; +} + + +template +float _frameNo(T* frames, int32_t key) +{ + if (!frames) return 0.0f; + if (key < 0) key = 0; + if (key >= (int32_t) frames->count) key = (int32_t)(frames->count - 1); + return (*frames)[key].no; +} + + +template +float _loop(T* frames, float frameNo, LottieExpression* exp) +{ + if (frameNo >= exp->loop.in || frameNo < frames->first().no ||frameNo < frames->last().no) return frameNo; + + switch (exp->loop.mode) { + case LottieExpression::LoopMode::InCycle: { + frameNo -= frames->first().no; + return fmodf(frameNo, frames->last().no - frames->first().no) + (*frames)[exp->loop.key].no; + } + case LottieExpression::LoopMode::OutCycle: { + frameNo -= frames->first().no; + return fmodf(frameNo, (*frames)[frames->count - 1 - exp->loop.key].no - frames->first().no) + frames->first().no; + } + default: break; + } + return frameNo; +} + + +template +struct LottieGenericProperty : LottieProperty +{ + //Property has an either keyframes or single value. + Array>* frames = nullptr; + T value; + + LottieGenericProperty(T v) : value(v) {} + LottieGenericProperty() {} + + ~LottieGenericProperty() + { + release(); + } + + void release() + { + delete(frames); + frames = nullptr; + if (exp) { + delete(exp); + exp = nullptr; + } + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) frames = new Array>; + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + T operator()(float frameNo) + { + if (!frames) return value; + if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; + if (frameNo >= frames->last().no) return frames->last().value; + + auto frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) return frame->value; + return frame->interpolate(frame + 1, frameNo); + } + + T operator()(float frameNo, LottieExpressions* exps) + { + if (exps && (exp && exp->enabled)) { + T out{}; + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result>(frameNo, out, exp)) return out; + } + return operator()(frameNo); + } + + T& operator=(const T& other) + { + //shallow copy, used for slot overriding + if (other.frames) { + frames = other.frames; + const_cast(other).frames = nullptr; + } else value = other.value; + return *this; + } + + float angle(float frameNo) { return 0; } + void prepare() {} +}; + + +struct LottiePathSet : LottieProperty +{ + Array>* frames = nullptr; + PathSet value; + + ~LottiePathSet() + { + release(); + } + + void release() + { + if (exp) { + delete(exp); + exp = nullptr; + } + + free(value.cmds); + free(value.pts); + + if (!frames) return; + + for (auto p = frames->begin(); p < frames->end(); ++p) { + free((*p).value.cmds); + free((*p).value.pts); + } + free(frames->data); + free(frames); + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) { + frames = static_cast>*>(calloc(1, sizeof(Array>))); + } + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + bool operator()(float frameNo, Array& cmds, Array& pts, Matrix* transform, float roundness) + { + PathSet* path = nullptr; + LottieScalarFrame* frame = nullptr; + float t; + bool interpolate = false; + + if (!frames) path = &value; + else if (frames->count == 1 || frameNo <= frames->first().no) path = &frames->first().value; + else if (frameNo >= frames->last().no) path = &frames->last().value; + else { + frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) path = &frame->value; + else { + t = (frameNo - frame->no) / ((frame + 1)->no - frame->no); + if (frame->interpolator) t = frame->interpolator->progress(t); + if (frame->hold) path = &(frame + ((t < 1.0f) ? 0 : 1))->value; + else interpolate = true; + } + } + + if (!interpolate) { + if (roundness > ROUNDNESS_EPSILON) return _modifier(path->pts, path->ptsCnt, path->cmds, path->cmdsCnt, cmds, pts, transform, roundness); + _copy(path, cmds); + _copy(path, pts, transform); + return true; + } + + auto s = frame->value.pts; + auto e = (frame + 1)->value.pts; + + if (roundness > ROUNDNESS_EPSILON) { + auto interpPts = (Point*)malloc(frame->value.ptsCnt * sizeof(Point)); + auto p = interpPts; + for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) { + *p = mathLerp(*s, *e, t); + if (transform) mathMultiply(p, transform); + } + _modifier(interpPts, frame->value.ptsCnt, frame->value.cmds, frame->value.cmdsCnt, cmds, pts, nullptr, roundness); + free(interpPts); + return true; + } else { + for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) { + auto pt = mathLerp(*s, *e, t); + if (transform) mathMultiply(&pt, transform); + pts.push(pt); + } + _copy(&frame->value, cmds); + } + return true; + } + + + bool operator()(float frameNo, Array& cmds, Array& pts, Matrix* transform, float roundness, LottieExpressions* exps) + { + if (exps && (exp && exp->enabled)) { + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result(frameNo, cmds, pts, transform, roundness, exp)) return true; + } + return operator()(frameNo, cmds, pts, transform, roundness); + } + + void prepare() {} +}; + + +struct LottieColorStop : LottieProperty +{ + Array>* frames = nullptr; + ColorStop value; + uint16_t count = 0; //colorstop count + bool populated = false; + + ~LottieColorStop() + { + release(); + } + + void release() + { + if (exp) { + delete(exp); + exp = nullptr; + } + + if (value.data) { + free(value.data); + value.data = nullptr; + } + + if (!frames) return; + + for (auto p = frames->begin(); p < frames->end(); ++p) { + free((*p).value.data); + } + free(frames->data); + free(frames); + frames = nullptr; + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) { + frames = static_cast>*>(calloc(1, sizeof(Array>))); + } + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + Result operator()(float frameNo, Fill* fill, LottieExpressions* exps) + { + if (exps && (exp && exp->enabled)) { + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result(frameNo, fill, exp)) return Result::Success; + } + + if (!frames) return fill->colorStops(value.data, count); + + if (frames->count == 1 || frameNo <= frames->first().no) { + return fill->colorStops(frames->first().value.data, count); + } + + if (frameNo >= frames->last().no) return fill->colorStops(frames->last().value.data, count); + + auto frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) return fill->colorStops(frame->value.data, count); + + //interpolate + auto t = (frameNo - frame->no) / ((frame + 1)->no - frame->no); + if (frame->interpolator) t = frame->interpolator->progress(t); + + if (frame->hold) { + if (t < 1.0f) fill->colorStops(frame->value.data, count); + else fill->colorStops((frame + 1)->value.data, count); + } + + auto s = frame->value.data; + auto e = (frame + 1)->value.data; + + Array result; + + for (auto i = 0; i < count; ++i, ++s, ++e) { + auto offset = mathLerp(s->offset, e->offset, t); + auto r = mathLerp(s->r, e->r, t); + auto g = mathLerp(s->g, e->g, t); + auto b = mathLerp(s->b, e->b, t); + auto a = mathLerp(s->a, e->a, t); + result.push({offset, r, g, b, a}); + } + return fill->colorStops(result.data, count); + } + + LottieColorStop& operator=(const LottieColorStop& other) + { + //shallow copy, used for slot overriding + if (other.frames) { + frames = other.frames; + const_cast(other).frames = nullptr; + } else { + value = other.value; + const_cast(other).value = {nullptr, nullptr}; + } + populated = other.populated; + count = other.count; + + return *this; + } + + void prepare() {} +}; + + +struct LottiePosition : LottieProperty +{ + Array>* frames = nullptr; + Point value; + + LottiePosition(Point v) : value(v) + { + } + + ~LottiePosition() + { + release(); + } + + void release() + { + delete(frames); + frames = nullptr; + + if (exp) { + delete(exp); + exp = nullptr; + } + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieVectorFrame& newFrame() + { + if (!frames) frames = new Array>; + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieVectorFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieVectorFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + Point operator()(float frameNo) + { + if (!frames) return value; + if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; + if (frameNo >= frames->last().no) return frames->last().value; + + auto frame = frames->data + _bsearch(frames, frameNo); + if (mathEqual(frame->no, frameNo)) return frame->value; + return frame->interpolate(frame + 1, frameNo); + } + + Point operator()(float frameNo, LottieExpressions* exps) + { + Point out{}; + if (exps && (exp && exp->enabled)) { + if (exp->loop.mode != LottieExpression::LoopMode::None) frameNo = _loop(frames, frameNo, exp); + if (exps->result(frameNo, out, exp)) return out; + } + return operator()(frameNo); + } + + float angle(float frameNo) + { + if (!frames) return 0; + if (frames->count == 1 || frameNo <= frames->first().no) return 0; + if (frameNo >= frames->last().no) return 0; + + auto frame = frames->data + _bsearch(frames, frameNo); + return frame->angle(frame + 1, frameNo); + } + + void prepare() + { + if (!frames || frames->count < 2) return; + for (auto frame = frames->begin() + 1; frame < frames->end(); ++frame) { + (frame - 1)->prepare(frame); + } + } +}; + + +struct LottieTextDoc : LottieProperty +{ + Array>* frames = nullptr; + TextDocument value; + + ~LottieTextDoc() + { + release(); + } + + void release() + { + if (exp) { + delete(exp); + exp = nullptr; + } + + if (value.text) { + free(value.text); + value.text = nullptr; + } + if (value.name) { + free(value.name); + value.name = nullptr; + } + + if (!frames) return; + + for (auto p = frames->begin(); p < frames->end(); ++p) { + free((*p).value.text); + free((*p).value.name); + } + delete(frames); + frames = nullptr; + } + + uint32_t nearest(float frameNo) override + { + return _nearest(frames, frameNo); + } + + uint32_t frameCnt() override + { + return frames ? frames->count : 1; + } + + float frameNo(int32_t key) override + { + return _frameNo(frames, key); + } + + LottieScalarFrame& newFrame() + { + if (!frames) frames = new Array>; + if (frames->count + 1 >= frames->reserved) { + auto old = frames->reserved; + frames->grow(frames->count + 2); + memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame) * (frames->reserved - old)); + } + ++frames->count; + return frames->last(); + } + + LottieScalarFrame& nextFrame() + { + return (*frames)[frames->count]; + } + + TextDocument& operator()(float frameNo) + { + if (!frames) return value; + if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value; + if (frameNo >= frames->last().no) return frames->last().value; + + auto frame = frames->data + _bsearch(frames, frameNo); + return frame->value; + } + + LottieTextDoc& operator=(const LottieTextDoc& other) + { + //shallow copy, used for slot overriding + if (other.frames) { + frames = other.frames; + const_cast(other).frames = nullptr; + } else { + value = other.value; + const_cast(other).value.text = nullptr; + const_cast(other).value.name = nullptr; + } + return *this; + } + + void prepare() {} +}; + + +using LottiePoint = LottieGenericProperty; +using LottieFloat = LottieGenericProperty; +using LottieOpacity = LottieGenericProperty; +using LottieColor = LottieGenericProperty; + +#endif //_TVG_LOTTIE_PROPERTY_H_ + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.cpp index cf43490df..509a459d5 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -74,9 +74,9 @@ void mathRotate(Matrix* m, float degree) { if (degree == 0.0f) return; - auto radian = degree / 180.0f * (float)M_PI; - auto cosVal = cosf((float)radian); - auto sinVal = sinf((float)radian); + auto radian = degree / 180.0f * MATH_PI; + auto cosVal = cosf(radian); + auto sinVal = sinf(radian); m->e12 = m->e11 * -sinVal; m->e11 *= cosVal; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.h index 3f48e3cac..49bbe1864 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgMath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,8 @@ #define MATH_PI 3.14159265358979323846f #define MATH_PI2 1.57079632679489661923f +#define FLOAT_EPSILON 1.0e-06f //1.192092896e-07f +#define PATH_KAPPA 0.552284f #define mathMin(x, y) (((x) < (y)) ? (x) : (y)) #define mathMax(x, y) (((x) > (y)) ? (x) : (y)) @@ -46,15 +48,33 @@ bool mathIdentity(const Matrix* m); void mathMultiply(Point* pt, const Matrix* transform); +static inline float mathDeg2Rad(float degree) +{ + return degree * (MATH_PI / 180.0f); +} + + +static inline float mathRad2Deg(float radian) +{ + return radian * (180.0f / MATH_PI); +} + + static inline bool mathZero(float a) { - return (fabsf(a) < FLT_EPSILON) ? true : false; + return (fabsf(a) <= FLOAT_EPSILON) ? true : false; +} + + +static inline bool mathZero(const Point& p) +{ + return mathZero(p.x) && mathZero(p.y); } static inline bool mathEqual(float a, float b) { - return (fabsf(a - b) < FLT_EPSILON); + return mathZero(a - b); } @@ -72,14 +92,14 @@ static inline bool mathEqual(const Matrix& a, const Matrix& b) static inline bool mathRightAngle(const Matrix* m) { auto radian = fabsf(atan2f(m->e21, m->e11)); - if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true; + if (radian < FLOAT_EPSILON || mathEqual(radian, MATH_PI2) || mathEqual(radian, MATH_PI)) return true; return false; } static inline bool mathSkewed(const Matrix* m) { - return (fabsf(m->e21 + m->e12) > FLT_EPSILON); + return !mathZero(m->e21 + m->e12); } @@ -159,6 +179,12 @@ static inline float mathLength(const Point* a, const Point* b) } +static inline float mathLength(const Point& a) +{ + return sqrtf(a.x * a.x + a.y * a.y); +} + + static inline Point operator-(const Point& lhs, const Point& rhs) { return {lhs.x - rhs.x, lhs.y - rhs.y}; @@ -177,6 +203,18 @@ static inline Point operator*(const Point& lhs, float rhs) } +static inline Point operator*(const float& lhs, const Point& rhs) +{ + return {lhs * rhs.x, lhs * rhs.y}; +} + + +static inline Point operator/(const Point& lhs, const float rhs) +{ + return {lhs.x / rhs, lhs.y / rhs}; +} + + template static inline T mathLerp(const T &start, const T &end, float t) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.cpp index 50ba3e6cc..4db483107 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,26 +25,45 @@ #include "tvgMath.h" #include "tvgPaint.h" +#include "tvgShape.h" +#include "tvgPicture.h" +#include "tvgScene.h" +#include "tvgText.h" /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ +#define PAINT_METHOD(ret, METHOD) \ + switch (id) { \ + case TVG_CLASS_ID_SHAPE: ret = P((Shape*)paint)->METHOD; break; \ + case TVG_CLASS_ID_SCENE: ret = P((Scene*)paint)->METHOD; break; \ + case TVG_CLASS_ID_PICTURE: ret = P((Picture*)paint)->METHOD; break; \ + case TVG_CLASS_ID_TEXT: ret = P((Text*)paint)->METHOD; break; \ + default: ret = {}; \ + } -static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) + + +static Result _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) { /* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */ auto shape = static_cast(cmpTarget); //Rectangle Candidates? const Point* pts; - if (shape->pathCoords(&pts) != 4) return false; + auto ptsCnt = shape->pathCoords(&pts); + + //nothing to clip + if (ptsCnt == 0) return Result::InvalidArguments; + + if (ptsCnt != 4) return Result::InsufficientCondition; if (rTransform) rTransform->update(); //No rotation and no skewing - if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return false; - if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return false; + if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return Result::InsufficientCondition; + if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return Result::InsufficientCondition; //Perpendicular Rectangle? auto pt1 = pts + 0; @@ -89,16 +108,32 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, if (viewport.w < 0) viewport.w = 0; if (viewport.h < 0) viewport.h = 0; - return true; + return Result::Success; } + return Result::InsufficientCondition; +} - return false; + +RenderRegion Paint::Impl::bounds(RenderMethod* renderer) const +{ + RenderRegion ret; + PAINT_METHOD(ret, bounds(renderer)); + return ret; +} + + +Iterator* Paint::Impl::iterator() +{ + Iterator* ret; + PAINT_METHOD(ret, iterator()); + return ret; } Paint* Paint::Impl::duplicate() { - auto ret = smethod->duplicate(); + Paint* ret; + PAINT_METHOD(ret, duplicate()); //duplicate Transform if (rTransform) { @@ -161,47 +196,54 @@ bool Paint::Impl::translate(float x, float y) } -bool Paint::Impl::render(RenderMethod& renderer) +bool Paint::Impl::render(RenderMethod* renderer) { Compositor* cmp = nullptr; /* Note: only ClipPath is processed in update() step. Create a composition image. */ if (compData && compData->method != CompositeMethod::ClipPath && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) { - auto region = smethod->bounds(renderer); - if (MASK_REGION_MERGING(compData->method)) region.add(compData->target->pImpl->smethod->bounds(renderer)); + RenderRegion region; + PAINT_METHOD(region, bounds(renderer)); + + if (MASK_REGION_MERGING(compData->method)) region.add(P(compData->target)->bounds(renderer)); if (region.w == 0 || region.h == 0) return true; - cmp = renderer.target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method)); - if (renderer.beginComposite(cmp, CompositeMethod::None, 255)) { + cmp = renderer->target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method)); + if (renderer->beginComposite(cmp, CompositeMethod::None, 255)) { compData->target->pImpl->render(renderer); } } - if (cmp) renderer.beginComposite(cmp, compData->method, compData->target->pImpl->opacity); + if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity); - renderer.blend(blendMethod); - auto ret = smethod->render(renderer); + renderer->blend(blendMethod); - if (cmp) renderer.endComposite(cmp); + bool ret; + PAINT_METHOD(ret, render(renderer)); + + if (cmp) renderer->endComposite(cmp); return ret; } -RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) +RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { + if (this->renderer != renderer) { + if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); + renderer->ref(); + this->renderer = renderer; + } + if (renderFlag & RenderUpdateFlag::Transform) { if (!rTransform) return nullptr; - if (!rTransform->update()) { - delete(rTransform); - rTransform = nullptr; - } + rTransform->update(); } /* 1. Composition Pre Processing */ RenderData trd = nullptr; //composite target render data RenderRegion viewport; - bool compFastTrack = false; + Result compFastTrack = Result::InsufficientCondition; bool childClipper = false; if (compData) { @@ -226,15 +268,15 @@ RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pT } if (tryFastTrack) { RenderRegion viewport2; - if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2))) { - viewport = renderer.viewport(); + if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2)) == Result::Success) { + viewport = renderer->viewport(); viewport2.intersect(viewport); - renderer.viewport(viewport2); + renderer->viewport(viewport2); target->pImpl->ctxFlag |= ContextFlag::FastTrack; } } } - if (!compFastTrack) { + if (compFastTrack == Result::InsufficientCondition) { childClipper = compData->method == CompositeMethod::ClipPath ? true : false; trd = target->pImpl->update(renderer, pTransform, clips, 255, pFlag, childClipper); if (childClipper) clips.push(trd); @@ -242,21 +284,16 @@ RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pT } /* 2. Main Update */ - RenderData rd = nullptr; auto newFlag = static_cast(pFlag | renderFlag); renderFlag = RenderUpdateFlag::None; opacity = MULTIPLY(opacity, this->opacity); - if (rTransform && pTransform) { - RenderTransform outTransform(pTransform, rTransform); - rd = smethod->update(renderer, &outTransform, clips, opacity, newFlag, clipper); - } else { - auto outTransform = pTransform ? pTransform : rTransform; - rd = smethod->update(renderer, outTransform, clips, opacity, newFlag, clipper); - } + RenderData rd = nullptr; + RenderTransform outTransform(pTransform, rTransform); + PAINT_METHOD(rd, update(renderer, &outTransform, clips, opacity, newFlag, clipper)); /* 3. Composition Post Processing */ - if (compFastTrack) renderer.viewport(viewport); + if (compFastTrack == Result::Success) renderer->viewport(viewport); else if (childClipper) clips.pop(); return rd; @@ -266,9 +303,13 @@ RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pT bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking) { Matrix* m = nullptr; + bool ret; //Case: No transformed, quick return! - if (!transformed || !(m = this->transform())) return smethod->bounds(x, y, w, h, stroking); + if (!transformed || !(m = this->transform())) { + PAINT_METHOD(ret, bounds(x, y, w, h, stroking)); + return ret; + } //Case: Transformed auto tx = 0.0f; @@ -276,7 +317,7 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme auto tw = 0.0f; auto th = 0.0f; - auto ret = smethod->bounds(&tx, &ty, &tw, &th, stroking); + PAINT_METHOD(ret, bounds(&tx, &ty, &tw, &th, stroking)); //Get vertices Point pt[4] = {{tx, ty}, {tx + tw, ty}, {tx + tw, ty + th}, {tx, ty + th}}; @@ -310,7 +351,7 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme /* External Class Implementation */ /************************************************************************/ -Paint :: Paint() : pImpl(new Impl()) +Paint :: Paint() : pImpl(new Impl(this)) { } @@ -422,7 +463,10 @@ uint32_t Paint::identifier() const noexcept Result Paint::blend(BlendMethod method) const noexcept { - pImpl->blendMethod = method; + if (pImpl->blendMethod != method) { + pImpl->blendMethod = method; + pImpl->renderFlag |= RenderUpdateFlag::Blend; + } return Result::Success; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.h index ea5878d85..a3fbc0748 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPaint.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,19 +41,6 @@ namespace tvg virtual void begin() = 0; }; - struct StrategyMethod - { - virtual ~StrategyMethod() {} - - virtual bool dispose(RenderMethod& renderer) = 0; //return true if the deletion is allowed. - virtual void* update(RenderMethod& renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) = 0; //Return engine data if it has. - virtual bool render(RenderMethod& renderer) = 0; - virtual bool bounds(float* x, float* y, float* w, float* h, bool stroking) = 0; - virtual RenderRegion bounds(RenderMethod& renderer) const = 0; - virtual Paint* duplicate() = 0; - virtual Iterator* iterator() = 0; - }; - struct Composite { Paint* target; @@ -63,41 +50,39 @@ namespace tvg struct Paint::Impl { - StrategyMethod* smethod = nullptr; + Paint* paint = nullptr; RenderTransform* rTransform = nullptr; Composite* compData = nullptr; - BlendMethod blendMethod = BlendMethod::Normal; //uint8_t + RenderMethod* renderer = nullptr; + BlendMethod blendMethod = BlendMethod::Normal; //uint8_t uint8_t renderFlag = RenderUpdateFlag::None; uint8_t ctxFlag = ContextFlag::Invalid; uint8_t id; uint8_t opacity = 255; - uint8_t refCnt = 0; + uint8_t refCnt = 0; //reference count + + Impl(Paint* pnt) : paint(pnt) {} ~Impl() { if (compData) { - delete(compData->target); + if (P(compData->target)->unref() == 0) delete(compData->target); free(compData); } - delete(smethod); delete(rTransform); + if (renderer && (renderer->unref() == 0)) delete(renderer); } uint8_t ref() { if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!"); - return (++refCnt); + return ++refCnt; } uint8_t unref() { if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!"); - return (--refCnt); - } - - void method(StrategyMethod* method) - { - smethod = method; + return --refCnt; } bool transform(const Matrix& m) @@ -122,29 +107,16 @@ namespace tvg return nullptr; } - RenderRegion bounds(RenderMethod& renderer) const - { - return smethod->bounds(renderer); - } - - bool dispose(RenderMethod& renderer) - { - if (compData) compData->target->pImpl->dispose(renderer); - return smethod->dispose(renderer); - } - - Iterator* iterator() - { - return smethod->iterator(); - } - bool composite(Paint* source, Paint* target, CompositeMethod method) { //Invalid case if ((!target && method != CompositeMethod::None) || (target && method == CompositeMethod::None)) return false; if (compData) { - delete(compData->target); + P(compData->target)->unref(); + if ((compData->target != target) && P(compData->target)->refCnt == 0) { + delete(compData->target); + } //Reset scenario if (!target && method == CompositeMethod::None) { free(compData); @@ -155,65 +127,23 @@ namespace tvg if (!target && method == CompositeMethod::None) return true; compData = static_cast(calloc(1, sizeof(Composite))); } + P(target)->ref(); compData->target = target; compData->source = source; compData->method = method; return true; } + RenderRegion bounds(RenderMethod* renderer) const; + Iterator* iterator(); bool rotate(float degree); bool scale(float factor); bool translate(float x, float y); bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking); - RenderData update(RenderMethod& renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); - bool render(RenderMethod& renderer); + RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); + bool render(RenderMethod* renderer); Paint* duplicate(); }; - - - template - struct PaintMethod : StrategyMethod - { - T* inst = nullptr; - - PaintMethod(T* _inst) : inst(_inst) {} - ~PaintMethod() {} - - bool bounds(float* x, float* y, float* w, float* h, bool stroking) override - { - return inst->bounds(x, y, w, h, stroking); - } - - RenderRegion bounds(RenderMethod& renderer) const override - { - return inst->bounds(renderer); - } - - bool dispose(RenderMethod& renderer) override - { - return inst->dispose(renderer); - } - - RenderData update(RenderMethod& renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag renderFlag, bool clipper) override - { - return inst->update(renderer, transform, clips, opacity, renderFlag, clipper); - } - - bool render(RenderMethod& renderer) override - { - return inst->render(renderer); - } - - Paint* duplicate() override - { - return inst->duplicate(); - } - - Iterator* iterator() override - { - return inst->iterator(); - } - }; } #endif //_TVG_PAINT_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.cpp index e58d68ea3..3d7859d22 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,10 +32,11 @@ RenderUpdateFlag Picture::Impl::load() { if (loader) { - if (!paint) { - if (auto p = loader->paint()) { - paint = p.release(); - loader->close(); + if (paint) { + loader->sync(); + } else { + paint = loader->paint(); + if (paint) { if (w != loader->w || h != loader->h) { if (!resizing) { w = loader->w; @@ -44,13 +45,11 @@ RenderUpdateFlag Picture::Impl::load() loader->resize(paint, w, h); resizing = false; } - if (paint) return RenderUpdateFlag::None; + return RenderUpdateFlag::None; } - } else loader->sync(); - + } if (!surface) { - if ((surface = loader->bitmap().release())) { - loader->close(); + if ((surface = loader->bitmap())) { return RenderUpdateFlag::Image; } } @@ -58,6 +57,93 @@ RenderUpdateFlag Picture::Impl::load() return RenderUpdateFlag::None; } + +bool Picture::Impl::needComposition(uint8_t opacity) +{ + //In this case, paint(scene) would try composition itself. + if (opacity < 255) return false; + + //Composition test + const Paint* target; + auto method = picture->composite(&target); + if (!target || method == tvg::CompositeMethod::ClipPath) return false; + if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false; + + return true; +} + + +bool Picture::Impl::render(RenderMethod* renderer) +{ + bool ret = false; + if (surface) return renderer->renderImage(rd); + else if (paint) { + Compositor* cmp = nullptr; + if (needComp) { + cmp = renderer->target(bounds(renderer), renderer->colorSpace()); + renderer->beginComposite(cmp, CompositeMethod::None, 255); + } + ret = paint->pImpl->render(renderer); + if (cmp) renderer->endComposite(cmp); + } + return ret; +} + + +bool Picture::Impl::size(float w, float h) +{ + this->w = w; + this->h = h; + resizing = true; + return true; +} + + +RenderRegion Picture::Impl::bounds(RenderMethod* renderer) +{ + if (rd) return renderer->region(rd); + if (paint) return paint->pImpl->bounds(renderer); + return {0, 0, 0, 0}; +} + + +RenderTransform Picture::Impl::resizeTransform(const RenderTransform* pTransform) +{ + //Overriding Transformation by the desired image size + auto sx = w / loader->w; + auto sy = h / loader->h; + auto scale = sx < sy ? sx : sy; + + RenderTransform tmp; + tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1}; + + if (!pTransform) return tmp; + else return RenderTransform(pTransform, &tmp); +} + + +Result Picture::Impl::load(ImageLoader* loader) +{ + //Same resource has been loaded. + if (this->loader == loader) { + this->loader->sharing--; //make it sure the reference counting. + return Result::Success; + } else if (this->loader) { + LoaderMgr::retrieve(this->loader); + } + + this->loader = loader; + + if (!loader->read()) return Result::Unknown; + + this->w = loader->w; + this->h = loader->h; + + return Result::Success; +} + + + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -65,7 +151,6 @@ RenderUpdateFlag Picture::Impl::load() Picture::Picture() : pImpl(new Impl(this)) { Paint::pImpl->id = TVG_CLASS_ID_PICTURE; - Paint::pImpl->method(new PaintMethod(pImpl)); } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.h index a9a52a98f..7c3ec5407 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgPicture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,16 +23,13 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#ifndef _TVG_PICTURE_IMPL_H_ -#define _TVG_PICTURE_IMPL_H_ +#ifndef _TVG_PICTURE_H_ +#define _TVG_PICTURE_H_ #include #include "tvgPaint.h" #include "tvgLoader.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct PictureIterator : Iterator { @@ -63,7 +60,7 @@ struct PictureIterator : Iterator struct Picture::Impl { - shared_ptr loader = nullptr; + ImageLoader* loader = nullptr; Paint* paint = nullptr; //vector picture uses Surface* surface = nullptr; //bitmap picture uses @@ -74,59 +71,35 @@ struct Picture::Impl bool resizing = false; bool needComp = false; //need composition + RenderTransform resizeTransform(const RenderTransform* pTransform); + bool needComposition(uint8_t opacity); + bool render(RenderMethod* renderer); + bool size(float w, float h); + RenderRegion bounds(RenderMethod* renderer); + Result load(ImageLoader* ploader); + Impl(Picture* p) : picture(p) { } ~Impl() { + LoaderMgr::retrieve(loader); + if (surface) { + if (auto renderer = PP(picture)->renderer) { + renderer->dispose(rd); + } + } delete(paint); - delete(surface); } - bool dispose(RenderMethod& renderer) - { - if (paint) paint->pImpl->dispose(renderer); - else if (surface) renderer.dispose(rd); - rd = nullptr; - return true; - } - - RenderTransform resizeTransform(const RenderTransform* pTransform) - { - //Overriding Transformation by the desired image size - auto sx = w / loader->w; - auto sy = h / loader->h; - auto scale = sx < sy ? sx : sy; - - RenderTransform tmp; - tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1}; - - if (!pTransform) return tmp; - else return RenderTransform(pTransform, &tmp); - } - - bool needComposition(uint8_t opacity) - { - //In this case, paint(scene) would try composition itself. - if (opacity < 255) return false; - - //Composition test - const Paint* target; - auto method = picture->composite(&target); - if (!target || method == tvg::CompositeMethod::ClipPath) return false; - if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false; - - return true; - } - - RenderData update(RenderMethod &renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { auto flag = load(); if (surface) { auto transform = resizeTransform(pTransform); - rd = renderer.prepare(surface, &rm, rd, &transform, clips, opacity, static_cast(pFlag | flag)); + rd = renderer->prepare(surface, &rm, rd, &transform, clips, opacity, static_cast(pFlag | flag)); } else if (paint) { if (resizing) { loader->resize(paint, w, h); @@ -138,30 +111,6 @@ struct Picture::Impl return rd; } - bool render(RenderMethod &renderer) - { - bool ret = false; - if (surface) return renderer.renderImage(rd); - else if (paint) { - Compositor* cmp = nullptr; - if (needComp) { - cmp = renderer.target(bounds(renderer), renderer.colorSpace()); - renderer.beginComposite(cmp, CompositeMethod::None, 255); - } - ret = paint->pImpl->render(renderer); - if (cmp) renderer.endComposite(cmp); - } - return ret; - } - - bool size(float w, float h) - { - this->w = w; - this->h = h; - resizing = true; - return true; - } - bool bounds(float* x, float* y, float* w, float* h, bool stroking) { if (rm.triangleCnt > 0) { @@ -198,50 +147,35 @@ struct Picture::Impl return true; } - RenderRegion bounds(RenderMethod& renderer) - { - if (rd) return renderer.region(rd); - if (paint) return paint->pImpl->bounds(renderer); - return {0, 0, 0, 0}; - } - Result load(const string& path) { if (paint || surface) return Result::InsufficientCondition; - if (loader) loader->close(); + bool invalid; //Invalid Path - loader = LoaderMgr::loader(path, &invalid); + auto loader = static_cast(LoaderMgr::loader(path, &invalid)); if (!loader) { if (invalid) return Result::InvalidArguments; return Result::NonSupport; } - if (!loader->read()) return Result::Unknown; - w = loader->w; - h = loader->h; - return Result::Success; + return load(loader); } Result load(const char* data, uint32_t size, const string& mimeType, bool copy) { if (paint || surface) return Result::InsufficientCondition; - if (loader) loader->close(); - loader = LoaderMgr::loader(data, size, mimeType, copy); + auto loader = static_cast(LoaderMgr::loader(data, size, mimeType, copy)); if (!loader) return Result::NonSupport; - if (!loader->read()) return Result::Unknown; - w = loader->w; - h = loader->h; - return Result::Success; + return load(loader); } Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) { if (paint || surface) return Result::InsufficientCondition; - if (loader) loader->close(); - loader = LoaderMgr::loader(data, w, h, copy); + + auto loader = static_cast(LoaderMgr::loader(data, w, h, copy)); if (!loader) return Result::FailedAllocation; - this->w = loader->w; - this->h = loader->h; - return Result::Success; + + return load(loader); } void mesh(const Polygon* triangles, const uint32_t triangleCnt) @@ -261,18 +195,17 @@ struct Picture::Impl { load(); - auto ret = Picture::gen(); + auto ret = Picture::gen().release(); + auto dup = ret->pImpl; - auto dup = ret.get()->pImpl; if (paint) dup->paint = paint->duplicate(); - dup->loader = loader; - if (surface) { - dup->surface = new Surface; - *dup->surface = *surface; - //TODO: A dupilcation is not a proxy... it needs copy of the pixel data? - dup->surface->owner = false; + if (loader) { + dup->loader = loader; + ++dup->loader->sharing; } + + dup->surface = surface; dup->w = w; dup->h = h; dup->resizing = resizing; @@ -283,7 +216,7 @@ struct Picture::Impl memcpy(dup->rm.triangles, rm.triangles, sizeof(Polygon) * rm.triangleCnt); } - return ret.release(); + return ret; } Iterator* iterator() @@ -311,7 +244,7 @@ struct Picture::Impl RenderUpdateFlag load(); }; -#endif //_TVG_PICTURE_IMPL_H_ +#endif //_TVG_PICTURE_H_ #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.cpp index b20c7fda8..227414121 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,17 +37,21 @@ /* External Class Implementation */ /************************************************************************/ +RawLoader::RawLoader() : ImageLoader(FileType::Raw) +{ +} + + RawLoader::~RawLoader() { - if (copy && content) { - free((void*)content); - content = nullptr; - } + if (copy) free(surface.buf32); } bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { + if (!LoadModule::read()) return true; + if (!data || w == 0 || h == 0) return false; this->w = (float)w; @@ -55,13 +59,19 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) this->copy = copy; if (copy) { - content = (uint32_t*)malloc(sizeof(uint32_t) * w * h); - if (!content) return false; - memcpy((void*)content, data, sizeof(uint32_t) * w * h); + surface.buf32 = (uint32_t*)malloc(sizeof(uint32_t) * w * h); + if (!surface.buf32) return false; + memcpy((void*)surface.buf32, data, sizeof(uint32_t) * w * h); } - else content = const_cast(data); + else surface.buf32 = const_cast(data); - cs = ColorSpace::ARGB8888; + //setup the surface + surface.stride = w; + surface.w = w; + surface.h = h; + surface.cs = ColorSpace::ARGB8888; + surface.channelSize = sizeof(uint32_t); + surface.premultiplied = true; return true; } @@ -69,33 +79,10 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) bool RawLoader::read() { + LoadModule::read(); + return true; } - -bool RawLoader::close() -{ - return true; -} - - -unique_ptr RawLoader::bitmap() -{ - if (!content) return nullptr; - - //TODO: It's better to keep this surface instance in the loader side - auto surface = new Surface; - surface->buf32 = content; - surface->stride = static_cast(w); - surface->w = static_cast(w); - surface->h = static_cast(h); - surface->cs = cs; - surface->channelSize = sizeof(uint32_t); - surface->premultiplied = false; - surface->owner = true; - - return unique_ptr(surface); -} - #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.h index bc3851f55..492fd5341 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRawLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,20 +26,17 @@ #ifndef _TVG_RAW_LOADER_H_ #define _TVG_RAW_LOADER_H_ -class RawLoader : public LoadModule +class RawLoader : public ImageLoader { public: - uint32_t* content = nullptr; bool copy = false; + RawLoader(); ~RawLoader(); using LoadModule::open; - bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) override; + bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy); bool read() override; - bool close() override; - - unique_ptr bitmap() override; }; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.cpp index 9994c8cbb..dad20e8b5 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,12 +42,9 @@ void RenderTransform::override(const Matrix& m) } -bool RenderTransform::update() +void RenderTransform::update() { - if (overriding) return true; - - //Init Status - if (mathZero(x) && mathZero(y) && mathZero(degree) && mathEqual(scale, 1)) return false; + if (overriding) return; mathIdentity(&m); @@ -56,19 +53,47 @@ bool RenderTransform::update() if (!mathZero(degree)) mathRotate(&m, degree); mathTranslate(&m, x, y); - - return true; -} - - -RenderTransform::RenderTransform() -{ } RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs) { - m = mathMultiply(&lhs->m, &rhs->m); + if (lhs && rhs) m = mathMultiply(&lhs->m, &rhs->m); + else if (lhs) m = lhs->m; + else if (rhs) m = rhs->m; + else mathIdentity(&m); +} + + +void RenderRegion::intersect(const RenderRegion& rhs) +{ + auto x1 = x + w; + auto y1 = y + h; + auto x2 = rhs.x + rhs.w; + auto y2 = rhs.y + rhs.h; + + x = (x > rhs.x) ? x : rhs.x; + y = (y > rhs.y) ? y : rhs.y; + w = ((x1 < x2) ? x1 : x2) - x; + h = ((y1 < y2) ? y1 : y2) - y; + + if (w < 0) w = 0; + if (h < 0) h = 0; +} + + +void RenderRegion::add(const RenderRegion& rhs) +{ + if (rhs.x < x) { + w += (x - rhs.x); + x = rhs.x; + } + if (rhs.y < y) { + h += (y - rhs.y); + y = rhs.y; + } + if (rhs.x + rhs.w > x + w) w = (rhs.x + rhs.w) - x; + if (rhs.y + rhs.h > y + h) h = (rhs.y + rhs.h) - y; } #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.h index d95c37cc0..8467a9101 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgRender.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +28,7 @@ #include "tvgCommon.h" #include "tvgArray.h" +#include "tvgLock.h" namespace tvg { @@ -35,7 +36,7 @@ namespace tvg using RenderData = void*; using pixel_t = uint32_t; -enum RenderUpdateFlag : uint8_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255}; +enum RenderUpdateFlag : uint8_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, All = 255}; struct Surface; @@ -52,17 +53,33 @@ enum ColorSpace struct Surface { union { - pixel_t* data; //system based data pointer - uint32_t* buf32; //for explicit 32bits channels - uint8_t* buf8; //for explicit 8bits grayscale + pixel_t* data = nullptr; //system based data pointer + uint32_t* buf32; //for explicit 32bits channels + uint8_t* buf8; //for explicit 8bits grayscale }; - uint32_t stride; - uint32_t w, h; - ColorSpace cs; - uint8_t channelSize; + Key key; //a reserved lock for the thread safety + uint32_t stride = 0; + uint32_t w = 0, h = 0; + ColorSpace cs = ColorSpace::Unsupported; + uint8_t channelSize = 0; + bool premultiplied = false; //Alpha-premultiplied + + Surface() + { + } + + Surface(const Surface* rhs) + { + data = rhs->data; + stride = rhs->stride; + w = rhs->w; + h = rhs->h; + cs = rhs->cs; + channelSize = rhs->channelSize; + premultiplied = rhs->premultiplied; + } + - bool premultiplied; //Alpha-premultiplied - bool owner; //Only owner could modify the buffer }; struct Compositor @@ -86,34 +103,13 @@ struct RenderRegion { int32_t x, y, w, h; - void intersect(const RenderRegion& rhs) + void intersect(const RenderRegion& rhs); + void add(const RenderRegion& rhs); + + bool operator==(const RenderRegion& rhs) { - auto x1 = x + w; - auto y1 = y + h; - auto x2 = rhs.x + rhs.w; - auto y2 = rhs.y + rhs.h; - - x = (x > rhs.x) ? x : rhs.x; - y = (y > rhs.y) ? y : rhs.y; - w = ((x1 < x2) ? x1 : x2) - x; - h = ((y1 < y2) ? y1 : y2) - y; - - if (w < 0) w = 0; - if (h < 0) h = 0; - } - - void add(const RenderRegion& rhs) - { - if (rhs.x < x) { - w += (x - rhs.x); - x = rhs.x; - } - if (rhs.y < y) { - h += (y - rhs.y); - y = rhs.y; - } - if (rhs.x + rhs.w > x + w) w = (rhs.x + rhs.w) - x; - if (rhs.y + rhs.h > y + h) h = (rhs.y + rhs.h) - y; + if (x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h) return true; + return false; } }; @@ -126,10 +122,10 @@ struct RenderTransform float scale = 1.0f; //scale factor bool overriding = false; //user transform? - bool update(); + void update(); void override(const Matrix& m); - RenderTransform(); + RenderTransform() {} RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs); }; @@ -149,6 +145,7 @@ struct RenderStroke struct { float begin = 0.0f; float end = 1.0f; + bool individual = false; } trim; ~RenderStroke() @@ -247,7 +244,23 @@ struct RenderShape class RenderMethod { +private: + uint32_t refCnt = 0; //reference count + Key key; + public: + uint32_t ref() + { + ScopedLock lock(key); + return (++refCnt); + } + + uint32_t unref() + { + ScopedLock lock(key); + return (--refCnt); + } + virtual ~RenderMethod() {} virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; virtual RenderData prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; @@ -256,12 +269,13 @@ public: virtual bool renderShape(RenderData data) = 0; virtual bool renderImage(RenderData data) = 0; virtual bool postRender() = 0; - virtual bool dispose(RenderData data) = 0; + virtual void dispose(RenderData data) = 0; virtual RenderRegion region(RenderData data) = 0; virtual RenderRegion viewport() = 0; virtual bool viewport(const RenderRegion& vp) = 0; virtual bool blend(BlendMethod method) = 0; virtual ColorSpace colorSpace() = 0; + virtual const Surface* mainSurface() = 0; virtual bool clear() = 0; virtual bool sync() = 0; @@ -308,7 +322,7 @@ static inline uint8_t CHANNEL_SIZE(ColorSpace cs) } } -static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, CompositeMethod method) +static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod* renderer, CompositeMethod method) { switch(method) { case CompositeMethod::AlphaMask: @@ -321,7 +335,7 @@ static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, Composi //TODO: Optimize Luma/InvLuma colorspace to Grayscale8 case CompositeMethod::LumaMask: case CompositeMethod::InvLumaMask: - return renderer.colorSpace(); + return renderer->colorSpace(); default: TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method); return ColorSpace::Unsupported; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaveModule.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaveModule.h index cff1a81db..abfd5381a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaveModule.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaveModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,6 +37,7 @@ public: virtual ~SaveModule() {} virtual bool save(Paint* paint, const string& path, bool compress) = 0; + virtual bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) = 0; virtual bool close() = 0; }; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaver.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaver.cpp index 4fd9848e3..f2a22ec6c 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaver.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSaver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,10 +25,14 @@ #include "tvgCommon.h" #include "tvgSaveModule.h" +#include "tvgPaint.h" #ifdef THORVG_TVG_SAVER_SUPPORT #include "tvgTvgSaver.h" #endif +#ifdef THORVG_GIF_SAVER_SUPPORT + #include "tvgGifSaver.h" +#endif /************************************************************************/ /* Internal Class Implementation */ @@ -37,9 +41,12 @@ struct Saver::Impl { SaveModule* saveModule = nullptr; + Paint* bg = nullptr; + ~Impl() { delete(saveModule); + delete(bg); } }; @@ -50,6 +57,12 @@ static SaveModule* _find(FileType type) case FileType::Tvg: { #ifdef THORVG_TVG_SAVER_SUPPORT return new TvgSaver; +#endif + break; + } + case FileType::Gif: { +#ifdef THORVG_GIF_SAVER_SUPPORT + return new GifSaver; #endif break; } @@ -65,12 +78,16 @@ static SaveModule* _find(FileType type) format = "TVG"; break; } + case FileType::Gif: { + format = "GIF"; + break; + } default: { format = "???"; break; } } - TVGLOG("SAVER", "%s format is not supported", format); + TVGLOG("RENDERER", "%s format is not supported", format); #endif return nullptr; } @@ -81,6 +98,8 @@ static SaveModule* _find(const string& path) auto ext = path.substr(path.find_last_of(".") + 1); if (!ext.compare("tvg")) { return _find(FileType::Tvg); + } else if (!ext.compare("gif")) { + return _find(FileType::Gif); } return nullptr; } @@ -106,9 +125,9 @@ Result Saver::save(std::unique_ptr paint, const string& path, bool compre auto p = paint.release(); if (!p) return Result::MemoryCorruption; - //Already on saving an other resource. + //Already on saving another resource. if (pImpl->saveModule) { - delete(p); + if (P(p)->refCnt == 0) delete(p); return Result::InsufficientCondition; } @@ -117,12 +136,55 @@ Result Saver::save(std::unique_ptr paint, const string& path, bool compre pImpl->saveModule = saveModule; return Result::Success; } else { - delete(p); + if (P(p)->refCnt == 0) delete(p); delete(saveModule); return Result::Unknown; } } - delete(p); + if (P(p)->refCnt == 0) delete(p); + return Result::NonSupport; +} + + +Result Saver::background(unique_ptr paint) noexcept +{ + delete(pImpl->bg); + pImpl->bg = paint.release(); + + return Result::Success; +} + + +Result Saver::save(unique_ptr animation, const string& path, uint32_t quality, uint32_t fps) noexcept +{ + auto a = animation.release(); + if (!a) return Result::MemoryCorruption; + + //animation holds the picture, it must be 1 at the bottom. + auto remove = PP(a->picture())->refCnt <= 1 ? true : false; + + if (mathZero(a->totalFrame())) { + if (remove) delete(a); + return Result::InsufficientCondition; + } + + //Already on saving another resource. + if (pImpl->saveModule) { + if (remove) delete(a); + return Result::InsufficientCondition; + } + + if (auto saveModule = _find(path)) { + if (saveModule->save(a, pImpl->bg, path, quality, fps)) { + pImpl->saveModule = saveModule; + return Result::Success; + } else { + if (remove) delete(a); + delete(saveModule); + return Result::Unknown; + } + } + if (remove) delete(a); return Result::NonSupport; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.cpp index 122cd5354..cd911f710 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,6 @@ Scene::Scene() : pImpl(new Impl(this)) { Paint::pImpl->id = TVG_CLASS_ID_SCENE; - Paint::pImpl->method(new PaintMethod(pImpl)); } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.h index f626e993e..8347d924d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgScene.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,15 +23,12 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#ifndef _TVG_SCENE_IMPL_H_ -#define _TVG_SCENE_IMPL_H_ +#ifndef _TVG_SCENE_H_ +#define _TVG_SCENE_H_ #include #include "tvgPaint.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct SceneIterator : Iterator { @@ -65,11 +62,10 @@ struct SceneIterator : Iterator struct Scene::Impl { list paints; - RenderMethod* renderer = nullptr; //keep it for explicit clear RenderData rd = nullptr; Scene* scene = nullptr; uint8_t opacity; //for composition - bool needComp; //composite or not + bool needComp = false; //composite or not Impl(Scene* s) : scene(s) { @@ -78,21 +74,12 @@ struct Scene::Impl ~Impl() { for (auto paint : paints) { - if (paint->pImpl->unref() == 0) delete(paint); - } - } - - bool dispose(RenderMethod& renderer) - { - for (auto paint : paints) { - paint->pImpl->dispose(renderer); + if (P(paint)->unref() == 0) delete(paint); } - renderer.dispose(rd); - this->renderer = nullptr; - this->rd = nullptr; - - return true; + if (auto renderer = PP(scene)->renderer) { + renderer->dispose(rd); + } } bool needComposition(uint8_t opacity) @@ -117,24 +104,21 @@ struct Scene::Impl return true; } - RenderData update(RenderMethod &renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) + RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) { if ((needComp = needComposition(opacity))) { /* Overriding opacity value. If this scene is half-translucent, - It must do intermeidate composition with that opacity value. */ + It must do intermediate composition with that opacity value. */ this->opacity = opacity; opacity = 255; } - this->renderer = &renderer; - if (clipper) { - Array rds; - rds.reserve(paints.size()); + Array rds(paints.size()); for (auto paint : paints) { rds.push(paint->pImpl->update(renderer, transform, clips, opacity, flag, true)); } - rd = renderer.prepare(rds, rd, transform, clips, opacity, flag); + rd = renderer->prepare(rds, rd, transform, clips, opacity, flag); return rd; } else { for (auto paint : paints) { @@ -144,25 +128,26 @@ struct Scene::Impl } } - bool render(RenderMethod& renderer) + bool render(RenderMethod* renderer) { Compositor* cmp = nullptr; + auto ret = true; if (needComp) { - cmp = renderer.target(bounds(renderer), renderer.colorSpace()); - renderer.beginComposite(cmp, CompositeMethod::None, opacity); + cmp = renderer->target(bounds(renderer), renderer->colorSpace()); + renderer->beginComposite(cmp, CompositeMethod::None, opacity); } for (auto paint : paints) { - if (!paint->pImpl->render(renderer)) return false; + ret &= paint->pImpl->render(renderer); } - if (cmp) renderer.endComposite(cmp); + if (cmp) renderer->endComposite(cmp); - return true; + return ret; } - RenderRegion bounds(RenderMethod& renderer) const + RenderRegion bounds(RenderMethod* renderer) const { if (paints.empty()) return {0, 0, 0, 0}; @@ -218,9 +203,8 @@ struct Scene::Impl Paint* duplicate() { - auto ret = Scene::gen(); - - auto dup = ret.get()->pImpl; + auto ret = Scene::gen().release(); + auto dup = ret->pImpl; for (auto paint : paints) { auto cdup = paint->duplicate(); @@ -228,19 +212,15 @@ struct Scene::Impl dup->paints.push_back(cdup); } - return ret.release(); + return ret; } void clear(bool free) { - auto dispose = renderer ? true : false; - for (auto paint : paints) { - if (dispose) free &= P(paint)->dispose(*renderer); if (P(paint)->unref() == 0 && free) delete(paint); } paints.clear(); - renderer = nullptr; } Iterator* iterator() @@ -249,7 +229,7 @@ struct Scene::Impl } }; -#endif //_TVG_SCENE_IMPL_H_ +#endif //_TVG_SCENE_H_ #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.cpp index e43c07f2f..fcf77e242 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -constexpr auto PATH_KAPPA = 0.552284f; + /************************************************************************/ /* External Class Implementation */ @@ -38,7 +38,6 @@ constexpr auto PATH_KAPPA = 0.552284f; Shape :: Shape() : pImpl(new Impl(this)) { Paint::pImpl->id = TVG_CLASS_ID_SHAPE; - Paint::pImpl->method(new PaintMethod(pImpl)); } @@ -65,7 +64,7 @@ Result Shape::reset() noexcept pImpl->rs.path.cmds.clear(); pImpl->rs.path.pts.clear(); - pImpl->flag = RenderUpdateFlag::Path; + pImpl->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -73,18 +72,14 @@ Result Shape::reset() noexcept uint32_t Shape::pathCommands(const PathCommand** cmds) const noexcept { - if (!cmds) return 0; - - *cmds = pImpl->rs.path.cmds.data; + if (cmds) *cmds = pImpl->rs.path.cmds.data; return pImpl->rs.path.cmds.count; } uint32_t Shape::pathCoords(const Point** pts) const noexcept { - if (!pts) return 0; - - *pts = pImpl->rs.path.pts.data; + if (pts) *pts = pImpl->rs.path.pts.data; return pImpl->rs.path.pts.count; } @@ -138,11 +133,11 @@ Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept auto ryKappa = ry * PATH_KAPPA; pImpl->grow(6, 13); - pImpl->moveTo(cx, cy - ry); - pImpl->cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy); + pImpl->moveTo(cx + rx, cy); pImpl->cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry); pImpl->cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy); pImpl->cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry); + pImpl->cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy); pImpl->close(); return Result::Success; @@ -153,13 +148,15 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa //just circle if (sweep >= 360.0f || sweep <= -360.0f) return appendCircle(cx, cy, radius, radius); - startAngle = (startAngle * MATH_PI) / 180.0f; - sweep = sweep * MATH_PI / 180.0f; + const float arcPrecision = 1e-5f; + startAngle = mathDeg2Rad(startAngle); + sweep = mathDeg2Rad(sweep); - auto nCurves = ceil(fabsf(sweep / MATH_PI2)); + auto nCurves = static_cast(fabsf(sweep / MATH_PI2)); + if (fabsf(sweep / MATH_PI2) - nCurves > arcPrecision) ++nCurves; auto sweepSign = (sweep < 0 ? -1 : 1); auto fract = fmodf(sweep, MATH_PI2); - fract = (mathZero(fract)) ? MATH_PI2 * sweepSign : fract; + fract = (fabsf(fract) < arcPrecision) ? MATH_PI2 * sweepSign : fract; //Start from here Point start = {radius * cosf(startAngle), radius * sinf(startAngle)}; @@ -172,7 +169,7 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa } for (int i = 0; i < nCurves; ++i) { - auto endAngle = startAngle + ((i != nCurves - 1) ? float(M_PI_2) * sweepSign : fract); + auto endAngle = startAngle + ((i != nCurves - 1) ? MATH_PI2 * sweepSign : fract); Point end = {radius * cosf(endAngle), radius * sinf(endAngle)}; //variables needed to calculate bezier control points @@ -223,12 +220,10 @@ Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry) pImpl->lineTo(x + w, y + h); pImpl->lineTo(x, y + h); pImpl->close(); - //circle - } else if (mathEqual(rx, halfW) && mathEqual(ry, halfH)) { - return appendCircle(x + (w * 0.5f), y + (h * 0.5f), rx, ry); + //rounded rectangle or circle } else { - auto hrx = rx * 0.5f; - auto hry = ry * 0.5f; + auto hrx = rx * PATH_KAPPA; + auto hry = ry * PATH_KAPPA; pImpl->grow(10, 17); pImpl->moveTo(x + rx, y); pImpl->lineTo(x + w - rx, y); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.h index 161932d11..bb5e6f37f 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgShape.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,16 +23,13 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#ifndef _TVG_SHAPE_IMPL_H_ -#define _TVG_SHAPE_IMPL_H_ +#ifndef _TVG_SHAPE_H_ +#define _TVG_SHAPE_H_ #include #include "tvgMath.h" #include "tvgPaint.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct Shape::Impl { @@ -41,30 +38,30 @@ struct Shape::Impl Shape* shape; uint8_t flag = RenderUpdateFlag::None; uint8_t opacity; //for composition - bool needComp; //composite or not + bool needComp = false; //composite or not Impl(Shape* s) : shape(s) { } - bool dispose(RenderMethod& renderer) + ~Impl() { - renderer.dispose(rd); - rd = nullptr; - return true; + if (auto renderer = PP(shape)->renderer) { + renderer->dispose(rd); + } } - bool render(RenderMethod& renderer) + bool render(RenderMethod* renderer) { Compositor* cmp = nullptr; bool ret; if (needComp) { - cmp = renderer.target(bounds(renderer), renderer.colorSpace()); - renderer.beginComposite(cmp, CompositeMethod::None, opacity); + cmp = renderer->target(bounds(renderer), renderer->colorSpace()); + renderer->beginComposite(cmp, CompositeMethod::None, opacity); } - ret = renderer.renderShape(rd); - if (cmp) renderer.endComposite(cmp); + ret = renderer->renderShape(rd); + if (cmp) renderer->endComposite(cmp); return ret; } @@ -73,7 +70,7 @@ struct Shape::Impl if (opacity == 0) return false; //Shape composition is only necessary when stroking & fill are valid. - if (!rs.stroke || rs.stroke->width < FLT_EPSILON || (!rs.stroke->fill && rs.stroke->color[3] == 0)) return false; + if (!rs.stroke || rs.stroke->width < FLOAT_EPSILON || (!rs.stroke->fill && rs.stroke->color[3] == 0)) return false; if (!rs.fill && rs.color[3] == 0) return false; //translucent fill & stroke @@ -82,36 +79,49 @@ struct Shape::Impl //Composition test const Paint* target; auto method = shape->composite(&target); - if (!target || method == tvg::CompositeMethod::ClipPath) return false; - if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false; + if (!target || method == CompositeMethod::ClipPath) return false; + if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) { + if (target->identifier() == TVG_CLASS_ID_SHAPE) { + auto shape = static_cast(target); + if (!shape->fill()) { + uint8_t r, g, b, a; + shape->fillColor(&r, &g, &b, &a); + if (a == 0 || a == 255) { + if (method == CompositeMethod::LumaMask || method == CompositeMethod::InvLumaMask) { + if ((r == 255 && g == 255 && b == 255) || (r == 0 && g == 0 && b == 0)) return false; + } else return false; + } + } + } + } return true; } - RenderData update(RenderMethod& renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) - { + RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + { if ((needComp = needComposition(opacity))) { /* Overriding opacity value. If this scene is half-translucent, - It must do intermeidate composition with that opacity value. */ + It must do intermediate composition with that opacity value. */ this->opacity = opacity; opacity = 255; } - rd = renderer.prepare(rs, rd, transform, clips, opacity, static_cast(pFlag | flag), clipper); + rd = renderer->prepare(rs, rd, transform, clips, opacity, static_cast(pFlag | flag), clipper); flag = RenderUpdateFlag::None; return rd; } - RenderRegion bounds(RenderMethod& renderer) + RenderRegion bounds(RenderMethod* renderer) { - return renderer.region(rd); + return renderer->region(rd); } bool bounds(float* x, float* y, float* w, float* h, bool stroking) { //Path bounding size if (rs.path.pts.count > 0 ) { - auto pts = rs.path.pts.data; + auto pts = rs.path.pts.begin(); Point min = { pts->x, pts->y }; Point max = { pts->x, pts->y }; @@ -209,7 +219,7 @@ struct Shape::Impl return true; } - bool strokeTrim(float begin, float end) + bool strokeTrim(float begin, float end, bool individual) { if (!rs.stroke) { if (begin == 0.0f && end == 1.0f) return true; @@ -220,6 +230,7 @@ struct Shape::Impl rs.stroke->trim.begin = begin; rs.stroke->trim.end = end; + rs.stroke->trim.individual = individual; flag |= RenderUpdateFlag::Stroke; return true; @@ -293,7 +304,7 @@ struct Shape::Impl } for (uint32_t i = 0; i < cnt; i++) { - if (pattern[i] < FLT_EPSILON) return Result::InvalidArguments; + if (pattern[i] < FLOAT_EPSILON) return Result::InvalidArguments; } //Reset dash @@ -343,9 +354,9 @@ struct Shape::Impl Paint* duplicate() { - auto ret = Shape::gen(); + auto ret = Shape::gen().release(); + auto dup = ret->pImpl; - auto dup = ret.get()->pImpl; dup->rs.rule = rs.rule; //Color @@ -381,7 +392,7 @@ struct Shape::Impl dup->flag |= RenderUpdateFlag::Gradient; } - return ret.release(); + return ret; } Iterator* iterator() @@ -390,7 +401,7 @@ struct Shape::Impl } }; -#endif //_TVG_SHAPE_IMPL_H_ +#endif //_TVG_SHAPE_H_ #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.cpp index 25630c7e9..1838e7560 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,7 @@ #if LV_USE_THORVG_INTERNAL #include "config.h" +#include #include #include #include "tvgMath.h" @@ -185,7 +186,7 @@ float strToFloat(const char *nPtr, char **endPtr) auto scale = 1.0f; while (exponentPart >= 8U) { - scale *= (float)1E8; + scale *= 1E8f; exponentPart -= 8U; } while (exponentPart > 0U) { @@ -200,6 +201,8 @@ float strToFloat(const char *nPtr, char **endPtr) success: if (endPtr) *endPtr = (char *)(a); + if (!std::isfinite(val)) return 0.0f; + return minus * val; error: diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.h index eb664e2f5..154a1995a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgStr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.cpp index 89e45d401..11274e332 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2022 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -52,6 +52,22 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from) to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Color); } } + if (((from->flags & SvgStyleFlags::PaintOrder) && !(to->flags & SvgStyleFlags::PaintOrder)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::PaintOrder)) { + to->paintOrder = from->paintOrder; + to->flags = (to->flags | SvgStyleFlags::PaintOrder); + if (from->flagsImportance & SvgStyleFlags::PaintOrder) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::PaintOrder); + } + } + if (((from->flags & SvgStyleFlags::Display) && !(to->flags & SvgStyleFlags::Display)) || + _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Display)) { + to->display = from->display; + to->flags = (to->flags | SvgStyleFlags::Display); + if (from->flagsImportance & SvgStyleFlags::Display) { + to->flagsImportance = (to->flagsImportance | SvgStyleFlags::Display); + } + } //Fill if (((from->fill.flags & SvgFillFlags::Paint) && !(to->flags & SvgStyleFlags::Fill)) || _isImportanceApplicable(to->flagsImportance, from->flagsImportance, SvgStyleFlags::Fill)) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.h index d718ede64..24812b3e1 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgCssStyle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2022 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.cpp index efca81245..34ca2c5b4 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -92,6 +92,7 @@ static char* _skipSpace(const char* str, const char* end) static char* _copyId(const char* str) { if (!str) return nullptr; + if (strlen(str) == 0) return nullptr; return strdup(str); } @@ -105,15 +106,19 @@ static const char* _skipComma(const char* content) } -static bool _parseNumber(const char** content, float* number) +static bool _parseNumber(const char** content, const char** end, float* number) { - char* end = nullptr; + const char* _end = end ? *end : nullptr; - *number = strToFloat(*content, &end); + *number = strToFloat(*content, (char**)&_end); //If the start of string is not number - if ((*content) == end) return false; + if ((*content) == _end) { + if (end) *end = _end; + return false; + } //Skip comma if any - *content = _skipComma(end); + *content = _skipComma(_end); + if (end) *end = _end; return true; } @@ -380,19 +385,25 @@ static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* das static char* _idFromUrl(const char* url) { - url = _skipSpace(url, nullptr); - if ((*url) == '(') { - ++url; - url = _skipSpace(url, nullptr); + auto open = strchr(url, '('); + auto close = strchr(url, ')'); + if (!open || !close || open >= close) return nullptr; + + open = strchr(url, '#'); + if (!open || open >= close) return nullptr; + + ++open; + --close; + + //trim the rest of the spaces if any + while (open < close && *close == ' ') --close; + + //quick verification + for (auto id = open; id < close; id++) { + if (*id == ' ' || *id == '\'') return nullptr; } - if ((*url) == '\'') ++url; - if ((*url) == '#') ++url; - - int i = 0; - while (url[i] > ' ' && url[i] != ')' && url[i] != '\'') ++i; - - return strDuplicate(url, i); + return strDuplicate(open, (close - open + 1)); } @@ -572,14 +583,89 @@ static constexpr struct }; -static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** ref) +static bool _hslToRgb(float hue, float saturation, float brightness, uint8_t* red, uint8_t* green, uint8_t* blue) +{ + if (!red || !green || !blue) return false; + + float sv, vsf, f, p, q, t, v; + float _red = 0, _green = 0, _blue = 0; + uint32_t i = 0; + + if (mathZero(saturation)) _red = _green = _blue = brightness; + else { + if (mathEqual(hue, 360.0)) hue = 0.0f; + hue /= 60.0f; + + v = (brightness <= 0.5f) ? (brightness * (1.0f + saturation)) : (brightness + saturation - (brightness * saturation)); + p = brightness + brightness - v; + + if (!mathZero(v)) sv = (v - p) / v; + else sv = 0; + + i = static_cast(hue); + f = hue - i; + + vsf = v * sv * f; + + t = p + vsf; + q = v - vsf; + + switch (i) { + case 0: { + _red = v; + _green = t; + _blue = p; + break; + } + case 1: { + _red = q; + _green = v; + _blue = p; + break; + } + case 2: { + _red = p; + _green = v; + _blue = t; + break; + } + case 3: { + _red = p; + _green = q; + _blue = v; + break; + } + case 4: { + _red = t; + _green = p; + _blue = v; + break; + } + case 5: { + _red = v; + _green = p; + _blue = q; + break; + } + } + } + + *red = static_cast(roundf(_red * 255.0f)); + *green = static_cast(roundf(_green * 255.0f)); + *blue = static_cast(roundf(_blue * 255.0f)); + + return true; +} + + +static bool _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** ref) { unsigned int len = strlen(str); char *red, *green, *blue; unsigned char tr, tg, tb; if (len == 4 && str[0] == '#') { - //Case for "#456" should be interprete as "#445566" + //Case for "#456" should be interpreted as "#445566" if (isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3])) { char tmp[3] = { '\0', '\0', '\0' }; tmp[0] = str[1]; @@ -592,6 +678,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** tmp[1] = str[3]; *b = strtol(tmp, nullptr, 16); } + return true; } else if (len == 7 && str[0] == '#') { if (isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3]) && isxdigit(str[4]) && isxdigit(str[5]) && isxdigit(str[6])) { char tmp[3] = { '\0', '\0', '\0' }; @@ -605,6 +692,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** tmp[1] = str[6]; *b = strtol(tmp, nullptr, 16); } + return true; } else if (len >= 10 && (str[0] == 'r' || str[0] == 'R') && (str[1] == 'g' || str[1] == 'G') && (str[2] == 'b' || str[2] == 'B') && str[3] == '(' && str[len - 1] == ')') { tr = _parseColor(str + 4, &red); if (red && *red == ',') { @@ -618,9 +706,35 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** } } } + return true; } else if (ref && len >= 3 && !strncmp(str, "url", 3)) { if (*ref) free(*ref); *ref = _idFromUrl((const char*)(str + 3)); + return true; + } else if (len >= 10 && (str[0] == 'h' || str[0] == 'H') && (str[1] == 's' || str[1] == 'S') && (str[2] == 'l' || str[2] == 'L') && str[3] == '(' && str[len - 1] == ')') { + float th, ts, tb; + const char *content, *hue, *saturation, *brightness; + content = str + 4; + content = _skipSpace(content, nullptr); + if (_parseNumber(&content, &hue, &th) && hue) { + th = float(uint32_t(th) % 360); + hue = _skipSpace(hue, nullptr); + hue = (char*)_skipComma(hue); + hue = _skipSpace(hue, nullptr); + if (_parseNumber(&hue, &saturation, &ts) && saturation && *saturation == '%') { + ts /= 100.0f; + saturation = _skipSpace(saturation + 1, nullptr); + saturation = (char*)_skipComma(saturation); + saturation = _skipSpace(saturation, nullptr); + if (_parseNumber(&saturation, &brightness, &tb) && brightness && *brightness == '%') { + tb /= 100.0f; + brightness = _skipSpace(brightness + 1, nullptr); + if (brightness && brightness[0] == ')' && brightness[1] == '\0') { + return _hslToRgb(th, ts, tb, r, g, b); + } + } + } + } } else { //Handle named color for (unsigned int i = 0; i < (sizeof(colors) / sizeof(colors[0])); i++) { @@ -628,10 +742,11 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** *r = (((uint8_t*)(&(colors[i].value)))[2]); *g = (((uint8_t*)(&(colors[i].value)))[1]); *b = (((uint8_t*)(&(colors[i].value)))[0]); - return; + return true; } } } + return false; } @@ -686,32 +801,6 @@ static constexpr struct }; -static void _matrixCompose(const Matrix* m1, const Matrix* m2, Matrix* dst) -{ - auto a11 = (m1->e11 * m2->e11) + (m1->e12 * m2->e21) + (m1->e13 * m2->e31); - auto a12 = (m1->e11 * m2->e12) + (m1->e12 * m2->e22) + (m1->e13 * m2->e32); - auto a13 = (m1->e11 * m2->e13) + (m1->e12 * m2->e23) + (m1->e13 * m2->e33); - - auto a21 = (m1->e21 * m2->e11) + (m1->e22 * m2->e21) + (m1->e23 * m2->e31); - auto a22 = (m1->e21 * m2->e12) + (m1->e22 * m2->e22) + (m1->e23 * m2->e32); - auto a23 = (m1->e21 * m2->e13) + (m1->e22 * m2->e23) + (m1->e23 * m2->e33); - - auto a31 = (m1->e31 * m2->e11) + (m1->e32 * m2->e21) + (m1->e33 * m2->e31); - auto a32 = (m1->e31 * m2->e12) + (m1->e32 * m2->e22) + (m1->e33 * m2->e32); - auto a33 = (m1->e31 * m2->e13) + (m1->e32 * m2->e23) + (m1->e33 * m2->e33); - - dst->e11 = a11; - dst->e12 = a12; - dst->e13 = a13; - dst->e21 = a21; - dst->e22 = a22; - dst->e23 = a23; - dst->e31 = a31; - dst->e32 = a32; - dst->e33 = a33; -} - - /* parse transform attribute * https://www.w3.org/TR/SVG/coords.html#TransformAttribute */ @@ -754,31 +843,31 @@ static Matrix* _parseTransformationMatrix(const char* value) if (state == MatrixState::Matrix) { if (ptCount != 6) goto error; Matrix tmp = {points[0], points[2], points[4], points[1], points[3], points[5], 0, 0, 1}; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); } else if (state == MatrixState::Translate) { if (ptCount == 1) { Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1}; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); } else if (ptCount == 2) { Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1}; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); } else goto error; } else if (state == MatrixState::Rotate) { //Transform to signed. - points[0] = fmod(points[0], (float)360); - if (points[0] < 0) points[0] += 360; - auto c = cosf(points[0] * (float)(M_PI / 180.0)); - auto s = sinf(points[0] * (float)(M_PI / 180.0)); + points[0] = fmodf(points[0], 360.0f); + if (points[0] < 0) points[0] += 360.0f; + auto c = cosf(mathDeg2Rad(points[0])); + auto s = sinf(mathDeg2Rad(points[0])); if (ptCount == 1) { Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); } else if (ptCount == 3) { Matrix tmp = { 1, 0, points[1], 0, 1, points[2], 0, 0, 1 }; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 }; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); } else { goto error; } @@ -786,9 +875,19 @@ static Matrix* _parseTransformationMatrix(const char* value) if (ptCount < 1 || ptCount > 2) goto error; auto sx = points[0]; auto sy = sx; - if (ptCount == 2) sy = (float)points[1]; + if (ptCount == 2) sy = points[1]; Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 }; - _matrixCompose(matrix, &tmp, matrix); + *matrix = mathMultiply(matrix, &tmp); + } else if (state == MatrixState::SkewX) { + if (ptCount != 1) goto error; + auto deg = tanf(mathDeg2Rad(points[0])); + Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); + } else if (state == MatrixState::SkewY) { + if (ptCount != 1) goto error; + auto deg = tanf(mathDeg2Rad(points[0])); + Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 }; + *matrix = mathMultiply(matrix, &tmp); } } return matrix; @@ -866,10 +965,10 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value) doc->viewFlag = (doc->viewFlag | SvgViewFlag::Height); } } else if (!strcmp(key, "viewBox")) { - if (_parseNumber(&value, &doc->vx)) { - if (_parseNumber(&value, &doc->vy)) { - if (_parseNumber(&value, &doc->vw)) { - if (_parseNumber(&value, &doc->vh)) { + if (_parseNumber(&value, nullptr, &doc->vx)) { + if (_parseNumber(&value, nullptr, &doc->vy)) { + if (_parseNumber(&value, nullptr, &doc->vw)) { + if (_parseNumber(&value, nullptr, &doc->vh)) { doc->viewFlag = (doc->viewFlag | SvgViewFlag::Viewbox); loader->svgParse->global.h = doc->vh; } @@ -892,7 +991,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "style")) { return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); #ifdef THORVG_LOG_ENABLED - } else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(strToFloat(value, nullptr)) > FLT_EPSILON) { + } else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(strToFloat(value, nullptr)) > FLOAT_EPSILON) { TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value); #endif } else { @@ -910,20 +1009,21 @@ static void _handlePaintAttr(SvgPaint* paint, const char* value) paint->none = true; return; } - paint->none = false; if (!strcmp(value, "currentColor")) { paint->curColor = true; + paint->none = false; return; } - _toColor(value, &paint->color.r, &paint->color.g, &paint->color.b, &paint->url); + if (_toColor(value, &paint->color.r, &paint->color.g, &paint->color.b, &paint->url)) paint->none = false; } static void _handleColorAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) { SvgStyleProperty* style = node->style; - style->curColorSet = true; - _toColor(value, &style->color.r, &style->color.g, &style->color.b, nullptr); + if (_toColor(value, &style->color.r, &style->color.g, &style->color.b, nullptr)) { + style->curColorSet = true; + } } @@ -1007,6 +1107,7 @@ static void _handleFillRuleAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, static void _handleOpacityAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) { + node->style->flags = (node->style->flags | SvgStyleFlags::Opacity); node->style->opacity = _toOpacity(value); } @@ -1058,8 +1159,9 @@ static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, // The default is "inline" which means visible and "none" means invisible. // Depending on the type of node, additional functionality may be required. // refer to https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/display - if (!strcmp(value, "none")) node->display = false; - else node->display = true; + node->style->flags = (node->style->flags | SvgStyleFlags::Display); + if (!strcmp(value, "none")) node->style->display = false; + else node->style->display = true; } @@ -1279,8 +1381,8 @@ static bool _attrParseSymbolNode(void* data, const char* key, const char* value) SvgSymbolNode* symbol = &(node->node.symbol); if (!strcmp(key, "viewBox")) { - if (!_parseNumber(&value, &symbol->vx) || !_parseNumber(&value, &symbol->vy)) return false; - if (!_parseNumber(&value, &symbol->vw) || !_parseNumber(&value, &symbol->vh)) return false; + if (!_parseNumber(&value, nullptr, &symbol->vx) || !_parseNumber(&value, nullptr, &symbol->vy)) return false; + if (!_parseNumber(&value, nullptr, &symbol->vw) || !_parseNumber(&value, nullptr, &symbol->vh)) return false; symbol->hasViewBox = true; } else if (!strcmp(key, "width")) { symbol->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); @@ -1344,7 +1446,7 @@ static SvgNode* _createNode(SvgNode* parent, SvgNodeType type) node->style->paintOrder = _toPaintOrder("fill stroke"); //Default display is true("inline"). - node->display = true; + node->style->display = true; node->parent = parent; node->type = type; @@ -1420,7 +1522,7 @@ static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, cons loader->svgParse->node = _createNode(parent, SvgNodeType::ClipPath); if (!loader->svgParse->node) return nullptr; - loader->svgParse->node->display = false; + loader->svgParse->node->style->display = false; loader->svgParse->node->node.clip.userSpace = true; func(buf, bufLength, _attrParseClipPathNode, loader); @@ -1445,7 +1547,6 @@ static SvgNode* _createSymbolNode(SvgLoaderData* loader, SvgNode* parent, const loader->svgParse->node = _createNode(parent, SvgNodeType::Symbol); if (!loader->svgParse->node) return nullptr; - loader->svgParse->node->display = false; loader->svgParse->node->node.symbol.align = AspectRatioAlign::XMidYMid; loader->svgParse->node->node.symbol.meetOrSlice = AspectRatioMeetOrSlice::Meet; loader->svgParse->node->node.symbol.overflowVisible = false; @@ -1627,8 +1728,11 @@ static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const static bool _attrParsePolygonPoints(const char* str, SvgPolygonNode* polygon) { - float num; - while (_parseNumber(&str, &num)) polygon->pts.push(num); + float num_x, num_y; + while (_parseNumber(&str, nullptr, &num_x) && _parseNumber(&str, nullptr, &num_y)) { + polygon->pts.push(num_x); + polygon->pts.push(num_y); + } return true; } @@ -1723,8 +1827,8 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value) if (!strncmp(rectTags[i].tag, "rx", sz)) rect->hasRx = true; if (!strncmp(rectTags[i].tag, "ry", sz)) rect->hasRy = true; - if ((rect->rx >= FLT_EPSILON) && (rect->ry < FLT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; - if ((rect->ry >= FLT_EPSILON) && (rect->rx < FLT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; + if ((rect->rx >= FLOAT_EPSILON) && (rect->ry < FLOAT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; + if ((rect->ry >= FLOAT_EPSILON) && (rect->rx < FLOAT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; return ret; } } @@ -1931,6 +2035,19 @@ static SvgNode* _findNodeById(SvgNode *node, const char* id) } +static SvgNode* _findParentById(SvgNode* node, char* id, SvgNode* doc) +{ + SvgNode *parent = node->parent; + while (parent != nullptr && parent != doc) { + if (parent->id && !strcmp(parent->id, id)) { + return parent; + } + parent = parent->parent; + } + return nullptr; +} + + static constexpr struct { const char* tag; @@ -1971,8 +2088,12 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) defs = _getDefsNode(node); nodeFrom = _findNodeById(defs, id); if (nodeFrom) { - _cloneNode(nodeFrom, node, 0); - if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom; + if (!_findParentById(node, id, loader->doc)) { + _cloneNode(nodeFrom, node, 0); + if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom; + } else { + TVGLOG("SVG", "%s is ancestor element. This reference is invalid.", id); + } free(id); } else { //some svg export software include element at the end of the file @@ -2373,8 +2494,9 @@ static bool _attrParseStopsStyle(void* data, const char* key, const char* value) stop->a = _toOpacity(value); loader->svgParse->flags = (loader->svgParse->flags | SvgStopStyleFlags::StopOpacity); } else if (!strcmp(key, "stop-color")) { - _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); - loader->svgParse->flags = (loader->svgParse->flags | SvgStopStyleFlags::StopColor); + if (_toColor(value, &stop->r, &stop->g, &stop->b, nullptr)) { + loader->svgParse->flags = (loader->svgParse->flags | SvgStopStyleFlags::StopColor); + } } else { return false; } @@ -2681,7 +2803,7 @@ static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgSty if (to->transform) memcpy(to->transform, from->transform, sizeof(Matrix)); } - if (to->type == SvgGradientType::Linear && from->type == SvgGradientType::Linear) { + if (to->type == SvgGradientType::Linear) { for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) { bool coordSet = to->flags & linear_tags[i].flag; if (!(to->flags & linear_tags[i].flag) && (from->flags & linear_tags[i].flag)) { @@ -2698,7 +2820,7 @@ static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgSty linear_tags[i].tagInheritedRecalc(loader, to->linear, to->userSpace); } } - } else if (to->type == SvgGradientType::Radial && from->type == SvgGradientType::Radial) { + } else if (to->type == SvgGradientType::Radial) { for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) { bool coordSet = (to->flags & radialTags[i].flag); if (!(to->flags & radialTags[i].flag) && (from->flags & radialTags[i].flag)) { @@ -2708,10 +2830,16 @@ static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgSty //GradUnits not set directly, coord set if (!gradUnitSet && coordSet) { radialTags[i].tagRecalc(loader, to->radial, to->userSpace); + //If fx and fy are not set, set cx and cy. + if (!strcmp(radialTags[i].tag, "cx") && !(to->flags & SvgGradientFlags::Fx)) to->radial->fx = to->radial->cx; + if (!strcmp(radialTags[i].tag, "cy") && !(to->flags & SvgGradientFlags::Fy)) to->radial->fy = to->radial->cy; } //GradUnits set, coord not set directly if (to->userSpace == from->userSpace) continue; if (gradUnitSet && !coordSet) { + //If fx and fx are not set, do not call recalc. + if (!strcmp(radialTags[i].tag, "fx") && !(to->flags & SvgGradientFlags::Fx)) continue; + if (!strcmp(radialTags[i].tag, "fy") && !(to->flags & SvgGradientFlags::Fy)) continue; radialTags[i].tagInheritedRecalc(loader, to->radial, to->userSpace); } } @@ -2838,9 +2966,15 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from) to->color = from->color; to->curColorSet = true; } + if (from->flags & SvgStyleFlags::Opacity) { + to->opacity = from->opacity; + } if (from->flags & SvgStyleFlags::PaintOrder) { to->paintOrder = from->paintOrder; } + if (from->flags & SvgStyleFlags::Display) { + to->display = from->display; + } //Fill to->fill.flags = (to->fill.flags | from->fill.flags); if (from->fill.flags & SvgFillFlags::Paint) { @@ -3030,9 +3164,13 @@ static void _clonePostponedNodes(Array* cloneNodes, SvgNode* doc) auto defs = _getDefsNode(nodeIdPair.node); auto nodeFrom = _findNodeById(defs, nodeIdPair.id); if (!nodeFrom) nodeFrom = _findNodeById(doc, nodeIdPair.id); - _cloneNode(nodeFrom, nodeIdPair.node, 0); - if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) { - nodeIdPair.node->node.use.symbol = nodeFrom; + if (!_findParentById(nodeIdPair.node, nodeIdPair.id, doc)) { + _cloneNode(nodeFrom, nodeIdPair.node, 0); + if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) { + nodeIdPair.node->node.use.symbol = nodeFrom; + } + } else { + TVGLOG("SVG", "%s is ancestor element. This reference is invalid.", nodeIdPair.id); } free(nodeIdPair.id); } @@ -3065,6 +3203,14 @@ static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content) } } + for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) { + if (!strncmp(content, graphicsTags[i].tag, graphicsTags[i].sz - 1)) { + loader->currentGraphicsNode = nullptr; + loader->stack.pop(); + break; + } + } + loader->level--; } @@ -3111,7 +3257,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, else parent = loader->doc; if (!strcmp(tagName, "style")) { // TODO: For now only the first style node is saved. After the css id selector - // is introduced this if condition shouldin't be necessary any more + // is introduced this if condition shouldn't be necessary any more if (!loader->cssStyle) { node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes); loader->cssStyle = node; @@ -3131,6 +3277,11 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, if (loader->stack.count > 0) parent = loader->stack.last(); else parent = loader->doc; node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes); + if (node && !empty) { + auto defs = _createDefsNode(loader, nullptr, nullptr, 0, nullptr); + loader->stack.push(defs); + loader->currentGraphicsNode = node; + } } else if ((gradientMethod = _findGradientFactory(tagName))) { SvgStyleGradient* gradient; gradient = gradientMethod(loader, attrs, attrsLength); @@ -3242,7 +3393,7 @@ static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node) #ifdef THORVG_LOG_ENABLED auto type = simpleXmlNodeTypeToString(node->type); - if (!node->display && node->type != SvgNodeType::ClipPath && node->type != SvgNodeType::Symbol) TVGLOG("SVG", "Inefficient elements used [Display is none][Node Type : %s]", type); + if (!node->style->display && node->type != SvgNodeType::ClipPath) TVGLOG("SVG", "Inefficient elements used [Display is none][Node Type : %s]", type); if (node->style->opacity == 0) TVGLOG("SVG", "Inefficient elements used [Opacity is zero][Node Type : %s]", type); if (node->style->fill.opacity == 0 && node->style->stroke.opacity == 0) TVGLOG("SVG", "Inefficient elements used [Fill opacity and stroke opacity are zero][Node Type : %s]", type); @@ -3513,7 +3664,7 @@ void SvgLoader::clear(bool all) free(loaderData.svgParse); loaderData.svgParse = nullptr; - for (auto gradient = loaderData.gradients.data; gradient < loaderData.gradients.end(); ++gradient) { + for (auto gradient = loaderData.gradients.begin(); gradient < loaderData.gradients.end(); ++gradient) { (*gradient)->clear(); free(*gradient); } @@ -3525,12 +3676,16 @@ void SvgLoader::clear(bool all) if (!all) return; - for (auto p = loaderData.images.data; p < loaderData.images.end(); ++p) { + for (auto p = loaderData.images.begin(); p < loaderData.images.end(); ++p) { free(*p); } loaderData.images.reset(); if (copy) free((char*)content); + + delete(root); + root = nullptr; + size = 0; content = nullptr; copy = false; @@ -3541,23 +3696,24 @@ void SvgLoader::clear(bool all) /* External Class Implementation */ /************************************************************************/ -SvgLoader::SvgLoader() +SvgLoader::SvgLoader() : ImageLoader(FileType::Svg) { } SvgLoader::~SvgLoader() { - close(); + this->done(); + clear(); } void SvgLoader::run(unsigned tid) { //According to the SVG standard the value of the width/height of the viewbox set to 0 disables rendering - if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLT_EPSILON || fabsf(vh) <= FLT_EPSILON)) { + if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLOAT_EPSILON || fabsf(vh) <= FLOAT_EPSILON)) { TVGLOG("SVG", "The width and/or height set to 0 - rendering disabled."); - root = Scene::gen(); + root = Scene::gen().release(); return; } @@ -3679,10 +3835,11 @@ bool SvgLoader::open(const char* data, uint32_t size, bool copy) clear(); if (copy) { - content = (char*)malloc(size); + content = (char*)malloc(size + 1); if (!content) return false; memcpy((char*)content, data, size); - } else content = data; + content[size] = '\0'; + } else content = (char*)data; this->size = size; this->copy = copy; @@ -3706,7 +3863,7 @@ bool SvgLoader::open(const string& path) if (filePath.empty()) return false; - content = filePath.c_str(); + content = (char*)filePath.c_str(); size = filePath.size(); return header(); @@ -3731,7 +3888,7 @@ bool SvgLoader::read() if (!content || size == 0) return false; //the loading has been already completed in header() - if (root) return true; + if (root || !LoadModule::read()) return true; TaskScheduler::request(this); @@ -3741,18 +3898,19 @@ bool SvgLoader::read() bool SvgLoader::close() { + if (!LoadModule::close()) return false; this->done(); - clear(); - return true; } -unique_ptr SvgLoader::paint() +Paint* SvgLoader::paint() { this->done(); - return std::move(root); + auto ret = root; + root = nullptr; + return ret; } #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.h index 38ead0ebc..d5cd7bb5e 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,30 +29,29 @@ #include "tvgTaskScheduler.h" #include "tvgSvgLoaderCommon.h" -class SvgLoader : public LoadModule, public Task +class SvgLoader : public ImageLoader, public Task { public: string filePath; string svgPath = ""; - const char* content = nullptr; + char* content = nullptr; uint32_t size = 0; SvgLoaderData loaderData; - unique_ptr root; + Scene* root = nullptr; bool copy = false; SvgLoader(); ~SvgLoader(); - using LoadModule::open; bool open(const string& path) override; bool open(const char* data, uint32_t size, bool copy) override; bool resize(Paint* paint, float w, float h) override; bool read() override; bool close() override; - unique_ptr paint() override; + Paint* paint() override; private: SvgViewFlag viewFlag = SvgViewFlag::None; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoaderCommon.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoaderCommon.h index 6df7237d7..b0373908b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoaderCommon.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgLoaderCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -488,11 +488,12 @@ struct SvgStyleProperty SvgComposite mask; int opacity; SvgColor color; - bool curColorSet; char* cssClass; - bool paintOrder; //true if default (fill, stroke), false otherwise SvgStyleFlags flags; SvgStyleFlags flagsImportance; //indicates the importance of the flag - if set, higher priority is applied (https://drafts.csswg.org/css-cascade-4/#importance) + bool curColorSet; + bool paintOrder; //true if default (fill, stroke), false otherwise + bool display; }; struct SvgNode @@ -521,7 +522,6 @@ struct SvgNode SvgCssStyleNode cssStyle; SvgSymbolNode symbol; } node; - bool display; ~SvgNode(); }; @@ -563,6 +563,7 @@ struct SvgLoaderData int level = 0; bool result = false; bool style = false; + SvgNode* currentGraphicsNode = nullptr; }; struct Box diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.cpp index 46ec157f3..42312c37b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -54,8 +54,9 @@ #define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++. #include -#include #include +#include "tvgMath.h" +#include "tvgShape.h" #include "tvgSvgLoaderCommon.h" #include "tvgSvgPath.h" #include "tvgStr.h" @@ -124,14 +125,11 @@ void _pathAppendArcTo(Array* cmds, Array* pts, Point* cur, P sx = cur->x; sy = cur->y; - //If start and end points are identical, then no arc is drawn - if ((fabsf(x - sx) < (1.0f / 256.0f)) && (fabsf(y - sy) < (1.0f / 256.0f))) return; - //Correction of out-of-range radii, see F6.6.1 (step 2) rx = fabsf(rx); ry = fabsf(ry); - angle = angle * (float)M_PI / 180.0f; + angle = mathDeg2Rad(angle); cosPhi = cosf(angle); sinPhi = sinf(angle); dx2 = (sx - x) / 2.0f; @@ -195,29 +193,29 @@ void _pathAppendArcTo(Array* cmds, Array* pts, Point* cur, P cx += (sx + x) / 2.0f; cy += (sy + y) / 2.0f; - //Sstep 4 (F6.5.4) + //Step 4 (F6.5.4) //We dont' use arccos (as per w3c doc), see //http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm //Note: atan2 (0.0, 1.0) == 0.0 at = atan2(((y1p - cyp) / ry), ((x1p - cxp) / rx)); - theta1 = (at < 0.0f) ? 2.0f * (float)M_PI + at : at; + theta1 = (at < 0.0f) ? 2.0f * MATH_PI + at : at; nat = atan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx)); - deltaTheta = (nat < at) ? 2.0f * (float)M_PI - at + nat : nat - at; + deltaTheta = (nat < at) ? 2.0f * MATH_PI - at + nat : nat - at; if (sweep) { //Ensure delta theta < 0 or else add 360 degrees - if (deltaTheta < 0.0f) deltaTheta += (float)(2.0f * (float)M_PI); + if (deltaTheta < 0.0f) deltaTheta += 2.0f * MATH_PI; } else { //Ensure delta theta > 0 or else substract 360 degrees - if (deltaTheta > 0.0f) deltaTheta -= (float)(2.0f * (float)M_PI); + if (deltaTheta > 0.0f) deltaTheta -= 2.0f * MATH_PI; } //Add several cubic bezier to approximate the arc //(smaller than 90 degrees) //We add one extra segment because we want something //Smaller than 90deg (i.e. not 90 itself) - segments = static_cast(fabsf(deltaTheta / float(M_PI_2)) + 1.0f); + segments = static_cast(fabsf(deltaTheta / MATH_PI2) + 1.0f); delta = deltaTheta / segments; //http://www.stillhq.com/ctpfaq/2001/comp.text.pdf-faq-2001-04.txt (section 2.13) @@ -316,7 +314,7 @@ static int _numberCount(char cmd) } -static bool _processCommand(Array* cmds, Array* pts, char cmd, float* arr, int count, Point* cur, Point* curCtl, Point* startPoint, bool *isQuadratic) +static bool _processCommand(Array* cmds, Array* pts, char cmd, float* arr, int count, Point* cur, Point* curCtl, Point* startPoint, bool *isQuadratic, bool* closed) { switch (cmd) { case 'm': @@ -469,13 +467,21 @@ static bool _processCommand(Array* cmds, Array* pts, char cm case 'Z': { cmds->push(PathCommand::Close); *cur = *startPoint; + *closed = true; break; } case 'a': case 'A': { - _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], arr[0], arr[1], arr[2], arr[3], arr[4]); - *cur = *curCtl = {arr[5], arr[6]}; - *isQuadratic = false; + if (mathZero(arr[0]) || mathZero(arr[1])) { + Point p = {arr[5], arr[6]}; + cmds->push(PathCommand::LineTo); + pts->push(p); + *cur = {arr[5], arr[6]}; + } else if (!mathEqual(cur->x, arr[5]) || !mathEqual(cur->y, arr[6])) { + _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], fabsf(arr[0]), fabsf(arr[1]), arr[2], arr[3], arr[4]); + *cur = *curCtl = {arr[5], arr[6]}; + *isQuadratic = false; + } break; } default: { @@ -486,7 +492,7 @@ static bool _processCommand(Array* cmds, Array* pts, char cm } -static char* _nextCommand(char* path, char* cmd, float* arr, int* count) +static char* _nextCommand(char* path, char* cmd, float* arr, int* count, bool* closed) { int large, sweep; @@ -498,6 +504,9 @@ static char* _nextCommand(char* path, char* cmd, float* arr, int* count) } else { if (*cmd == 'm') *cmd = 'l'; else if (*cmd == 'M') *cmd = 'L'; + else { + if (*closed) return nullptr; + } } if (*count == 7) { //Special case for arc command @@ -537,7 +546,7 @@ static char* _nextCommand(char* path, char* cmd, float* arr, int* count) /************************************************************************/ -bool svgPathToTvgPath(const char* svgPath, Array& cmds, Array& pts) +bool svgPathToShape(const char* svgPath, Shape* shape) { float numberArray[7]; int numberCount = 0; @@ -546,14 +555,21 @@ bool svgPathToTvgPath(const char* svgPath, Array& cmds, Arrayrs.path.pts; + auto& cmds = P(shape)->rs.path.cmds; + auto lastCmds = cmds.count; + while ((path[0] != '\0')) { - path = _nextCommand(path, &cmd, numberArray, &numberCount); + path = _nextCommand(path, &cmd, numberArray, &numberCount, &closed); if (!path) break; - if (!_processCommand(&cmds, &pts, cmd, numberArray, numberCount, &cur, &curCtl, &startPoint, &isQuadratic)) break; + closed = false; + if (!_processCommand(&cmds, &pts, cmd, numberArray, numberCount, &cur, &curCtl, &startPoint, &isQuadratic, &closed)) break; } + if (cmds.count > lastCmds && cmds[lastCmds] != PathCommand::MoveTo) return false; return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.h index 5ac02cd6a..673fa0dda 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgPath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,7 @@ #include "tvgCommon.h" -bool svgPathToTvgPath(const char* svgPath, Array& cmds, Array& pts); +bool svgPathToShape(const char* svgPath, Shape* shape); #endif //_TVG_SVG_PATH_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.cpp index ace3d32e5..585e487a2 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -148,7 +148,7 @@ static unique_ptr _applyRadialGradientProperty(SvgStyleGradient* if (isTransform) finalTransform = *g->transform; if (g->userSpace) { - //The radius scalling is done according to the Units section: + //The radius scaling is done according to the Units section: //https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html g->radial->cx = g->radial->cx * vBox.w; g->radial->cy = g->radial->cy * vBox.h; @@ -313,7 +313,7 @@ static void _applyProperty(SvgLoaderData& loaderData, SvgNode* node, Shape* vg, //Clip transformation is applied directly to the path in the _appendClipShape function if (node->transform && !clip) vg->transform(*node->transform); - if (node->type == SvgNodeType::Doc || !node->display) return; + if (node->type == SvgNodeType::Doc || !node->style->display) return; //If fill property is nullptr then do nothing if (style->fill.paint.none) { @@ -399,10 +399,9 @@ static bool _recognizeShape(SvgNode* node, Shape* shape) switch (node->type) { case SvgNodeType::Path: { if (node->node.path.path) { - Array cmds; - Array pts; - if (svgPathToTvgPath(node->node.path.path, cmds, pts)) { - shape->appendPath(cmds.data, cmds.count, pts.data, pts.count); + if (!svgPathToShape(node->node.path.path, shape)) { + TVGERR("SVG", "Invalid path information."); + return false; } } break; @@ -413,7 +412,7 @@ static bool _recognizeShape(SvgNode* node, Shape* shape) } case SvgNodeType::Polygon: { if (node->node.polygon.pts.count < 2) break; - auto pts = node->node.polygon.pts.data; + auto pts = node->node.polygon.pts.begin(); shape->moveTo(pts[0], pts[1]); for (pts += 2; pts < node->node.polygon.pts.end(); pts += 2) { shape->lineTo(pts[0], pts[1]); @@ -423,7 +422,7 @@ static bool _recognizeShape(SvgNode* node, Shape* shape) } case SvgNodeType::Polyline: { if (node->node.polyline.pts.count < 2) break; - auto pts = node->node.polyline.pts.data; + auto pts = node->node.polyline.pts.begin(); shape->moveTo(pts[0], pts[1]); for (pts += 2; pts < node->node.polyline.pts.end(); pts += 2) { shape->lineTo(pts[0], pts[1]); @@ -561,7 +560,7 @@ static bool _isValidImageMimeTypeAndEncoding(const char** href, const char** mim static unique_ptr _imageBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath) { - if (!node->node.image.href) return nullptr; + if (!node->node.image.href || !strlen(node->node.image.href)) return nullptr; auto picture = Picture::gen(); TaskScheduler::async(false); //force to load a picture on the same thread @@ -786,13 +785,13 @@ static unique_ptr _sceneBuildHelper(SvgLoaderData& loaderData, const SvgN // For a Symbol node, the viewBox transformation has to be applied first - see _useBuildHelper() if (!mask && node->transform && node->type != SvgNodeType::Symbol) scene->transform(*node->transform); - if (node->display && node->style->opacity != 0) { + if (node->style->display && node->style->opacity != 0) { auto child = node->child.data; for (uint32_t i = 0; i < node->child.count; ++i, ++child) { if (_isGroupType((*child)->type)) { if ((*child)->type == SvgNodeType::Use) scene->push(_useBuildHelper(loaderData, *child, vBox, svgPath, depth + 1, isMaskWhite)); - else + else if (!((*child)->type == SvgNodeType::Symbol && node->type != SvgNodeType::Use)) scene->push(_sceneBuildHelper(loaderData, *child, vBox, svgPath, false, depth + 1, isMaskWhite)); } else if ((*child)->type == SvgNodeType::Image) { auto image = _imageBuildHelper(loaderData, *child, vBox, svgPath); @@ -848,7 +847,7 @@ static void _updateInvalidViewSize(const Scene* scene, Box& vBox, float& w, floa /* External Class Implementation */ /************************************************************************/ -unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag) +Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag) { //TODO: aspect ratio is valid only if viewBox was set @@ -866,8 +865,7 @@ unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, fl } auto viewBoxClip = Shape::gen(); - viewBoxClip->appendRect(0, 0, w, h, 0, 0); - viewBoxClip->fill(0, 0, 0); + viewBoxClip->appendRect(0, 0, w, h); auto compositeLayer = Scene::gen(); compositeLayer->composite(std::move(viewBoxClip), CompositeMethod::ClipPath); @@ -883,7 +881,7 @@ unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, fl loaderData.doc->node.doc.w = w; loaderData.doc->node.doc.h = h; - return root; + return root.release(); } #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.h index 5a401e713..8ab1b6721 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgSceneBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,7 @@ #include "tvgCommon.h" -unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag); +Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag); #endif //_TVG_SVG_SCENE_BUILDER_H_ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.cpp index 3c5da6cac..e77e2a0f7 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -50,7 +50,6 @@ size_t svgUtilURLDecode(const char *src, char** dst) if (length == 0) return 0; char* decoded = (char*)malloc(sizeof(char) * length + 1); - decoded[length] = '\0'; char a, b; int idx =0; @@ -67,9 +66,10 @@ size_t svgUtilURLDecode(const char *src, char** dst) decoded[idx++] = *src++; } } + decoded[idx] = '\0'; *dst = decoded; - return length + 1; + return idx + 1; } #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.h index c32298387..cc4b54c0d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSvgUtil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCanvas.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCanvas.cpp index b53fe26ed..27bd7e3f6 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCanvas.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,7 @@ #if LV_USE_THORVG_INTERNAL #include "tvgCanvas.h" +#include "tvgLoadModule.h" #ifdef THORVG_SW_RASTER_SUPPORT #include "tvgSwRenderer.h" @@ -89,10 +90,15 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t if (!renderer) return Result::MemoryCorruption; if (!renderer->target(buffer, stride, w, h, static_cast(cs))) return Result::InvalidArguments; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); //Paints must be updated again with this new target. Canvas::pImpl->needRefresh(); + //FIXME: The value must be associated with an individual canvas instance. + ImageLoader::cs = static_cast(cs); + return Result::Success; #endif return Result::NonSupport; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCommon.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCommon.h index 591b1c96f..182cf8fa3 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCommon.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -264,13 +264,26 @@ struct SwSurface : Surface SwAlpha alphas[4]; //Alpha:2, InvAlpha:3, Luma:4, InvLuma:5 SwBlender blender = nullptr; //blender (optional) SwCompositor* compositor = nullptr; //compositor (optional) - BlendMethod blendMethod; //blending method (uint8_t) + BlendMethod blendMethod; //blending method (uint8_t) SwAlpha alpha(CompositeMethod method) { auto idx = (int)(method) - 2; //0: None, 1: ClipPath return alphas[idx > 3 ? 0 : idx]; //CompositeMethod has only four Matting methods. } + + SwSurface() + { + } + + SwSurface(const SwSurface* rhs) : Surface(rhs) + { + join = rhs->join; + memcpy(alphas, rhs->alphas, sizeof(alphas)); + blender = rhs->blender; + compositor = rhs->compositor; + blendMethod = rhs->blendMethod; + } }; struct SwCompositor : Compositor diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwFill.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwFill.cpp index c4a697d35..f939fc8b2 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwFill.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -143,7 +143,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.dy = y2 - y1; fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; - if (fill->linear.len < FLT_EPSILON) return true; + if (fill->linear.len < FLOAT_EPSILON) return true; fill->linear.dx /= fill->linear.len; fill->linear.dy /= fill->linear.len; @@ -170,7 +170,6 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.dy = dx * invTransform.e12 + fill->linear.dy * invTransform.e22; fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; - if (fill->linear.len < FLT_EPSILON) return true; } return true; @@ -186,7 +185,7 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr auto fy = P(radial)->fy; auto fr = P(radial)->fr; - if (r < FLT_EPSILON) return true; + if (r < FLOAT_EPSILON) return true; fill->radial.dr = r - fr; fill->radial.dx = cx - fx; @@ -205,7 +204,13 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr fill->radial.fy = cy + r * (fy - cy) / dist; fill->radial.dx = cx - fill->radial.fx; fill->radial.dy = cy - fill->radial.fy; - fill->radial.a = fill->radial.dr * fill->radial.dr - fill->radial.dx * fill->radial.dx - fill->radial.dy * fill->radial.dy; + // Prevent loss of precision on Apple Silicon when dr=dy and dx=0 due to FMA + // https://github.com/thorvg/thorvg/issues/2014 + auto dr2 = fill->radial.dr * fill->radial.dr; + auto dx2 = fill->radial.dx * fill->radial.dx; + auto dy2 = fill->radial.dy * fill->radial.dy; + + fill->radial.a = dr2 - dx2 - dy2; } if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwImage.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwImage.cpp index 040c38930..22d1cf79a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwImage.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwImage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp index b636c04cf..8b8d8a4ba 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -53,12 +53,6 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw auto d2 = base[1] - base[2]; auto d3 = base[0] - base[1]; - if (d1 == d2 || d2 == d3) { - if (d3.small()) angleIn = angleMid = angleOut = 0; - else angleIn = angleMid = angleOut = mathAtan(d3); - return true; - } - if (d1.small()) { if (d2.small()) { if (d3.small()) { @@ -221,7 +215,7 @@ SwFixed mathLength(const SwPoint& pt) than 7% compared to the exact value. */ if (v.x < 0) v.x = -v.x; if (v.y < 0) v.y = -v.y; - return (SwFixed)((v.x > v.y) ? (v.x + v.y * 0.375f) : (v.y + v.x * 0.375f)); + return static_cast((v.x > v.y) ? (v.x + v.y * 0.375f) : (v.y + v.x * 0.375f)); } @@ -296,13 +290,13 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S { if (!outline) return false; - auto pt = outline->pts.data; - if (outline->pts.empty() || outline->cntrs.empty()) { renderRegion.reset(); return false; } + auto pt = outline->pts.begin(); + auto xMin = pt->x; auto xMax = pt->x; auto yMin = pt->y; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp index b9675e59c..4a9d7f527 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -89,6 +89,7 @@ SwMpool* mpoolInit(uint32_t threads) mpool->strokeOutline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); mpool->dashOutline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); mpool->allocSize = allocSize; + return mpool; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp index dc8c76eb1..237e30de7 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -260,15 +260,15 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride, auto ry2 = ry + 1; if (ry2 >= h) ry2 = h - 1; - auto dx = static_cast((sx - rx) * 255.0f); - auto dy = static_cast((sy - ry) * 255.0f); + auto dx = (sx > 0.0f) ? static_cast((sx - rx) * 255.0f) : 0; + auto dy = (sy > 0.0f) ? static_cast((sy - ry) * 255.0f) : 0; auto c1 = img[rx + ry * w]; auto c2 = img[rx2 + ry * w]; - auto c3 = img[rx2 + ry2 * w]; - auto c4 = img[rx + ry2 * w]; + auto c3 = img[rx + ry2 * w]; + auto c4 = img[rx2 + ry2 * w]; - return INTERPOLATE(INTERPOLATE(c3, c4, dx), INTERPOLATE(c2, c1, dx), dy); + return INTERPOLATE(INTERPOLATE(c4, c3, dx), INTERPOLATE(c2, c1, dx), dy); } @@ -284,21 +284,23 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t int32_t maxx = (int32_t)sx + n; if (maxx >= (int32_t)w) maxx = w; + int32_t inc = (n / 2) + 1; + n = 0; + auto src = img + minx + miny * stride; - for (auto y = miny; y < maxy; ++y) { + for (auto y = miny; y < maxy; y += inc) { auto p = src; - for (auto x = minx; x < maxx; ++x, ++p) { - c[0] += *p >> 24; - c[1] += (*p >> 16) & 0xff; - c[2] += (*p >> 8) & 0xff; - c[3] += *p & 0xff; + for (auto x = minx; x < maxx; x += inc, p += inc) { + c[0] += A(*p); + c[1] += C1(*p); + c[2] += C2(*p); + c[3] += C3(*p); + ++n; } - src += stride; + src += (stride * inc); } - n = (maxy - miny) * (maxx - minx); - c[0] /= n; c[1] /= n; c[2] /= n; @@ -375,7 +377,7 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t auto alpha = surface->alpha(surface->compositor->method); TVGLOG("SW_ENGINE", "Matted(%d) Rect [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h); - + //32bits channels if (surface->channelSize == sizeof(uint32_t)) { auto color = surface->join(r, g, b, a); @@ -672,10 +674,10 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, /************************************************************************/ #define SCALED_IMAGE_RANGE_Y(y) \ - auto sy = (y) * itransform->e22 + itransform->e23; \ - auto my = (int32_t)round(sy); \ - if (my < 0 || (uint32_t)sy >= image->h) continue; \ + auto sy = (y) * itransform->e22 + itransform->e23 - 0.49f; \ + if (sy <= -0.5f || (uint32_t)(sy + 0.5f) >= image->h) continue; \ if (scaleMethod == _interpDownScaler) { \ + auto my = (int32_t)round(sy); \ miny = my - (int32_t)sampleSize; \ if (miny < 0) miny = 0; \ maxy = my + (int32_t)sampleSize; \ @@ -683,8 +685,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, } #define SCALED_IMAGE_RANGE_X \ - auto sx = x * itransform->e11 + itransform->e13; \ - if ((int32_t)round(sx) < 0 || (uint32_t) sx >= image->w) continue; + auto sx = (x) * itransform->e11 + itransform->e13 - 0.49f; \ + if (sx <= -0.5f || (uint32_t)(sx + 0.5f) >= image->w) continue; \ #if 0 //Enable it when GRAYSCALE image is supported @@ -717,7 +719,7 @@ static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage* auto span = image->rle->spans; int32_t miny = 0, maxy = 0; - for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { + for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { SCALED_IMAGE_RANGE_Y(span->y) auto cmp = &surface->compositor->image.buf8[span->y * surface->compositor->image.stride + span->x]; auto dst = &surface->buf8[span->y * surface->stride + span->x]; @@ -866,11 +868,11 @@ static bool _rasterCompositeDirectMaskedRleImage(SwSurface* surface, const SwIma { auto span = image->rle->spans; auto cbuffer = surface->compositor->image.buf8; - auto ctride = surface->compositor->image.stride; + auto cstride = surface->compositor->image.stride; for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto src = image->buf8 + (span->y + image->oy) * image->stride + (span->x + image->ox); - auto cmp = &cbuffer[span->y * ctride + span->x]; + auto cmp = &cbuffer[span->y * cstride + span->x]; auto alpha = MULTIPLY(span->coverage, opacity); if (alpha == 255) { for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) { @@ -891,11 +893,11 @@ static bool _rasterDirectDirectMaskedRleImage(SwSurface* surface, const SwImage* { auto span = image->rle->spans; auto cbuffer = surface->compositor->image.buf8; - auto ctride = surface->compositor->image.stride; + auto cstride = surface->compositor->image.stride; for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto src = image->buf8 + (span->y + image->oy) * image->stride + (span->x + image->ox); - auto cmp = &cbuffer[span->y * ctride + span->x]; + auto cmp = &cbuffer[span->y * cstride + span->x]; auto dst = &surface->buf8[span->y * surface->stride + span->x]; auto alpha = MULTIPLY(span->coverage, opacity); if (alpha == 255) { @@ -1554,7 +1556,7 @@ static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, c static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { - if (fill->linear.len < FLT_EPSILON) return false; + if (fill->linear.len < FLOAT_EPSILON) return false; if (_compositing(surface)) { if (_matting(surface)) return _rasterGradientMattedRect(surface, region, fill); @@ -1717,7 +1719,7 @@ static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, co static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) { - if (!rle || fill->linear.len < FLT_EPSILON) return false; + if (!rle) return false; if (_compositing(surface)) { if (_matting(surface)) return _rasterGradientMattedRle(surface, rle, fill); @@ -1756,8 +1758,13 @@ static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, c void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len) { - //OPTIMIZE_ME: Support SIMD +#if defined(THORVG_AVX_VECTOR_SUPPORT) + avxRasterGrayscale8(dst, val, offset, len); +#elif defined(THORVG_NEON_VECTOR_SUPPORT) + neonRasterGrayscale8(dst, val, offset, len); +#else cRasterPixels(dst, val, offset, len); +#endif } @@ -1858,7 +1865,9 @@ void rasterUnpremultiply(Surface* surface) void rasterPremultiply(Surface* surface) { - if (surface->channelSize != sizeof(uint32_t)) return; + ScopedLock lock(surface->key); + if (surface->premultiplied || (surface->channelSize != sizeof(uint32_t))) return; + surface->premultiplied = true; TVGLOG("SW_ENGINE", "Premultiply [Size: %d x %d]", surface->w, surface->h); @@ -1872,7 +1881,6 @@ void rasterPremultiply(Surface* surface) *dst = (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); } } - surface->premultiplied = true; } @@ -1928,8 +1936,8 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity) { - //Verify Boundary - if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast(surface->w) || bbox.min.y >= static_cast(surface->h)) return false; + //Outside of the viewport, skip the rendering + if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast(surface->w) || bbox.min.y >= static_cast(surface->h)) return true; if (mesh && mesh->triangleCnt > 0) return _rasterTexmapPolygonMesh(surface, image, mesh, transform, &bbox, opacity); else return _rasterImage(surface, image, transform, bbox, opacity); @@ -1938,7 +1946,10 @@ bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, con bool rasterConvertCS(Surface* surface, ColorSpace to) { - //TOOD: Support SIMD accelerations + ScopedLock lock(surface->key); + if (surface->cs == to) return true; + + //TODO: Support SIMD accelerations auto from = surface->cs; if (((from == ColorSpace::ABGR8888) || (from == ColorSpace::ABGR8888S)) && ((to == ColorSpace::ARGB8888) || (to == ColorSpace::ARGB8888S))) { @@ -1949,7 +1960,6 @@ bool rasterConvertCS(Surface* surface, ColorSpace to) surface->cs = to; return cRasterARGBtoABGR(surface); } - return false; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h index 633abf1db..82c177ce3 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. +/* + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -65,6 +65,23 @@ static inline __m128i ALPHA_BLEND(__m128i c, __m128i a) } +static void avxRasterGrayscale8(uint8_t* dst, uint8_t val, uint32_t offset, int32_t len) +{ + dst += offset; + + __m256i vecVal = _mm256_set1_epi8(val); + + int32_t i = 0; + for (; i <= len - 32; i += 32) { + _mm256_storeu_si256((__m256i*)(dst + i), vecVal); + } + + for (; i < len; ++i) { + dst[i] = val; + } +} + + static void avxRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) { //1. calculate how many iterations we need to cover the length @@ -163,7 +180,7 @@ static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, ui } //2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once - //In order to avoid unneccessary avx variables declarations a check is made whether there are any iterations at all + //In order to avoid unnecessary avx variables declarations a check is made whether there are any iterations at all uint32_t iterations = (span->len - notAligned) / N_32BITS_IN_128REG; uint32_t avxFilled = 0; if (iterations > 0) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h index c7f2840f8..bc5211e5e 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h index 97e4706a3..a84bfe87d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,6 +27,15 @@ #include +//TODO : need to support windows ARM + +#if defined(__ARM_64BIT_STATE) || defined(_M_ARM64) +#define TVG_AARCH64 1 +#else +#define TVG_AARCH64 0 +#endif + + static inline uint8x8_t ALPHA_BLEND(uint8x8_t c, uint8x8_t a) { uint16x8_t t = vmull_u8(c, a); @@ -34,19 +43,50 @@ static inline uint8x8_t ALPHA_BLEND(uint8x8_t c, uint8x8_t a) } +static void neonRasterGrayscale8(uint8_t* dst, uint8_t val, uint32_t offset, int32_t len) +{ + dst += offset; + + int32_t i = 0; + const uint8x16_t valVec = vdupq_n_u8(val); +#if TVG_AARCH64 + uint8x16x4_t valQuad = {valVec, valVec, valVec, valVec}; + for (; i <= len - 16 * 4; i += 16 * 4) { + vst1q_u8_x4(dst + i, valQuad); + } +#else + for (; i <= len - 16; i += 16) { + vst1q_u8(dst + i, valVec); + } +#endif + for (; i < len; i++) { + dst[i] = val; + } +} + + static void neonRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) { + dst += offset; + + uint32x4_t vectorVal = vdupq_n_u32(val); + +#if TVG_AARCH64 + uint32_t iterations = len / 16; + uint32_t neonFilled = iterations * 16; + uint32x4x4_t valQuad = {vectorVal, vectorVal, vectorVal, vectorVal}; + for (uint32_t i = 0; i < iterations; ++i) { + vst4q_u32(dst, valQuad); + dst += 16; + } +#else uint32_t iterations = len / 4; uint32_t neonFilled = iterations * 4; - - dst += offset; - uint32x4_t vectorVal = {val, val, val, val}; - for (uint32_t i = 0; i < iterations; ++i) { vst1q_u32(dst, vectorVal); dst += 4; } - +#endif int32_t leftovers = len - neonFilled; while (leftovers--) *dst++ = val; } @@ -59,7 +99,7 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, u return false; } - auto color = surface->blender.join(r, g, b, a); + auto color = surface->join(r, g, b, a); auto span = rle->spans; uint32_t src; uint8x8_t *vDst = nullptr; @@ -70,9 +110,9 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, u else src = color; auto dst = &surface->buf32[span->y * surface->stride + span->x]; - auto ialpha = IALPHA(src); + auto ialpha = IA(src); - if ((((uint32_t) dst) & 0x7) != 0) { + if ((((uintptr_t) dst) & 0x7) != 0) { //fill not aligned byte *dst = src + ALPHA_BLEND(*dst, ialpha); vDst = (uint8x8_t*)(dst + 1); @@ -104,7 +144,7 @@ static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, return false; } - auto color = surface->blender.join(r, g, b, a); + auto color = surface->join(r, g, b, a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); @@ -119,7 +159,7 @@ static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; - if ((((uint32_t) dst) & 0x7) != 0) { + if ((((uintptr_t) dst) & 0x7) != 0) { //fill not aligned byte *dst = color + ALPHA_BLEND(*dst, ialpha); vDst = (uint8x8_t*) (dst + 1); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h index d7353c7c2..6ef2e3204 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -88,7 +88,7 @@ static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* int32_t sh = image->h; int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; int32_t vv = 0, uu = 0; - int32_t minx = INT32_MAX, maxx = INT32_MIN; + int32_t minx = INT32_MAX, maxx = 0; float dx, u, v, iptr; SwSpan* span = nullptr; //used only when rle based. @@ -116,7 +116,7 @@ static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* if (!region) { minx = INT32_MAX; - maxx = INT32_MIN; + maxx = 0; //one single row, could be consisted of multiple spans. while (span->y == y && spanIdx < image->rle->size) { if (minx > span->x) minx = span->x; @@ -281,7 +281,7 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage int32_t dw = surface->stride; int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; int32_t vv = 0, uu = 0; - int32_t minx = INT32_MAX, maxx = INT32_MIN; + int32_t minx = INT32_MAX, maxx = 0; float dx, u, v, iptr; uint32_t* buf; SwSpan* span = nullptr; //used only when rle based. @@ -310,7 +310,7 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage if (!region) { minx = INT32_MAX; - maxx = INT32_MIN; + maxx = 0; //one single row, could be consisted of multiple spans. while (span->y == y && spanIdx < image->rle->size) { if (minx > span->x) minx = span->x; @@ -458,7 +458,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, int32_t dw = surface->stride; int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay; int32_t vv = 0, uu = 0; - int32_t minx = INT32_MAX, maxx = INT32_MIN; + int32_t minx = INT32_MAX, maxx = 0; float dx, u, v, iptr; uint32_t* buf; SwSpan* span = nullptr; //used only when rle based. @@ -492,7 +492,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, if (!region) { minx = INT32_MAX; - maxx = INT32_MIN; + maxx = 0; //one single row, could be consisted of multiple spans. while (span->y == y && spanIdx < image->rle->size) { if (minx > span->x) minx = span->x; @@ -531,8 +531,8 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, vv = (int) v; if (vv >= sh) continue; - ar = (int)(255 * (1 - modff(u, &iptr))); - ab = (int)(255 * (1 - modff(v, &iptr))); + ar = (int)(255.0f * (1.0f - modff(u, &iptr))); + ab = (int)(255.0f * (1.0f - modff(v, &iptr))); iru = uu + 1; irv = vv + 1; @@ -579,8 +579,8 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, uu = (int) u; vv = (int) v; - ar = (int)(255 * (1 - modff(u, &iptr))); - ab = (int)(255 * (1 - modff(v, &iptr))); + ar = (int)(255.0f * (1.0f - modff(u, &iptr))); + ab = (int)(255.0f * (1.0f - modff(v, &iptr))); iru = uu + 1; irv = vv + 1; @@ -836,11 +836,13 @@ static AASpans* _AASpans(float ymin, float ymax, const SwImage* image, const SwB //Initialize X range auto height = yEnd - yStart; - aaSpans->lines = static_cast(calloc(height, sizeof(AALine))); + aaSpans->lines = static_cast(malloc(height * sizeof(AALine))); for (int32_t i = 0; i < height; i++) { aaSpans->lines[i].x[0] = INT32_MAX; - aaSpans->lines[i].x[1] = INT32_MIN; + aaSpans->lines[i].x[1] = 0; + aaSpans->lines[i].length[0] = 0; + aaSpans->lines[i].length[1] = 0; } return aaSpans; } @@ -1111,8 +1113,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const float ys = FLT_MAX, ye = -1.0f; for (int i = 0; i < 4; i++) { - mathMultiply(&vertices[i].pt, transform); - + if (transform) mathMultiply(&vertices[i].pt, transform); if (vertices[i].pt.y < ys) ys = vertices[i].pt.y; if (vertices[i].pt.y > ye) ye = vertices[i].pt.y; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp index 007c09edb..9a0965424 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,8 +48,11 @@ struct SwTask : Task bool pushed = false; //Pushed into task list? bool disposed = false; //Disposed task? - RenderRegion bounds() const + RenderRegion bounds() { + //Can we skip the synchronization? + done(); + RenderRegion region; //Range over? @@ -63,7 +66,7 @@ struct SwTask : Task return region; } - virtual bool dispose() = 0; + virtual void dispose() = 0; virtual bool clip(SwRleData* target) = 0; virtual SwRleData* rle() = 0; @@ -142,7 +145,9 @@ struct SwShapeTask : SwTask visibleFill = (alpha > 0 || rshape->fill); if (visibleFill || clipper) { shapeReset(&shape); - if (!shapePrepare(&shape, rshape, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err; + if (!shapePrepare(&shape, rshape, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) { + visibleFill = false; + } } } //Fill @@ -180,7 +185,7 @@ struct SwShapeTask : SwTask shapeDelOutline(&shape, mpool, tid); //Clip Path - for (auto clip = clips.data; clip < clips.end(); ++clip) { + for (auto clip = clips.begin(); clip < clips.end(); ++clip) { auto clipper = static_cast(*clip); //Clip shape rle if (shape.rle && !clipper->clip(shape.rle)) goto err; @@ -194,10 +199,9 @@ struct SwShapeTask : SwTask shapeDelOutline(&shape, mpool, tid); } - bool dispose() override + void dispose() override { shapeFree(&shape); - return true; } }; @@ -228,7 +232,7 @@ struct SwSceneTask : SwTask void run(unsigned tid) override { - //TODO: Skip the run if the scene hans't changed. + //TODO: Skip the run if the scene hasn't changed. if (!sceneRle) sceneRle = static_cast(calloc(1, sizeof(SwRleData))); else rleReset(sceneRle); @@ -241,17 +245,16 @@ struct SwSceneTask : SwTask rleMerge(sceneRle, clipper1->rle(), clipper2->rle()); //Unify the remained clippers - for (auto rd = scene.data + 2; rd < scene.end(); ++rd) { + for (auto rd = scene.begin() + 2; rd < scene.end(); ++rd) { auto clipper = static_cast(*rd); rleMerge(sceneRle, sceneRle, clipper->rle()); } } } - bool dispose() override + void dispose() override { rleFree(sceneRle); - return true; } }; @@ -279,10 +282,8 @@ struct SwImageTask : SwTask auto clipRegion = bbox; //Convert colorspace if it's not aligned. - if (source->owner) { - if (source->cs != surface->cs) rasterConvertCS(source, surface->cs); - if (!source->premultiplied) rasterPremultiply(source); - } + rasterConvertCS(source, surface->cs); + rasterPremultiply(source); image.data = source->data; image.w = source->w; @@ -303,7 +304,7 @@ struct SwImageTask : SwTask if (image.rle) { //Clear current task memorypool here if the clippers would use the same memory pool imageDelOutline(&image, mpool, tid); - for (auto clip = clips.data; clip < clips.end(); ++clip) { + for (auto clip = clips.begin(); clip < clips.end(); ++clip) { auto clipper = static_cast(*clip); if (!clipper->clip(image.rle)) goto err; } @@ -318,10 +319,9 @@ struct SwImageTask : SwTask imageDelOutline(&image, mpool, tid); } - bool dispose() override + void dispose() override { imageFree(&image); - return true; } }; @@ -380,7 +380,7 @@ SwRenderer::~SwRenderer() bool SwRenderer::clear() { - for (auto task = tasks.data; task < tasks.end(); ++task) { + for (auto task = tasks.begin(); task < tasks.end(); ++task) { if ((*task)->disposed) { delete(*task); } else { @@ -425,6 +425,8 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, { if (!data || stride == 0 || w == 0 || h == 0 || w > stride) return false; + clearCompositors(); + if (!surface) surface = new SwSurface; surface->data = data; @@ -434,11 +436,6 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, surface->cs = cs; surface->channelSize = CHANNEL_SIZE(cs); surface->premultiplied = true; - surface->owner = true; - - vport.x = vport.y = 0; - vport.w = surface->w; - vport.h = surface->h; return rasterCompositor(surface); } @@ -446,18 +443,14 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, bool SwRenderer::preRender() { -#if LV_USE_DRAW_VG_LITE && LV_USE_VG_LITE_THORVG return true; -#else - return rasterClear(surface, 0, 0, surface->w, surface->h); -#endif } void SwRenderer::clearCompositors() { //Free Composite Caches - for (auto comp = compositors.data; comp < compositors.end(); ++comp) { + for (auto comp = compositors.begin(); comp < compositors.end(); ++comp) { free((*comp)->compositor->image.data); delete((*comp)->compositor); delete(*comp); @@ -473,13 +466,12 @@ bool SwRenderer::postRender() rasterUnpremultiply(surface); } - for (auto task = tasks.data; task < tasks.end(); ++task) { + for (auto task = tasks.begin(); task < tasks.end(); ++task) { if ((*task)->disposed) delete(*task); else (*task)->pushed = false; } tasks.clear(); - clearCompositors(); return true; } @@ -614,6 +606,12 @@ bool SwRenderer::mempool(bool shared) } +const Surface* SwRenderer::mainSurface() +{ + return surface; +} + + Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) { auto x = region.x; @@ -631,7 +629,7 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) auto reqChannelSize = CHANNEL_SIZE(cs); //Use cached data - for (auto p = compositors.data; p < compositors.end(); ++p) { + for (auto p = compositors.begin(); p < compositors.end(); ++p) { if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) { cmp = *p; break; @@ -640,11 +638,8 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) //New Composition if (!cmp) { - cmp = new SwSurface; - //Inherits attributes from main surface - *cmp = *surface; - + cmp = new SwSurface(surface); cmp->compositor = new SwCompositor; //TODO: We can optimize compositor surface size from (surface->stride x surface->h) to Parameter(w x h) @@ -710,17 +705,15 @@ ColorSpace SwRenderer::colorSpace() } -bool SwRenderer::dispose(RenderData data) +void SwRenderer::dispose(RenderData data) { auto task = static_cast(data); - if (!task) return true; + if (!task) return; task->done(); task->dispose(); if (task->pushed) task->disposed = true; else delete(task); - - return true; } @@ -735,7 +728,7 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, //TODO: Failed threading them. It would be better if it's possible. //See: https://github.com/thorvg/thorvg/issues/1409 //Guarantee composition targets get ready. - for (auto clip = clips.data; clip < clips.end(); ++clip) { + for (auto clip = clips.begin(); clip < clips.end(); ++clip) { static_cast(*clip)->done(); } @@ -796,7 +789,7 @@ RenderData SwRenderer::prepare(const Array& scene, RenderData data, //TODO: Failed threading them. It would be better if it's possible. //See: https://github.com/thorvg/thorvg/issues/1409 //Guarantee composition targets get ready. - for (auto task = scene.data; task < scene.end(); ++task) { + for (auto task = scene.begin(); task < scene.end(); ++task) { static_cast(*task)->done(); } return prepareCommon(task, transform, clips, opacity, flags); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h index 8df5a2143..593ba52e4 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,12 +46,13 @@ public: bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; bool postRender() override; - bool dispose(RenderData data) override; + void dispose(RenderData data) override; RenderRegion region(RenderData data) override; RenderRegion viewport() override; bool viewport(const RenderRegion& vp) override; bool blend(BlendMethod method) override; ColorSpace colorSpace() override; + const Surface* mainSurface() override; bool clear() override; bool sync() override; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp index e541e943b..689f2fe1f 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -325,7 +325,7 @@ static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count) } -static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord acount) +static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord aCount) { x += rw.cellMin.x; y += rw.cellMin.y; @@ -349,11 +349,11 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor //span has ushort coordinates. check limit overflow if (x >= SHRT_MAX) { - TVGERR("SW_ENGINE", "X-coordiante overflow!"); + TVGERR("SW_ENGINE", "X-coordinate overflow!"); x = SHRT_MAX; } if (y >= SHRT_MAX) { - TVGERR("SW_ENGINE", "Y Coordiante overflow!"); + TVGERR("SW_ENGINE", "Y Coordinate overflow!"); y = SHRT_MAX; } @@ -368,11 +368,11 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor //Clip x range SwCoord xOver = 0; - if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); + if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x); if (x < rw.cellMin.x) xOver -= (rw.cellMin.x - x); - //span->len += (acount + xOver) - 1; - span->len += (acount + xOver); + //span->len += (aCount + xOver) - 1; + span->len += (aCount + xOver); return; } @@ -387,19 +387,19 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor //Clip x range SwCoord xOver = 0; - if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); + if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x); if (x < rw.cellMin.x) { xOver -= (rw.cellMin.x - x); x = rw.cellMin.x; } //Nothing to draw - if (acount + xOver <= 0) return; + if (aCount + xOver <= 0) return; //add a span to the current list span->x = x; span->y = y; - span->len = (acount + xOver); + span->len = (aCount + xOver); span->coverage = coverage; ++rw.spansCnt; rw.ySpan = y; @@ -716,7 +716,7 @@ static void _decomposeOutline(RleWorker& rw) auto outline = rw.outline; auto first = 0; //index of first point in contour - for (auto cntr = outline->cntrs.data; cntr < outline->cntrs.end(); ++cntr) { + for (auto cntr = outline->cntrs.begin(); cntr < outline->cntrs.end(); ++cntr) { auto last = *cntr; auto limit = outline->pts.data + last; auto start = UPSCALE(outline->pts[first]); @@ -772,7 +772,7 @@ static SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *tar auto clipEnd = clip->spans + clip->size; while (spans < end && clipSpans < clipEnd) { - //align y cooridnates. + //align y coordinates. if (clipSpans->y > spans->y) { ++spans; continue; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp index 6a9ea5330..e2652c1ea 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,57 +25,41 @@ #include "tvgSwCommon.h" #include "tvgMath.h" -#include "tvgBezier.h" +#include "tvgLines.h" /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -struct Line +static bool _outlineBegin(SwOutline& outline) { - Point pt1; - Point pt2; -}; - - -static float _lineLength(const Point& pt1, const Point& pt2) -{ - /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. - With alpha = 1, beta = 3/8, giving results with the largest error less - than 7% compared to the exact value. */ - Point diff = {pt2.x - pt1.x, pt2.y - pt1.y}; - if (diff.x < 0) diff.x = -diff.x; - if (diff.y < 0) diff.y = -diff.y; - return (diff.x > diff.y) ? (diff.x + diff.y * 0.375f) : (diff.y + diff.x * 0.375f); -} - - -static void _lineSplitAt(const Line& cur, float at, Line& left, Line& right) -{ - auto len = _lineLength(cur.pt1, cur.pt2); - auto dx = ((cur.pt2.x - cur.pt1.x) / len) * at; - auto dy = ((cur.pt2.y - cur.pt1.y) / len) * at; - left.pt1 = cur.pt1; - left.pt2.x = left.pt1.x + dx; - left.pt2.y = left.pt1.y + dy; - right.pt1 = left.pt2; - right.pt2 = cur.pt2; -} - - -static void _outlineEnd(SwOutline& outline) -{ - if (outline.pts.empty()) return; + //Make a contour if lineTo/curveTo without calling close or moveTo beforehand. + if (outline.pts.empty()) return false; outline.cntrs.push(outline.pts.count - 1); + outline.closed.push(false); + outline.pts.push(outline.pts[outline.cntrs.last()]); + outline.types.push(SW_CURVE_TYPE_POINT); + return false; } -static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform) +static bool _outlineEnd(SwOutline& outline) { - if (outline.pts.count > 0) outline.cntrs.push(outline.pts.count - 1); + if (outline.pts.empty()) return false; + outline.cntrs.push(outline.pts.count - 1); + outline.closed.push(false); + return false; +} + + +static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform, bool closed = false) +{ + //make it a contour, if the last contour is not closed yet. + if (!closed) _outlineEnd(outline); outline.pts.push(mathTransform(to, transform)); outline.types.push(SW_CURVE_TYPE_POINT); + return false; } @@ -92,36 +76,41 @@ static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* outline.types.push(SW_CURVE_TYPE_CUBIC); outline.pts.push(mathTransform(ctrl2, transform)); - outline.types.push(SW_CURVE_TYPE_CUBIC); + outline.types.push(SW_CURVE_TYPE_CUBIC); outline.pts.push(mathTransform(to, transform)); outline.types.push(SW_CURVE_TYPE_POINT); } -static void _outlineClose(SwOutline& outline) +static bool _outlineClose(SwOutline& outline) { - uint32_t i = 0; - + uint32_t i; if (outline.cntrs.count > 0) i = outline.cntrs.last() + 1; - else i = 0; //First Path + else i = 0; //Make sure there is at least one point in the current path - if (outline.pts.count == i) return; + if (outline.pts.count == i) return false; //Close the path outline.pts.push(outline.pts[i]); + outline.cntrs.push(outline.pts.count - 1); outline.types.push(SW_CURVE_TYPE_POINT); outline.closed.push(true); + + return true; } static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform) { Line cur = {dash.ptCur, *to}; - auto len = _lineLength(cur.pt1, cur.pt2); + auto len = lineLength(cur.pt1, cur.pt2); - if (len < dash.curLen) { + if (mathZero(len)) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + //draw the current line fully + } else if (len < dash.curLen) { dash.curLen -= len; if (!dash.curOpGap) { if (dash.move) { @@ -130,14 +119,15 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans } _outlineLineTo(*dash.outline, to, transform); } + //draw the current line partially } else { - while (len > dash.curLen) { + while (len - dash.curLen > 0.0001f) { Line left, right; if (dash.curLen > 0) { len -= dash.curLen; - _lineSplitAt(cur, dash.curLen, left, right); + lineSplitAt(cur, dash.curLen, left, right); if (!dash.curOpGap) { - if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) { + if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { _outlineMoveTo(*dash.outline, &left.pt1, transform); dash.move = false; } @@ -178,7 +168,10 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to}; auto len = bezLength(cur); - if (len < dash.curLen) { + //draw the current line fully + if (mathZero(len)) { + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + } else if (len < dash.curLen) { dash.curLen -= len; if (!dash.curOpGap) { if (dash.move) { @@ -187,14 +180,15 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct } _outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform); } + //draw the current line partially } else { - while (len > dash.curLen) { + while ((len - dash.curLen) > 0.0001f) { Bezier left, right; if (dash.curLen > 0) { len -= dash.curLen; bezSplitAt(cur, dash.curLen, left, right); if (!dash.curOpGap) { - if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) { + if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { _outlineMoveTo(*dash.outline, &left.start, transform); dash.move = false; } @@ -236,7 +230,15 @@ static void _dashClose(SwDashStroke& dash, const Matrix* transform) } -static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts, const Matrix* transform) +static void _dashMoveTo(SwDashStroke& dash, const Point* pts) +{ + dash.ptCur = *pts; + dash.ptStart = *pts; + dash.move = true; +} + + +static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts) { dash.curIdx = offIdx % dash.cnt; dash.curLen = dash.pattern[dash.curIdx] - offset; @@ -271,7 +273,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans //default if (end > begin) { - if (begin > 0) dash.cnt += 4; + if (begin > 0.0f) dash.cnt += 4; else dash.cnt += 2; //looping } else dash.cnt += 3; @@ -289,11 +291,11 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans dash.pattern[0] = 0; //zero dash to start with a space. dash.pattern[1] = begin; dash.pattern[2] = end - begin; - dash.pattern[3] = length - (end - begin); + dash.pattern[3] = length - end; } trimmed = true; - //just a dasy style. + //just a dash style. } else { if (dash.cnt == 0) return nullptr; } @@ -306,7 +308,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans bool isOdd = dash.cnt % 2; if (isOdd) patternLength *= 2; - offset = fmod(offset, patternLength); + offset = fmodf(offset, patternLength); if (offset < 0) offset += patternLength; for (size_t i = 0; i < dash.cnt * (1 + (size_t)isOdd); ++i, ++offIdx) { @@ -318,29 +320,22 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans dash.outline = mpoolReqDashOutline(mpool, tid); - //smart reservation - auto closeCnt = 0; - auto moveCnt = 0; - - for (auto cmd = rshape->path.cmds.data; cmd < rshape->path.cmds.end(); ++cmd) { - if (*cmd == PathCommand::Close) ++closeCnt; - else if (*cmd == PathCommand::MoveTo) ++moveCnt; + //must begin with moveTo + if (cmds[0] == PathCommand::MoveTo) { + _dashMoveTo(dash, offIdx, offset, pts); + cmds++; + pts++; } - //No idea exact count.... Reserve Approximitely 20x... - //OPTIMIZE: we can directly copy the path points when the close is occupied with a point. - dash.outline->pts.grow(20 * (closeCnt + ptsCnt + 1)); - dash.outline->types.grow(20 * (closeCnt + ptsCnt + 1)); - dash.outline->cntrs.grow(20 * (moveCnt + 1)); - - while (cmdCnt-- > 0) { + while (--cmdCnt > 0) { switch (*cmds) { case PathCommand::Close: { _dashClose(dash, transform); break; } case PathCommand::MoveTo: { - _dashMoveTo(dash, offIdx, offset, pts, transform); + if (rshape->stroke->trim.individual) _dashMoveTo(dash, pts); + else _dashMoveTo(dash, offIdx, offset, pts); ++pts; break; } @@ -378,13 +373,19 @@ static float _outlineLength(const RenderShape* rshape) const Point* close = nullptr; auto length = 0.0f; + auto slength = -1.0f; + auto simultaneous = !rshape->stroke->trim.individual; //Compute the whole length while (cmdCnt-- > 0) { switch (*cmds) { case PathCommand::Close: { length += mathLength(pts - 1, close); - ++pts; + //retrieve the max length of the shape if the simultaneous mode. + if (simultaneous) { + if (slength < length) slength = length; + length = 0.0f; + } break; } case PathCommand::MoveTo: { @@ -405,7 +406,8 @@ static float _outlineLength(const RenderShape* rshape) } ++cmds; } - return length; + if (simultaneous && slength > length) return slength; + else return length; } @@ -438,47 +440,30 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* //No actual shape data if (cmdCnt == 0 || ptsCnt == 0) return false; - //smart reservation - auto moveCnt = 0; - auto closeCnt = 0; - - for (auto cmd = rshape->path.cmds.data; cmd < rshape->path.cmds.end(); ++cmd) { - if (*cmd == PathCommand::Close) ++closeCnt; - else if (*cmd == PathCommand::MoveTo) ++moveCnt; - } - shape->outline = mpoolReqOutline(mpool, tid); auto outline = shape->outline; - - //OPTIMIZE: we can directly copy the path points when the close is occupied with a point. - outline->pts.grow(ptsCnt + closeCnt + 1); - outline->types.grow(ptsCnt + closeCnt + 1); - outline->cntrs.grow(moveCnt + 1); - - //Dash outlines are always opened. - //Only normal outlines use this information, it sholud be same to their contour counts. - outline->closed.reserve(outline->cntrs.reserved); - - memset(outline->closed.data, 0x0, sizeof(bool) * outline->closed.reserved); + auto closed = false; //Generate Outlines while (cmdCnt-- > 0) { switch (*cmds) { case PathCommand::Close: { - _outlineClose(*outline); + if (!closed) closed = _outlineClose(*outline); break; } case PathCommand::MoveTo: { - _outlineMoveTo(*outline, pts, transform); + closed = _outlineMoveTo(*outline, pts, transform, closed); ++pts; break; } case PathCommand::LineTo: { + if (closed) closed = _outlineBegin(*outline); _outlineLineTo(*outline, pts, transform); ++pts; break; } case PathCommand::CubicTo: { + if (closed) closed = _outlineBegin(*outline); _outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform); pts += 3; break; @@ -487,7 +472,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* ++cmds; } - _outlineEnd(*outline); + if (!closed) _outlineEnd(*outline); outline->fillRule = rshape->rule; shape->outline = outline; @@ -561,11 +546,15 @@ void shapeReset(SwShape* shape) void shapeFree(SwShape* shape) { rleFree(shape->rle); + shape->rle = nullptr; + shapeDelFill(shape); if (shape->stroke) { rleFree(shape->strokeRle); + shape->strokeRle = nullptr; strokeFree(shape->stroke); + shape->stroke = nullptr; } } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp index c097c6063..954250c8c 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -380,9 +380,6 @@ static void _lineTo(SwStroke& stroke, const SwPoint& to) //a zero-length lineto is a no-op; avoid creating a spurious corner if (delta.zero()) return; - //compute length of line - auto angle = mathAtan(delta); - /* The lineLength is used to determine the intersection of strokes outlines. The scale needs to be reverted since the stroke width has not been scaled. An alternative option is to scale the width of the stroke properly by @@ -390,6 +387,7 @@ static void _lineTo(SwStroke& stroke, const SwPoint& to) delta.x = static_cast(delta.x / stroke.sx); delta.y = static_cast(delta.y / stroke.sy); auto lineLength = mathLength(delta); + auto angle = mathAtan(delta); delta = {static_cast(stroke.width), 0}; mathRotate(delta, angle + SW_ANGLE_PI2); @@ -667,7 +665,7 @@ static void _beginSubPath(SwStroke& stroke, const SwPoint& to, bool closed) /* Determine if we need to check whether the border radius is greater than the radius of curvature of a curve, to handle this case specially. This is only required if bevel joins or butt caps may be created because - round & miter joins and round & square caps cover the nagative sector + round & miter joins and round & square caps cover the negative sector created with wide strokes. */ if ((stroke.join != StrokeJoin::Round) || (!stroke.closedSubPath && stroke.cap == StrokeCap::Butt)) stroke.handleWideStrokes = true; @@ -720,7 +718,7 @@ static void _endSubPath(SwStroke& stroke) _addCap(stroke, stroke.subPathAngle + SW_ANGLE_PI, 0); /* now end the right subpath accordingly. The left one is rewind - and deosn't need further processing */ + and doesn't need further processing */ _borderClose(right, false); } } @@ -838,7 +836,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline) uint32_t first = 0; uint32_t i = 0; - for (auto cntr = outline.cntrs.data; cntr < outline.cntrs.end(); ++cntr, ++i) { + for (auto cntr = outline.cntrs.begin(); cntr < outline.cntrs.end(); ++cntr, ++i) { auto last = *cntr; //index of last point in contour auto limit = outline.pts.data + last; @@ -864,7 +862,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline) ++pt; ++types; - //emit a signel line_to + //emit a single line_to if (types[0] == SW_CURVE_TYPE_POINT) { _lineTo(*stroke, *pt); //types cubic diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.cpp index cad12c3a8..b5c7c2ed9 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,56 +23,211 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL -#include -#include +#include "tvgArray.h" +#include "tvgInlist.h" #include "tvgTaskScheduler.h" +#ifdef THORVG_THREAD_SUPPORT + #include + #include +#endif + /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ namespace tvg { -static thread_local bool _async = true; //toggle async tasking for each thread on/off +struct TaskSchedulerImpl; +static TaskSchedulerImpl* inst = nullptr; + +#ifdef THORVG_THREAD_SUPPORT + +static thread_local bool _async = true; + +struct TaskQueue { + Inlist taskDeque; + mutex mtx; + condition_variable ready; + bool done = false; + + bool tryPop(Task** task) + { + unique_lock lock{mtx, try_to_lock}; + if (!lock || taskDeque.empty()) return false; + *task = taskDeque.front(); + return true; + } + + bool tryPush(Task* task) + { + { + unique_lock lock{mtx, try_to_lock}; + if (!lock) return false; + taskDeque.back(task); + } + ready.notify_one(); + return true; + } + + void complete() + { + { + lock_guard lock{mtx}; + done = true; + } + ready.notify_all(); + } + + bool pop(Task** task) + { + unique_lock lock{mtx}; + + while (taskDeque.empty() && !done) { + ready.wait(lock); + } + + if (taskDeque.empty()) return false; + + *task = taskDeque.front(); + return true; + } + + void push(Task* task) + { + { + lock_guard lock{mtx}; + taskDeque.back(task); + } + ready.notify_one(); + } +}; struct TaskSchedulerImpl { - TaskSchedulerImpl(unsigned threadCnt) + Array threads; + Array taskQueues; + atomic idx{0}; + + TaskSchedulerImpl(uint32_t threadCnt) { + threads.reserve(threadCnt); + taskQueues.reserve(threadCnt); + + for (uint32_t i = 0; i < threadCnt; ++i) { + taskQueues.push(new TaskQueue); + threads.push(new thread); + } + for (uint32_t i = 0; i < threadCnt; ++i) { + *threads.data[i] = thread([&, i] { run(i); }); + } } ~TaskSchedulerImpl() { + for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) { + (*tq)->complete(); + } + for (auto thread = threads.begin(); thread < threads.end(); ++thread) { + (*thread)->join(); + delete(*thread); + } + for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) { + delete(*tq); + } + } + + void run(unsigned i) + { + Task* task; + + //Thread Loop + while (true) { + auto success = false; + for (uint32_t x = 0; x < threads.count * 2; ++x) { + if (taskQueues[(i + x) % threads.count]->tryPop(&task)) { + success = true; + break; + } + } + + if (!success && !taskQueues[i]->pop(&task)) break; + (*task)(i + 1); + } } void request(Task* task) { - task->run(0); + //Async + if (threads.count > 0 && _async) { + task->prepare(); + auto i = idx++; + for (uint32_t n = 0; n < threads.count; ++n) { + if (taskQueues[(i + n) % threads.count]->tryPush(task)) return; + } + taskQueues[i % threads.count]->push(task); + //Sync + } else { + task->run(0); + } + } + + uint32_t threadCnt() + { + return threads.count; } }; -} +#else //THORVG_THREAD_SUPPORT -static TaskSchedulerImpl* inst = nullptr; +static bool _async = true; + +struct TaskSchedulerImpl +{ + TaskSchedulerImpl(TVG_UNUSED uint32_t threadCnt) {} + void request(Task* task) { task->run(0); } + uint32_t threadCnt() { return 0; } +}; + +#endif //THORVG_THREAD_SUPPORT + +} //namespace /************************************************************************/ /* External Class Implementation */ /************************************************************************/ -void TaskScheduler::init(unsigned threads) +void TaskScheduler::init(uint32_t threads) { if (inst) return; inst = new TaskSchedulerImpl(threads); } + +void TaskScheduler::term() +{ + delete(inst); + inst = nullptr; +} + + void TaskScheduler::request(Task* task) { if (inst) inst->request(task); } + +uint32_t TaskScheduler::threads() +{ + if (inst) return inst->threadCnt(); + return 0; +} + + void TaskScheduler::async(bool on) { + //toggle async tasking for each thread on/off _async = on; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h index 41d6f9bef..af1334b79 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,29 +26,36 @@ #ifndef _TVG_TASK_SCHEDULER_H_ #define _TVG_TASK_SCHEDULER_H_ +#include +#include + #include "tvgCommon.h" +#include "tvgInlist.h" -namespace tvg -{ +namespace tvg { -struct Task; - -struct TaskScheduler -{ - static void init(unsigned threads); - static void request(Task* task); - static void async(bool on); -}; +#ifdef THORVG_THREAD_SUPPORT struct Task { private: + mutex mtx; + condition_variable cv; + bool ready = true; + bool pending = false; public: + INLIST_ITEM(Task); + virtual ~Task() = default; void done() { + if (!pending) return; + + unique_lock lock(mtx); + while (!ready) cv.wait(lock); + pending = false; } protected: @@ -59,19 +66,52 @@ private: { run(tid); + lock_guard lock(mtx); + ready = true; + cv.notify_one(); } void prepare() { + ready = false; + pending = true; } friend struct TaskSchedulerImpl; }; -} +#else //THORVG_THREAD_SUPPORT + +struct Task +{ +public: + INLIST_ITEM(Task); + + virtual ~Task() = default; + void done() {} + +protected: + virtual void run(unsigned tid) = 0; + +private: + friend struct TaskSchedulerImpl; +}; + +#endif //THORVG_THREAD_SUPPORT + + +struct TaskScheduler +{ + static uint32_t threads(); + static void init(uint32_t threads); + static void term(); + static void request(Task* task); + static void async(bool on); +}; + +} //namespace #endif //_TVG_TASK_SCHEDULER_H_ - #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.cpp new file mode 100644 index 000000000..6cb2b4f74 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + + +#include "tvgText.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +Text::Text() : pImpl(new Impl) +{ + Paint::pImpl->id = TVG_CLASS_ID_TEXT; +} + + +Text::~Text() +{ + delete(pImpl); +} + + +Result Text::text(const char* text) noexcept +{ + return pImpl->text(text); +} + + +Result Text::font(const char* name, float size, const char* style) noexcept +{ + return pImpl->font(name, size, style); +} + + +Result Text::load(const std::string& path) noexcept +{ + bool invalid; //invalid path + if (!LoaderMgr::loader(path, &invalid)) { + if (invalid) return Result::InvalidArguments; + else return Result::NonSupport; + } + + return Result::Success; +} + + +Result Text::unload(const std::string& path) noexcept +{ + if (LoaderMgr::retrieve(path)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Text::fill(uint8_t r, uint8_t g, uint8_t b) noexcept +{ + if (!pImpl->paint) return Result::InsufficientCondition; + + return pImpl->fill(r, g, b); +} + + +Result Text::fill(unique_ptr f) noexcept +{ + if (!pImpl->paint) return Result::InsufficientCondition; + + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + return pImpl->fill(p); +} + + +unique_ptr Text::gen() noexcept +{ + return unique_ptr(new Text); +} + + +uint32_t Text::identifier() noexcept +{ + return TVG_CLASS_ID_TEXT; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.h new file mode 100644 index 000000000..89cef1879 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#ifndef _TVG_TEXT_H +#define _TVG_TEXT_H + +#include +#include "tvgShape.h" +#include "tvgFill.h" + +#ifdef THORVG_TTF_LOADER_SUPPORT + #include "tvgTtfLoader.h" +#else + #include "tvgLoader.h" +#endif + +struct Text::Impl +{ + FontLoader* loader = nullptr; + Shape* paint = nullptr; + char* utf8 = nullptr; + float fontSize; + bool italic = false; + bool changed = false; + + ~Impl() + { + free(utf8); + LoaderMgr::retrieve(loader); + delete(paint); + } + + Result fill(uint8_t r, uint8_t g, uint8_t b) + { + return paint->fill(r, g, b); + } + + Result fill(Fill* f) + { + return paint->fill(cast(f)); + } + + Result text(const char* utf8) + { + free(this->utf8); + if (utf8) this->utf8 = strdup(utf8); + else this->utf8 = nullptr; + changed = true; + + return Result::Success; + } + + Result font(const char* name, float size, const char* style) + { + auto loader = LoaderMgr::loader(name); + if (!loader) return Result::InsufficientCondition; + + //Same resource has been loaded. + if (this->loader == loader) { + this->loader->sharing--; //make it sure the reference counting. + return Result::Success; + } else if (this->loader) { + LoaderMgr::retrieve(this->loader); + } + this->loader = static_cast(loader); + + if (!paint) paint = Shape::gen().release(); + + fontSize = size; + if (style && strstr(style, "italic")) italic = true; + changed = true; + return Result::Success; + } + + RenderRegion bounds(RenderMethod* renderer) + { + if (paint) return P(paint)->bounds(renderer); + else return {0, 0, 0, 0}; + } + + bool render(RenderMethod* renderer) + { + if (paint) return PP(paint)->render(renderer); + return false; + } + + bool load() + { + if (!loader) return false; + + //reload + if (changed) { + loader->request(paint, utf8, italic); + loader->read(); + changed = false; + } + if (paint) { + loader->resize(paint, fontSize, fontSize); + return true; + } + return false; + } + + RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + { + if (!load()) return nullptr; + + //transform the gradient coordinates based on the final scaled font. + if (P(paint)->flag & RenderUpdateFlag::Gradient) { + auto fill = P(paint)->rs.fill; + auto scale = 1.0f / loader->scale; + if (fill->identifier() == TVG_CLASS_ID_LINEAR) { + P(static_cast(fill))->x1 *= scale; + P(static_cast(fill))->y1 *= scale; + P(static_cast(fill))->x2 *= scale; + P(static_cast(fill))->y2 *= scale; + } else { + P(static_cast(fill))->cx *= scale; + P(static_cast(fill))->cy *= scale; + P(static_cast(fill))->r *= scale; + P(static_cast(fill))->fx *= scale; + P(static_cast(fill))->fy *= scale; + P(static_cast(fill))->fr *= scale; + } + } + return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); + } + + bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking) + { + if (!load() || !paint) return false; + paint->bounds(x, y, w, h, true); + return true; + } + + Paint* duplicate() + { + load(); + + auto ret = Text::gen().release(); + auto dup = ret->pImpl; + if (paint) dup->paint = static_cast(paint->duplicate()); + + if (loader) { + dup->loader = loader; + ++dup->loader->sharing; + } + + dup->utf8 = strdup(utf8); + dup->italic = italic; + dup->fontSize = fontSize; + + return ret; + } + + Iterator* iterator() + { + return nullptr; + } +}; + + + +#endif //_TVG_TEXT_H + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp new file mode 100644 index 000000000..3bdaec9e4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_THORVG_INTERNAL + +#include "tvgCanvas.h" + +#ifdef THORVG_WG_RASTER_SUPPORT + #include "tvgWgRenderer.h" +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct WgCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_WG_RASTER_SUPPORT +WgCanvas::WgCanvas() : Canvas(WgRenderer::gen()), pImpl(new Impl) +#else +WgCanvas::WgCanvas() : Canvas(nullptr), pImpl(nullptr) +#endif +{ +} + +WgCanvas::~WgCanvas() +{ + delete pImpl; +} + +Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept +{ +#ifdef THORVG_WG_RASTER_SUPPORT + if (!window) return Result::InvalidArguments; + if ((w == 0) || (h == 0)) return Result::InvalidArguments; + + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(window, w, h)) return Result::Unknown; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + +unique_ptr WgCanvas::gen() noexcept +{ +#ifdef THORVG_WG_RASTER_SUPPORT + return unique_ptr(new WgCanvas); +#endif + return nullptr; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp index 6bd35ba81..ffb9b5df4 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -174,10 +174,11 @@ static const char* _simpleXmlFindStartTag(const char* itr, const char* itrEnd) static const char* _simpleXmlFindEndTag(const char* itr, const char* itrEnd) { - bool insideQuote = false; + bool insideQuote[2] = {false, false}; // 0: ", 1: ' for (; itr < itrEnd; itr++) { - if (*itr == '"') insideQuote = !insideQuote; - if (!insideQuote) { + if (*itr == '"' && !insideQuote[1]) insideQuote[0] = !insideQuote[0]; + if (*itr == '\'' && !insideQuote[0]) insideQuote[1] = !insideQuote[1]; + if (!insideQuote[0] && !insideQuote[1]) { if ((*itr == '>') || (*itr == '<')) return itr; } @@ -316,7 +317,10 @@ bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttr if ((*keyEnd == '=') || (isspace((unsigned char)*keyEnd))) break; } if (keyEnd == itrEnd) goto error; - if (keyEnd == key) continue; + if (keyEnd == key) { // There is no key. This case is invalid, but explores the following syntax. + itr = keyEnd + 1; + continue; + } if (*keyEnd == '=') value = keyEnd + 1; else { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.h index e1cf2de2e..be0806860 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,9 +28,9 @@ #include "tvgSvgLoaderCommon.h" -#define NUMBER_OF_XML_ENTITIES 8 -const char* const xmlEntity[] = {""", " ", "'", "&", "<", ">", "#", "'"}; -const int xmlEntityLength[] = {6, 6, 6, 5, 4, 4, 6, 6}; +#define NUMBER_OF_XML_ENTITIES 9 +const char* const xmlEntity[] = {" ", """, " ", "'", "&", "<", ">", "#", "'"}; +const int xmlEntityLength[] = {5, 6, 6, 6, 5, 4, 4, 6, 6}; enum class SimpleXMLType { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.c b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.c index b185d3953..899432707 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.c @@ -8,11 +8,15 @@ *********************/ #include "../../lvgl.h" -#if LV_USE_TINY_TTF +#if LV_USE_TINY_TTF != 0 +#include "../../core/lv_global.h" + +#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers) /********************* * DEFINES *********************/ + #define STB_RECT_PACK_IMPLEMENTATION #define STBRP_STATIC #define STBTT_STATIC @@ -44,10 +48,10 @@ static void ttf_cb_stream_seek(ttf_cb_stream_t * stream, size_t position); #include "stb_rect_pack.h" #include "stb_truetype_htcw.h" -#define tiny_ttf_cache LV_GLOBAL_DEFAULT()->tiny_ttf_cache /********************** * TYPEDEFS **********************/ + typedef struct ttf_font_desc { lv_fs_file_t file; #if LV_TINY_TTF_FILE_SUPPORT != 0 @@ -59,11 +63,22 @@ typedef struct ttf_font_desc { float scale; int ascent; int descent; + + lv_font_kerning_t kerning; + + int cache_size; + lv_cache_t * glyph_cache; + lv_cache_t * draw_data_cache; } ttf_font_desc_t; -typedef struct _tiny_ttf_cache_data_t { - lv_font_t * font; +typedef struct _tiny_ttf_glyph_cache_data_t { uint32_t unicode; + int adv_w; + lv_font_glyph_dsc_t glyph_dsc; +} tiny_ttf_glyph_cache_data_t; + +typedef struct lv_tiny_ttf_cache_data_t { + uint32_t glyph_index; uint32_t size; lv_draw_buf_t * draw_buf; } tiny_ttf_cache_data_t; @@ -72,17 +87,23 @@ typedef struct _tiny_ttf_cache_data_t { **********************/ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next); -static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, - uint32_t unicode_letter, lv_draw_buf_t * draw_buf); +static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc); static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size_t data_size, - int32_t font_size, + int32_t font_size, lv_font_kerning_t kerning, size_t cache_size); -static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data); -static void tiny_ttf_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data); -static lv_cache_compare_res_t tiny_ttf_cache_compare_cb(const tiny_ttf_cache_data_t * lhs, - const tiny_ttf_cache_data_t * rhs); +static bool tiny_ttf_glyph_cache_create_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data); +static void tiny_ttf_glyph_cache_free_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data); +static lv_cache_compare_res_t tiny_ttf_glyph_cache_compare_cb(const tiny_ttf_glyph_cache_data_t * lhs, + const tiny_ttf_glyph_cache_data_t * rhs); + +static bool tiny_ttf_draw_data_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data); +static void tiny_ttf_draw_data_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data); +static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf_cache_data_t * lhs, + const tiny_ttf_cache_data_t * rhs); + +static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc); /********************** * GLOBAL VARIABLES **********************/ @@ -102,7 +123,7 @@ static lv_cache_compare_res_t tiny_ttf_cache_compare_cb(const tiny_ttf_cache_dat void lv_tiny_ttf_set_size(lv_font_t * font, int32_t font_size) { if(font_size <= 0) { - LV_LOG_ERROR("invalid font size: %"PRIx32, font_size); + LV_LOG_ERROR("invalid font size: %"LV_PRIx32, font_size); return; } ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; @@ -111,6 +132,20 @@ void lv_tiny_ttf_set_size(lv_font_t * font, int32_t font_size) stbtt_GetFontVMetrics(&dsc->info, &dsc->ascent, &dsc->descent, &line_gap); font->line_height = (int32_t)(dsc->scale * (dsc->ascent - dsc->descent + line_gap)); font->base_line = (int32_t)(dsc->scale * (line_gap - dsc->descent)); + + /* size change means cache needs to be invalidated. */ + + if(dsc->glyph_cache) { + lv_cache_destroy(dsc->glyph_cache, NULL); + dsc->glyph_cache = NULL; + } + + if(dsc->draw_data_cache) { + lv_cache_destroy(dsc->draw_data_cache, NULL); + dsc->draw_data_cache = NULL; + } + + lv_tiny_ttf_cache_create(dsc); } void lv_tiny_ttf_destroy(lv_font_t * font) @@ -124,7 +159,8 @@ void lv_tiny_ttf_destroy(lv_font_t * font) lv_fs_close(&ttf->file); } #endif - lv_cache_drop_all(tiny_ttf_cache, (void *)font->dsc); + lv_cache_destroy(ttf->glyph_cache, NULL); + lv_cache_destroy(ttf->draw_data_cache, NULL); lv_free(ttf); font->dsc = NULL; } @@ -132,22 +168,6 @@ void lv_tiny_ttf_destroy(lv_font_t * font) lv_free(font); } -void lv_tiny_ttf_init(void) -{ - lv_cache_ops_t ops = { - .compare_cb = (lv_cache_compare_cb_t)tiny_ttf_cache_compare_cb, - .create_cb = (lv_cache_create_cb_t)tiny_ttf_cache_create_cb, - .free_cb = (lv_cache_free_cb_t)tiny_ttf_cache_free_cb, - }; - - tiny_ttf_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(tiny_ttf_cache_data_t), 128, ops); -} - -void lv_tiny_ttf_deinit(void) -{ - lv_cache_destroy(tiny_ttf_cache, NULL); -} - /********************** * STATIC FUNCTIONS **********************/ @@ -198,48 +218,98 @@ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * d dsc_out->is_placeholder = false; return true; } + ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; - int g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter); - if(g1 == 0) { - /* Glyph not found */ + + tiny_ttf_glyph_cache_data_t search_key = { + .unicode = unicode_letter, + }; + + int adv_w; + lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc); + + if(entry == NULL) { + if(!dsc->cache_size) { /* no cache, do everything directly */ + uint32_t g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter); + tiny_ttf_glyph_cache_create_cb(&search_key, dsc); + *dsc_out = search_key.glyph_dsc; + adv_w = search_key.adv_w; + + /*Kerning correction*/ + if(font->kerning == LV_FONT_KERNING_NORMAL && + unicode_letter_next != 0) { + int g2 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter_next); /* not using cache, only do glyph id lookup */ + if(g2) { + int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, g2); + dsc_out->adv_w = (uint16_t)floor((((float)adv_w + (float)k) * dsc->scale) + + 0.5f); /*Horizontal space required by the glyph in [px]*/ + } + } + + dsc_out->entry = NULL; + return true; + } + LV_LOG_ERROR("cache not allocated"); return false; } - int x1, y1, x2, y2; - stbtt_GetGlyphBitmapBox(&dsc->info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2); - int g2 = 0; - if(unicode_letter_next != 0) { - g2 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter_next); + tiny_ttf_glyph_cache_data_t * data = lv_cache_entry_get_data(entry); + *dsc_out = data->glyph_dsc; + adv_w = data->adv_w; + lv_cache_release(dsc->glyph_cache, entry, NULL); + + /*Kerning correction*/ + if(font->kerning == LV_FONT_KERNING_NORMAL && + unicode_letter_next != 0) { /* check if we need to do any kerning calculations */ + uint32_t g1 = dsc_out->gid.index; + + int g2 = 0; + search_key.unicode = unicode_letter_next; /* reuse search key */ + lv_cache_entry_t * entry_next = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc); + + if(entry_next == NULL) + g2 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter_next); + else { + tiny_ttf_glyph_cache_data_t * data_next = lv_cache_entry_get_data(entry_next); + g2 = data_next->glyph_dsc.gid.index; + lv_cache_release(dsc->glyph_cache, entry_next, NULL); + } + + if(g2) { + int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, g2); + dsc_out->adv_w = (uint16_t)floor((((float)adv_w + (float)k) * dsc->scale) + + 0.5f); /*Horizontal space required by the glyph in [px]*/ + } } - int advw, lsb; - stbtt_GetGlyphHMetrics(&dsc->info, g1, &advw, &lsb); - int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, g2); - dsc_out->adv_w = (uint16_t)floor((((float)advw + (float)k) * dsc->scale) + - 0.5f); /*Horizontal space required by the glyph in [px]*/ - dsc_out->box_w = (x2 - x1 + 1); /*width of the bitmap in [px]*/ - dsc_out->box_h = (y2 - y1 + 1); /*height of the bitmap in [px]*/ - dsc_out->ofs_x = x1; /*X offset of the bitmap in [pf]*/ - dsc_out->ofs_y = -y2; /*Y offset of the bitmap measured from the as line*/ - dsc_out->format = LV_FONT_GLYPH_FORMAT_A8; - dsc_out->is_placeholder = false; + + dsc_out->entry = NULL; return true; /*true: glyph found; false: glyph was not found*/ } -static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, - uint32_t unicode_letter, lv_draw_buf_t * draw_buf) +static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) { LV_UNUSED(draw_buf); + uint32_t glyph_index = g_dsc->gid.index; const lv_font_t * font = g_dsc->resolved_font; + ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; tiny_ttf_cache_data_t search_key = { - .font = (lv_font_t *)font, - .unicode = unicode_letter, + .glyph_index = glyph_index, .size = font->line_height, }; - lv_cache_entry_t * entry = lv_cache_acquire_or_create(tiny_ttf_cache, &search_key, (void *)font->dsc); - + lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->draw_data_cache, &search_key, (void *)font->dsc); if(entry == NULL) { - LV_LOG_ERROR("cache not allocated\n"); + if(!dsc->cache_size) { /* no cache, do everything directly */ + if(tiny_ttf_draw_data_cache_create_cb(&search_key, (void *)font->dsc)) { + /* use the cache entry to store the buffer if no cache specified */ + g_dsc->entry = (lv_cache_entry_t *)search_key.draw_buf; + return g_dsc->entry; + } + else { + return NULL; + } + } + LV_LOG_ERROR("cache not allocated"); return NULL; } @@ -251,25 +321,51 @@ static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc) { LV_ASSERT_NULL(font); - if(g_dsc->entry == NULL) { - return; + + ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; + if(!dsc->cache_size) { /* no cache, do everything directly */ + lv_draw_buf_destroy_user(font_draw_buf_handlers, (lv_draw_buf_t *)g_dsc->entry); + } + else { + if(g_dsc->entry == NULL) { + return; + } + lv_cache_release(dsc->draw_data_cache, g_dsc->entry, NULL); } - lv_cache_release(tiny_ttf_cache, g_dsc->entry, NULL); g_dsc->entry = NULL; } +static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc) +{ + /*Init cache*/ + dsc->glyph_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(tiny_ttf_glyph_cache_data_t), dsc->cache_size, + (lv_cache_ops_t) { + .compare_cb = (lv_cache_compare_cb_t)tiny_ttf_glyph_cache_compare_cb, + .create_cb = (lv_cache_create_cb_t)tiny_ttf_glyph_cache_create_cb, + .free_cb = (lv_cache_free_cb_t)tiny_ttf_glyph_cache_free_cb + }); + lv_cache_set_name(dsc->glyph_cache, "TINY_TTF_GLYPH"); + + dsc->draw_data_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(tiny_ttf_cache_data_t), dsc->cache_size, + (lv_cache_ops_t) { + .compare_cb = (lv_cache_compare_cb_t)tiny_ttf_draw_data_cache_compare_cb, + .create_cb = (lv_cache_create_cb_t)tiny_ttf_draw_data_cache_create_cb, + .free_cb = (lv_cache_free_cb_t)tiny_ttf_draw_data_cache_free_cb, + }); + lv_cache_set_name(dsc->draw_data_cache, "TINY_TTF_DRAW_DATA"); +} + static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size_t data_size, int32_t font_size, - size_t cache_size) + lv_font_kerning_t kerning, size_t cache_size) { LV_UNUSED(data_size); - LV_UNUSED(cache_size); if((path == NULL && data == NULL) || 0 >= font_size) { - LV_LOG_ERROR("tiny_ttf: invalid argument\n"); + LV_LOG_ERROR("tiny_ttf: invalid argument"); return NULL; } ttf_font_desc_t * dsc = lv_malloc_zeroed(sizeof(ttf_font_desc_t)); if(dsc == NULL) { - LV_LOG_ERROR("tiny_ttf: out of memory\n"); + LV_LOG_ERROR("tiny_ttf: out of memory"); return NULL; } #if LV_TINY_TTF_FILE_SUPPORT != 0 @@ -287,7 +383,7 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size } if(0 == stbtt_InitFont(&dsc->info, &dsc->stream, stbtt_GetFontOffsetForIndex(&dsc->stream, 0))) { lv_free(dsc); - LV_LOG_ERROR("tiny_ttf: init failed\n"); + LV_LOG_ERROR("tiny_ttf: init failed"); return NULL; } @@ -295,17 +391,28 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size dsc->stream = (const uint8_t *)data; if(0 == stbtt_InitFont(&dsc->info, dsc->stream, stbtt_GetFontOffsetForIndex(dsc->stream, 0))) { lv_free(dsc); - LV_LOG_ERROR("tiny_ttf: init failed\n"); + LV_LOG_ERROR("tiny_ttf: init failed"); return NULL; } #endif + dsc->cache_size = cache_size; + lv_font_t * out_font = lv_malloc_zeroed(sizeof(lv_font_t)); if(out_font == NULL) { lv_free(dsc); - LV_LOG_ERROR("tiny_ttf: out of memory\n"); + LV_LOG_ERROR("tiny_ttf: out of memory"); return NULL; } + + /* check if font has kerning tables to use, else disable kerning automatically. */ + if(stbtt_KernTableCheck(&dsc->info) == 0) { + kerning = LV_FONT_KERNING_NONE; /* disable kerning if font has no tables. */ + } + + dsc->kerning = kerning; + out_font->kerning = kerning; + out_font->get_glyph_dsc = ttf_get_glyph_dsc_cb; out_font->get_glyph_bitmap = ttf_get_glyph_bitmap_cb; out_font->release_glyph = ttf_release_glyph_cb; @@ -314,48 +421,107 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size return out_font; } #if LV_TINY_TTF_FILE_SUPPORT != 0 -lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, size_t cache_size) +lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, lv_font_kerning_t kerning, + size_t cache_size) { - return lv_tiny_ttf_create(path, NULL, 0, font_size, cache_size); + return lv_tiny_ttf_create(path, NULL, 0, font_size, kerning, cache_size); } lv_font_t * lv_tiny_ttf_create_file(const char * path, int32_t font_size) { - return lv_tiny_ttf_create(path, NULL, 0, font_size, 0); + return lv_tiny_ttf_create(path, NULL, 0, font_size, LV_FONT_KERNING_NORMAL, LV_TINY_TTF_CACHE_GLYPH_CNT); } #endif -lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size, size_t cache_size) + +lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size, + lv_font_kerning_t kerning, size_t cache_size) { - return lv_tiny_ttf_create(NULL, data, data_size, font_size, cache_size); + return lv_tiny_ttf_create(NULL, data, data_size, font_size, kerning, cache_size); } lv_font_t * lv_tiny_ttf_create_data(const void * data, size_t data_size, int32_t font_size) { - return lv_tiny_ttf_create(NULL, data, data_size, font_size, 0); + return lv_tiny_ttf_create(NULL, data, data_size, font_size, LV_FONT_KERNING_NORMAL, LV_TINY_TTF_CACHE_GLYPH_CNT); } /*----------------- * Cache Callbacks *----------------*/ -static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data) +static bool tiny_ttf_glyph_cache_create_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data) { - ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data; + lv_font_glyph_dsc_t * dsc_out = &node->glyph_dsc; + uint32_t unicode_letter = node->unicode; - const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info; - int g1 = stbtt_FindGlyphIndex(info, (int)unicode_letter); + int g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter); if(g1 == 0) { /* Glyph not found */ return false; } int x1, y1, x2, y2; + + stbtt_GetGlyphBitmapBox(&dsc->info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2); + + int advw, lsb; + stbtt_GetGlyphHMetrics(&dsc->info, g1, &advw, &lsb); + if(dsc->kerning != LV_FONT_KERNING_NORMAL) { /* calculate default advance */ + int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, 0); + dsc_out->adv_w = (uint16_t)floor((((float)advw + (float)k) * dsc->scale) + + 0.5f); /*Horizontal space required by the glyph in [px]*/ + } + else { + dsc_out->adv_w = (uint16_t)floor(((float)advw * dsc->scale) + + 0.5f); /*Horizontal space required by the glyph in [px]*/; + } + /* precalculate no kerning value */ + node->adv_w = advw; + dsc_out->box_w = (x2 - x1 + 1); /*width of the bitmap in [px]*/ + dsc_out->box_h = (y2 - y1 + 1); /*height of the bitmap in [px]*/ + dsc_out->ofs_x = x1; /*X offset of the bitmap in [pf]*/ + dsc_out->ofs_y = -y2; /*Y offset of the bitmap measured from the as line*/ + dsc_out->format = LV_FONT_GLYPH_FORMAT_A8; + dsc_out->is_placeholder = false; + dsc_out->gid.index = (uint32_t)g1; + + return true; +} + +static void tiny_ttf_glyph_cache_free_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data) +{ + LV_UNUSED(node); + LV_UNUSED(user_data); +} + +static lv_cache_compare_res_t tiny_ttf_glyph_cache_compare_cb(const tiny_ttf_glyph_cache_data_t * lhs, + const tiny_ttf_glyph_cache_data_t * rhs) +{ + if(lhs->unicode != rhs->unicode) { + return lhs->unicode > rhs->unicode ? 1 : -1; + } + + return 0; +} + +static bool tiny_ttf_draw_data_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data) +{ + int g1 = (int)node->glyph_index; + if(g1 == 0) { + /* Glyph not found */ + return false; + } + + ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data; + + const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info; + int x1, y1, x2, y2; stbtt_GetGlyphBitmapBox(info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2); int w, h; w = x2 - x1 + 1; h = y2 - y1 + 1; - lv_draw_buf_t * draw_buf = lv_draw_buf_create(w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO); + + lv_draw_buf_t * draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO); if(NULL == draw_buf) { - LV_LOG_ERROR("tiny_ttf: out of memory\n"); + LV_LOG_ERROR("tiny_ttf: out of memory"); return false; } @@ -368,22 +534,18 @@ static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_d return true; } -static void tiny_ttf_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data) +static void tiny_ttf_draw_data_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data) { LV_UNUSED(user_data); lv_draw_buf_destroy(node->draw_buf); } -static lv_cache_compare_res_t tiny_ttf_cache_compare_cb(const tiny_ttf_cache_data_t * lhs, - const tiny_ttf_cache_data_t * rhs) +static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf_cache_data_t * lhs, + const tiny_ttf_cache_data_t * rhs) { - if(lhs->font != rhs->font) { - return lhs->font > rhs->font ? 1 : -1; - } - - if(lhs->unicode != rhs->unicode) { - return lhs->unicode > rhs->unicode ? 1 : -1; + if(lhs->glyph_index != rhs->glyph_index) { + return lhs->glyph_index > rhs->glyph_index ? 1 : -1; } if(lhs->size != rhs->size) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.h b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.h index 2966ade76..b6e7dc0a8 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/lv_tiny_ttf.h @@ -29,28 +29,60 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -#if LV_TINY_TTF_FILE_SUPPORT !=0 -/* create a font from the specified file or path with the specified line height.*/ +#if LV_TINY_TTF_FILE_SUPPORT != 0 +/** + * Create a font from the specified file or path with the specified line height. + * @param path the path or file name of the font + * @param font_size the font size in pixel + * @return a font object + */ lv_font_t * lv_tiny_ttf_create_file(const char * path, int32_t font_size); -/* create a font from the specified file or path with the specified line height with the specified cache size.*/ -lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, size_t cache_size); +/** + * Create a font from the specified file or path with the specified line height with the specified cache size. + * @param path the path or file name of the font + * @param font_size the font size in pixel + * @param kerning kerning value in pixel + * @param cache_size the cache size in count + * @return a font object + */ +lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, lv_font_kerning_t kerning, + size_t cache_size); #endif -void lv_tiny_ttf_init(void); - -void lv_tiny_ttf_deinit(void); - -/* create a font from the specified data pointer with the specified line height.*/ +/** + * Create a font from the specified data pointer with the specified line height. + * @param data the data pointer + * @param data_size the data size + * @param font_size the font size in pixel + * @return a font object + */ lv_font_t * lv_tiny_ttf_create_data(const void * data, size_t data_size, int32_t font_size); -/* create a font from the specified data pointer with the specified line height and the specified cache size.*/ -lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size, size_t cache_size); +/** + * Create a font from the specified data pointer with the specified line height and the specified cache size. + * @param data the data pointer + * @param data_size the data size + * @param font_size the font size in pixel + * @param kerning kerning value in pixel + * @param cache_size the cache size in count + * @return + */ +lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size, + lv_font_kerning_t kerning, size_t cache_size); -/* set the size of the font to a new font_size*/ +/** + * Set the size of the font to a new font_size + * @note the font bitmap cache and glyph cache will be flushed. + * @param font the font object + * @param font_size the font size in pixel + */ void lv_tiny_ttf_set_size(lv_font_t * font, int32_t font_size); -/* destroy a font previously created with lv_tiny_ttf_create_xxxx()*/ +/** + * Destroy a font previously created with lv_tiny_ttf_create_xxxx() + * @param font the font object + */ void lv_tiny_ttf_destroy(lv_font_t * font); /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_rect_pack.h b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_rect_pack.h index b265df907..b4c8b4d0b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_rect_pack.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_rect_pack.h @@ -469,7 +469,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context * context, // insert the new node into the right starting point, and // let 'cur' point to the remaining nodes needing to be - // stiched back in + // stitched back in cur = *res.prev_link; if(cur->x < res.x) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_truetype_htcw.h b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_truetype_htcw.h index e91997b4b..1cd3e2abe 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_truetype_htcw.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/stb_truetype_htcw.h @@ -912,7 +912,7 @@ STBTT_DEF unsigned char * stbtt_GetCodepointBitmap(const stbtt_fontinfo * info, STBTT_DEF unsigned char * stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int * width, int * height, int * xoff, int * yoff); -// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel +// the same as stbtt_GetCodepointBitmap, but you can specify a subpixel // shift for the character STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h, @@ -2854,7 +2854,47 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo * info, i } } } + return 0; +} +STBTT_DEF int stbtt_KernTableCheck(const stbtt_fontinfo * info) +{ + if(info->gpos) { + stbtt_uint16 lookupListOffset; + stbtt_uint32 lookupList; + stbtt_uint16 lookupCount; +#ifdef STBTT_STREAM_TYPE + STBTT_STREAM_TYPE data = info->data; +#else + const stbtt_uint8 * data = info->data; +#endif + stbtt_int32 i; + + if(!info->gpos) return 0; + + if(ttUSHORT(data, 0 + info->gpos) != 1) return 0; // Major version 1 + if(ttUSHORT(data, 2 + info->gpos) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data, 8 + info->gpos); + lookupList = lookupListOffset; + lookupCount = ttUSHORT(data, lookupList); + + for(i = 0; i < lookupCount; ++i) { + stbtt_uint16 lookupOffset = ttUSHORT(data, lookupList + 2 + 2 * i); + stbtt_uint32 lookupTable = lookupList + lookupOffset; + + stbtt_uint16 lookupType = ttUSHORT(data, lookupTable); + + if(lookupType != 2) // Pair Adjustment Positioning Subtable + continue; + + return 1; // we have a usable lookup table. + } + return 0; + } + else if(info->kern) { + return 1; + } return 0; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/lv_tjpgd.c b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/lv_tjpgd.c index 2185c2828..650b36ad6 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/lv_tjpgd.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/lv_tjpgd.c @@ -7,16 +7,21 @@ * INCLUDES *********************/ +#include "../../draw/lv_image_decoder_private.h" #include "../../../lvgl.h" #if LV_USE_TJPGD #include "tjpgd.h" #include "lv_tjpgd.h" -#include "../../misc/lv_fs.h" +#include "../../misc/lv_fs_private.h" +#include /********************* * DEFINES *********************/ + +#define DECODER_NAME "TJPGD" + #define TJPGD_WORKBUFF_SIZE 4096 //Recommended by TJPGD library /********************** @@ -26,7 +31,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header); +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, @@ -54,6 +59,8 @@ void lv_tjpgd_init(void) lv_image_decoder_set_open_cb(dec, decoder_open); lv_image_decoder_set_get_area_cb(dec, decoder_get_area); lv_image_decoder_set_close_cb(dec, decoder_close); + + dec->name = DECODER_NAME; } void lv_tjpgd_deinit(void) @@ -71,11 +78,12 @@ void lv_tjpgd_deinit(void) * STATIC FUNCTIONS **********************/ -static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, lv_image_header_t * header) +static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { LV_UNUSED(decoder); - lv_image_src_t src_type = lv_image_src_get_type(src); + const void * src = dsc->src; + lv_image_src_t src_type = dsc->src_type; if(src_type == LV_IMAGE_SRC_VARIABLE) { const lv_image_dsc_t * img_dsc = src; @@ -97,18 +105,13 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, } else if(src_type == LV_IMAGE_SRC_FILE) { const char * fn = src; - if((lv_strcmp(lv_fs_get_ext(fn), "jpg") == 0) || (lv_strcmp(lv_fs_get_ext(fn), "jpeg") == 0)) { - lv_fs_file_t f; - lv_fs_res_t res; - res = lv_fs_open(&f, fn, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) return LV_RESULT_INVALID; - + const char * ext = lv_fs_get_ext(fn); + if((lv_strcmp(ext, "jpg") == 0) || (lv_strcmp(ext, "jpeg") == 0)) { uint8_t workb[TJPGD_WORKBUFF_SIZE]; JDEC jd; - JRESULT rc = jd_prepare(&jd, input_func, workb, TJPGD_WORKBUFF_SIZE, &f); + JRESULT rc = jd_prepare(&jd, input_func, workb, TJPGD_WORKBUFF_SIZE, &dsc->file); if(rc) { LV_LOG_WARN("jd_prepare error: %d", rc); - lv_fs_close(&f); return LV_RESULT_INVALID; } header->cf = LV_COLOR_FORMAT_RAW; @@ -116,7 +119,6 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, const void * src, header->h = jd.height; header->stride = jd.width * 3; - lv_fs_close(&f); return LV_RESULT_OK; } } @@ -186,7 +188,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d JDEC * jd = lv_malloc(sizeof(JDEC)); dsc->user_data = jd; JRESULT rc = jd_prepare(jd, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, f); - if(rc) return rc; + if(rc) return LV_RESULT_INVALID; dsc->header.cf = LV_COLOR_FORMAT_RGB888; dsc->header.w = jd->width; @@ -210,8 +212,6 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod JDEC * jd = dsc->user_data; lv_draw_buf_t * decoded = (void *)dsc->decoded; - if(decoded == NULL) decoded = lv_malloc_zeroed(sizeof(lv_draw_buf_t)); - dsc->decoded = decoded; uint32_t mx, my; mx = jd->msx * 8; @@ -219,15 +219,23 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod if(decoded_area->y1 == LV_COORD_MIN) { decoded_area->y1 = 0; decoded_area->y2 = my - 1; - decoded_area->x1 = -mx; + decoded_area->x1 = -((int32_t)mx); decoded_area->x2 = -1; jd->scale = 0; jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */ jd->rst = 0; jd->rsc = 0; + if(decoded == NULL) { + decoded = lv_malloc_zeroed(sizeof(lv_draw_buf_t)); + dsc->decoded = decoded; + } + else { + lv_fs_seek(jd->device, 0, LV_FS_SEEK_SET); + JRESULT rc = jd_prepare(jd, input_func, jd->pool_original, (size_t)TJPGD_WORKBUFF_SIZE, jd->device); + if(rc) return LV_RESULT_INVALID; + } decoded->data = jd->workbuf; decoded->header = dsc->header; - decoded->header.stride = mx * 3; } decoded_area->x1 += mx; @@ -240,25 +248,29 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod decoded_area->y2 += my; } - decoded->header.w = mx; - decoded->header.h = my; + if(decoded_area->x2 >= jd->width) decoded_area->x2 = jd->width - 1; + if(decoded_area->y2 >= jd->height) decoded_area->y2 = jd->height - 1; + + decoded->header.w = lv_area_get_width(decoded_area); + decoded->header.h = lv_area_get_height(decoded_area); + decoded->header.stride = decoded->header.w * 3; decoded->data_size = decoded->header.stride * decoded->header.h; /* Process restart interval if enabled */ JRESULT rc; if(jd->nrst && jd->rst++ == jd->nrst) { rc = jd_restart(jd, jd->rsc++); - if(rc != JDR_OK) return rc; + if(rc != JDR_OK) return LV_RESULT_INVALID; jd->rst = 1; } /* Load an MCU (decompress huffman coded stream, dequantize and apply IDCT) */ rc = jd_mcu_load(jd); - if(rc != JDR_OK) return rc; + if(rc != JDR_OK) return LV_RESULT_INVALID; /* Output the MCU (YCbCr to RGB, scaling and output) */ rc = jd_mcu_output(jd, NULL, decoded_area->x1, decoded_area->y1); - if(rc != JDR_OK) return rc; + if(rc != JDR_OK) return LV_RESULT_INVALID; return LV_RESULT_OK; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.c b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.c index 63f4915d5..7152adf17 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.c @@ -24,9 +24,9 @@ / Some performance improvement. /----------------------------------------------------------------------------*/ -#ifndef TASMOTA // has tjpegd in ROM #include "tjpgd.h" +#if LV_USE_TJPGD #if JD_FASTDECODE == 2 #define HUFF_BIT 10 /* Bit length to apply fast huffman decode */ @@ -316,7 +316,7 @@ static int huffext( /* >=0: decoded data, <0: error code */ dc--; /* Decrement number of available bytes */ if(flg) { /* In flag sequence? */ flg = 0; /* Exit flag sequence */ - if(*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */ + if(*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be corrupted data) */ *dp = 0xFF; /* The flag is a data 0xFF */ } else { @@ -426,7 +426,7 @@ static int huffext( /* >=0: decoded data, <0: error code */ } #endif - return 0 - (int)JDR_FMT1; /* Err: code not found (may be collapted data) */ + return 0 - (int)JDR_FMT1; /* Err: code not found (may be corrupted data) */ } @@ -462,7 +462,7 @@ static int bitext( /* >=0: extracted data, <0: error code */ dc--; /* Decrement number of available bytes */ if(flg) { /* In flag sequence? */ flg = 0; /* Exit flag sequence */ - if(*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */ + if(*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be corrupted data) */ *dp = 0xFF; /* The flag is a data 0xFF */ } else { @@ -534,7 +534,7 @@ static int bitext( /* >=0: extracted data, <0: error code */ JRESULT jd_restart( JDEC * jd, /* Pointer to the decompressor object */ - uint16_t rstn /* Expected restert sequence number */ + uint16_t rstn /* Expected restart sequence number */ ) { unsigned int i; @@ -563,7 +563,7 @@ JRESULT jd_restart( /* Check the marker */ if((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7)) { - return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be collapted data) */ + return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be corrupted data) */ } #else @@ -591,7 +591,7 @@ JRESULT jd_restart( /* Check the marker */ if((marker & 0xFFD8) != 0xFFD0 || (marker & 7) != (rstn & 7)) { - return JDR_FMT1; /* Err: expected RSTn marker was not detected (may be collapted data) */ + return JDR_FMT1; /* Err: expected RSTn marker was not detected (may be corrupted data) */ } jd->dbit = 0; /* Discard stuff bits */ @@ -892,7 +892,7 @@ JRESULT jd_mcu_output( /* Squeeze up pixel table if a part of MCU is to be truncated */ mx >>= jd->scale; - if(rx < mx) { /* Is the MCU spans rigit edge? */ + if(rx < mx) { /* Is the MCU spans right edge? */ uint8_t * s, * d; unsigned int xi, yi; @@ -940,7 +940,7 @@ JRESULT jd_mcu_output( JRESULT jd_prepare( JDEC * jd, /* Blank decompressor object */ - size_t (*infunc)(JDEC *, uint8_t *, size_t), /* JPEG strem input function */ + size_t (*infunc)(JDEC *, uint8_t *, size_t), /* JPEG stream input function */ void * pool, /* Working buffer for the decompression session */ size_t sz_pool, /* Size of working buffer */ void * dev /* I/O device identifier for the session */ @@ -977,7 +977,7 @@ JRESULT jd_prepare( marker = LDB_WORD(seg); /* Marker */ len = LDB_WORD(seg + 2); /* Length field */ if(len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1; - len -= 2; /* Segent content size */ + len -= 2; /* Segment content size */ ofs += 4 + len; /* Number of bytes loaded */ switch(marker & 0xFF) { @@ -1023,7 +1023,7 @@ JRESULT jd_prepare( if(rc) return rc; break; - case 0xDB: /* DQT - Define Quaitizer Tables */ + case 0xDB: /* DQT - Define Quantizer Tables */ if(len > JD_SZBUF) return JDR_MEM2; if(jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */ @@ -1044,7 +1044,7 @@ JRESULT jd_prepare( if(b != 0x00 && b != 0x11) return JDR_FMT3; /* Err: Different table number for DC/AC element */ n = i ? 1 : 0; /* Component class */ if(!jd->huffbits[n][0] || !jd->huffbits[n][1]) { /* Check huffman table for this component */ - return JDR_FMT1; /* Err: Nnot loaded */ + return JDR_FMT1; /* Err: Not loaded */ } if(!jd->qttbl[jd->qtid[i]]) { /* Check dequantizer table for this component */ return JDR_FMT1; /* Err: Not loaded */ @@ -1083,7 +1083,7 @@ JRESULT jd_prepare( case 0xCE: /* SOF14 */ case 0xCF: /* SOF15 */ case 0xD9: /* EOI */ - return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */ + return JDR_FMT3; /* Unsupported JPEG standard (may be progressive JPEG) */ default: /* Unknown segment (comment, exif or etc..) */ /* Skip segment data (null pointer specifies to remove data from the stream) */ @@ -1136,5 +1136,4 @@ JRESULT jd_decomp( return rc; } -#endif // TASMOTA - +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.h b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.h index 7c0b91a00..887038a2b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/tjpgd.h @@ -1,7 +1,6 @@ /*----------------------------------------------------------------------------/ / TJpgDec - Tiny JPEG Decompressor R0.03 include file (C)ChaN, 2021 /----------------------------------------------------------------------------*/ -#ifndef TASMOTA // has tjpegd in ROM #ifndef DEF_TJPGDEC #define DEF_TJPGDEC @@ -9,7 +8,11 @@ extern "C" { #endif +#include "../../lv_conf_internal.h" #include "tjpgdcnf.h" + +#if LV_USE_TJPGD + #include #include @@ -96,10 +99,10 @@ JRESULT jd_mcu_output(JDEC * jd, int (*outfunc)(JDEC *, void *, JRECT *), unsign JRESULT jd_restart(JDEC * jd, uint16_t rstn); +#endif #ifdef __cplusplus } #endif #endif /* _TJPGDEC */ -#endif // TASMOTA diff --git a/lib/libesp32_lvgl/lvgl/src/lv_api_map_v8.h b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v8.h index 0b6da1ba1..822450f57 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_api_map_v8.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v8.h @@ -29,6 +29,7 @@ extern "C" { #define LV_DISP_RENDER_MODE_DIRECT LV_DISPLAY_RENDER_MODE_DIRECT #define LV_DISP_RENDER_MODE_FULL LV_DISPLAY_RENDER_MODE_FULL +#if LV_USE_BUTTONMATRIX #define LV_BTNMATRIX_BTN_NONE LV_BUTTONMATRIX_BUTTON_NONE #define LV_BTNMATRIX_CTRL_HIDDEN LV_BUTTONMATRIX_CTRL_HIDDEN @@ -40,6 +41,7 @@ extern "C" { #define LV_BTNMATRIX_CTRL_POPOVER LV_BUTTONMATRIX_CTRL_POPOVER #define LV_BTNMATRIX_CTRL_CUSTOM_1 LV_BUTTONMATRIX_CTRL_CUSTOM_1 #define LV_BTNMATRIX_CTRL_CUSTOM_2 LV_BUTTONMATRIX_CTRL_CUSTOM_2 +#endif /* LV_USE_BUTTONMATRIX */ /********************** * TYPEDEFS @@ -52,7 +54,19 @@ typedef lv_display_rotation_t lv_disp_rotation_t; typedef lv_display_render_mode_t lv_disp_render_t; typedef lv_anim_completed_cb_t lv_anim_ready_cb_t; typedef lv_screen_load_anim_t lv_scr_load_anim_t; + +#if LV_USE_BUTTONMATRIX typedef lv_buttonmatrix_ctrl_t lv_btnmatrix_ctrl_t; +#endif /* LV_USE_BUTTONMATRIX */ + +#if LV_USE_IMAGEBUTTON +#define LV_IMGBTN_STATE_RELEASED LV_IMAGEBUTTON_STATE_RELEASED +#define LV_IMGBTN_STATE_PRESSED LV_IMAGEBUTTON_STATE_PRESSED +#define LV_IMGBTN_STATE_DISABLED LV_IMAGEBUTTON_STATE_DISABLED +#define LV_IMGBTN_STATE_CHECKED_RELEASED LV_IMAGEBUTTON_STATE_CHECKED_RELEASED +#define LV_IMGBTN_STATE_CHECKED_PRESSED LV_IMAGEBUTTON_STATE_CHECKED_PRESSED +#define LV_IMGBTN_STATE_CHECKED_DISABLED LV_IMAGEBUTTON_STATE_CHECKED_DISABLED +#endif /* LV_USE_IMAGEBUTTON */ /********************** * GLOBAL PROTOTYPES @@ -138,8 +152,8 @@ static inline void lv_obj_move_background(lv_obj_t * obj) #define lv_disp_trig_activity lv_display_trigger_activity #define lv_disp_enable_invalidation lv_display_enable_invalidation #define lv_disp_is_invalidation_enabled lv_display_is_invalidation_enabled -#define _lv_disp_refr_timer _lv_display_refr_timer -#define _lv_disp_get_refr_timer lv_display_get_refr_timer +#define lv_disp_refr_timer lv_display_refr_timer +#define lv_disp_get_refr_timer lv_display_get_refr_timer #define lv_timer_del lv_timer_delete @@ -149,9 +163,12 @@ static inline void lv_obj_move_background(lv_obj_t * obj) #define lv_group_del lv_group_delete +#if LV_USE_TEXTAREA #define lv_txt_get_size lv_text_get_size #define lv_txt_get_width lv_text_get_width +#endif /* LV_USE_TEXTAREA */ +#if LV_USE_IMAGE #define lv_img_create lv_image_create #define lv_img_set_src lv_image_set_src #define lv_img_set_offset_x lv_image_set_offset_x @@ -167,13 +184,28 @@ static inline void lv_obj_move_background(lv_obj_t * obj) #define lv_img_get_pivot lv_image_get_pivot #define lv_img_get_zoom lv_image_get_scale #define lv_img_get_antialias lv_image_get_antialias +#endif /* LV_USE_IMAGE */ +#if LV_USE_IMAGEBUTTON +#define lv_imgbtn_create lv_imagebutton_create +#define lv_imgbtn_set_src lv_imagebutton_set_src +#define lv_imgbtn_set_state lv_imagebutton_set_state +#define lv_imgbtn_get_src_left lv_imagebutton_get_src_left +#define lv_imgbtn_get_src_middle lv_imagebutton_get_src_middle +#define lv_imgbtn_get_src_right lv_imagebutton_get_src_right +#endif /* LV_USE_IMAGEBUTTON */ + +#if LV_USE_LIST #define lv_list_set_btn_text lv_list_set_button_text #define lv_list_get_btn_text lv_list_get_button_text #define lv_list_add_btn lv_list_add_button +#endif /* LV_USE_LIST */ +#if LV_USE_BUTTON #define lv_btn_create lv_button_create +#endif /* LV_USE_BUTTON */ +#if LV_USE_BUTTONMATRIX #define lv_btnmatrix_create lv_buttonmatrix_create #define lv_btnmatrix_set_map lv_buttonmatrix_set_map #define lv_btnmatrix_set_ctrl_map lv_buttonmatrix_set_ctrl_map @@ -189,26 +221,37 @@ static inline void lv_obj_move_background(lv_obj_t * obj) #define lv_btnmatrix_get_btn_text lv_buttonmatrix_get_button_text #define lv_btnmatrix_has_button_ctrl lv_buttonmatrix_has_button_ctrl #define lv_btnmatrix_get_one_checked lv_buttonmatrix_get_one_checked +#endif /* LV_USE_BUTTONMATRIX */ +#if LV_USE_TABVIEW #define lv_tabview_get_tab_btns lv_tabview_get_tab_bar #define lv_tabview_get_tab_act lv_tabview_get_tab_active #define lv_tabview_set_act lv_tabview_set_active +#endif /* LV_USE_TABVIEW */ +#if LV_USE_TILEVIEW #define lv_tileview_get_tile_act lv_tileview_get_tile_active #define lv_obj_set_tile_id lv_tileview_set_tile_by_index #define lv_obj_set_tile lv_tileview_set_tile +#endif /* LV_USE_TILEVIEW */ +#if LV_USE_ROLLER #define lv_roller_set_visible_row_cnt lv_roller_set_visible_row_count #define lv_roller_get_option_cnt lv_roller_get_option_count +#endif /* LV_USE_ROLLER */ +#if LV_USE_TABLE #define lv_table_set_col_cnt lv_table_set_column_count #define lv_table_set_row_cnt lv_table_set_row_count #define lv_table_get_col_cnt lv_table_get_column_count #define lv_table_get_row_cnt lv_table_get_row_count #define lv_table_set_col_width lv_table_set_column_width #define lv_table_get_col_width lv_table_get_column_width +#endif /* LV_USE_TABLE */ +#if LV_USE_DROPDOWN #define lv_dropdown_get_option_cnt lv_dropdown_get_option_count +#endif /* LV_USE_DROPDOWN */ #define lv_obj_get_child_cnt lv_obj_get_child_count #define lv_obj_get_disp lv_obj_get_display @@ -258,6 +301,11 @@ static inline void lv_obj_move_background(lv_obj_t * obj) #define lv_style_set_bg_img_recolor lv_style_set_bg_image_recolor #define lv_style_set_bg_img_recolor_opa lv_style_set_bg_image_recolor_opa +#if LV_USE_KEYBOARD +#define lv_keyboard_get_selected_btn lv_keyboard_get_selected_button +#define lv_keyboard_get_btn_text lv_keyboard_get_button_text +#endif /* LV_USE_KEYBOARD */ + #define LV_ZOOM_NONE LV_SCALE_NONE #define lv_image_decoder_built_in_open lv_bin_decoder_open diff --git a/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_0.h b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_0.h index 3992844e9..b0d22cdf5 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_0.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_0.h @@ -37,6 +37,20 @@ extern "C" { #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE #endif +#define lv_button_bind_checked lv_obj_bind_checked + +#define LV_DRAW_BUF_DEFINE LV_DRAW_BUF_DEFINE_STATIC + +#define _lv_utils_bsearch lv_utils_bsearch +#define lv_draw_buf_align_user lv_draw_buf_align_ex +#define lv_draw_buf_create_user lv_draw_buf_create_ex +#define lv_draw_buf_width_to_stride_user lv_draw_buf_width_to_stride_ex +#define lv_draw_buf_dup_user lv_draw_buf_dup_ex + +#define lv_draw_buf_invalidate_cache_user(handlers, drawbuf, area) lv_draw_buf_invalidate_cache(drawbuf, area) +#define lv_draw_buf_flush_cache_user(handlers, drawbuf, area) lv_draw_buf_flush_cache(drawbuf, area) +#define lv_draw_buf_destroy_user(handlers, drawbuf) lv_draw_buf_destroy(drawbuf) + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h new file mode 100644 index 000000000..3264b9abe --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h @@ -0,0 +1,98 @@ +/** + * @file lv_api_map_v9_1.h + * + */ + +#ifndef LV_API_MAP_V9_1_H +#define LV_API_MAP_V9_1_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * MACROS + **********************/ + +#define _LV_EVENT_LAST LV_EVENT_LAST +#define _lv_obj_t lv_obj_t +#define _lv_obj_class_t lv_obj_class_t +#define _lv_event_t lv_event_t +#define _lv_event_code_t lv_event_code_t +#define _lv_event_mark_deleted lv_event_mark_deleted +#define lv_obj_add_event lv_obj_add_event_cb + +#define _lv_anim_t lv_anim_t + +#define _LV_STYLE_LAST_BUILT_IN_PROP LV_STYLE_LAST_BUILT_IN_PROP +#define _LV_FLEX_REVERSE LV_FLEX_REVERSE +#define _LV_FLEX_WRAP LV_FLEX_WRAP +#define _LV_FLEX_COLUMN LV_FLEX_COLUMN + +#define _lv_area_is_equal lv_area_is_equal +#define _lv_area_is_in lv_area_is_in +#define _lv_area_intersect lv_area_intersect +#define _lv_area_is_point_on lv_area_is_point_on +#define _lv_area_join lv_area_join +#define _lv_image_buf_get_transformed_area lv_image_buf_get_transformed_area + +#define _lv_ll_init lv_ll_init +#define _lv_ll_ins_head lv_ll_ins_head +#define _lv_ll_ins_prev lv_ll_ins_prev +#define _lv_ll_ins_tail lv_ll_ins_tail +#define _lv_ll_get_head lv_ll_get_head +#define _lv_ll_get_tail lv_ll_get_tail +#define _lv_ll_get_next lv_ll_get_next +#define _lv_ll_get_prev lv_ll_get_prev +#define _lv_ll_get_len lv_ll_get_len +#define _lv_ll_move_before lv_ll_move_before +#define _lv_ll_is_empty lv_ll_is_empty +#define _lv_ll_clear lv_ll_clear +#define _lv_ll_remove lv_ll_remove +#define _lv_ll_chg_list lv_ll_chg_list +#define _LV_LL_READ LV_LL_READ +#define _LV_LL_READ_BACK LV_LL_READ_BACK + +#define _lv_obj_scroll_by_raw lv_obj_scroll_by_raw +#define _lv_obj_get_ext_draw_size lv_obj_get_ext_draw_size +#define _lv_indev_scroll_handler lv_indev_scroll_handler + +#define _lv_display_t lv_display_t +#define _lv_display_refr_timer lv_disp_refr_timer +#define _lv_disp_refr_timer lv_disp_refr_timer +#define _lv_disp_get_refr_timer lv_disp_get_refr_timer + +#define _lv_timer_t lv_timer_t + +#define _lv_inv_area lv_inv_area + +/********************** + * DEPRECATED FUNCTIONS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_API_MAP_V9_0_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h b/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h index d6d7fd0d8..5cebb73f1 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h @@ -15,6 +15,7 @@ #define LV_OS_CMSIS_RTOS2 3 #define LV_OS_RTTHREAD 4 #define LV_OS_WINDOWS 5 +#define LV_OS_MQX 6 #define LV_OS_CUSTOM 255 #define LV_STDLIB_BUILTIN 0 @@ -46,7 +47,7 @@ #endif /*If lv_conf.h is not skipped include it*/ -#ifndef LV_CONF_SKIP +#if !defined(LV_CONF_SKIP) || defined(LV_CONF_PATH) #ifdef LV_CONF_PATH /*If there is a path defined for lv_conf.h use it*/ #define __LV_TO_STR_AUX(x) #x #define __LV_TO_STR(x) __LV_TO_STR_AUX(x) @@ -66,7 +67,7 @@ #endif #ifdef CONFIG_LV_COLOR_DEPTH - #define _LV_KCONFIG_PRESENT + #define LV_KCONFIG_PRESENT #endif /*---------------------------------- @@ -82,7 +83,7 @@ COLOR SETTINGS *====================*/ -/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ #ifndef LV_COLOR_DEPTH #ifdef CONFIG_LV_COLOR_DEPTH #define LV_COLOR_DEPTH CONFIG_LV_COLOR_DEPTH @@ -124,6 +125,48 @@ #endif #endif +#ifndef LV_STDINT_INCLUDE + #ifdef CONFIG_LV_STDINT_INCLUDE + #define LV_STDINT_INCLUDE CONFIG_LV_STDINT_INCLUDE + #else + #define LV_STDINT_INCLUDE + #endif +#endif +#ifndef LV_STDDEF_INCLUDE + #ifdef CONFIG_LV_STDDEF_INCLUDE + #define LV_STDDEF_INCLUDE CONFIG_LV_STDDEF_INCLUDE + #else + #define LV_STDDEF_INCLUDE + #endif +#endif +#ifndef LV_STDBOOL_INCLUDE + #ifdef CONFIG_LV_STDBOOL_INCLUDE + #define LV_STDBOOL_INCLUDE CONFIG_LV_STDBOOL_INCLUDE + #else + #define LV_STDBOOL_INCLUDE + #endif +#endif +#ifndef LV_INTTYPES_INCLUDE + #ifdef CONFIG_LV_INTTYPES_INCLUDE + #define LV_INTTYPES_INCLUDE CONFIG_LV_INTTYPES_INCLUDE + #else + #define LV_INTTYPES_INCLUDE + #endif +#endif +#ifndef LV_LIMITS_INCLUDE + #ifdef CONFIG_LV_LIMITS_INCLUDE + #define LV_LIMITS_INCLUDE CONFIG_LV_LIMITS_INCLUDE + #else + #define LV_LIMITS_INCLUDE + #endif +#endif +#ifndef LV_STDARG_INCLUDE + #ifdef CONFIG_LV_STDARG_INCLUDE + #define LV_STDARG_INCLUDE CONFIG_LV_STDARG_INCLUDE + #else + #define LV_STDARG_INCLUDE + #endif +#endif #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ @@ -204,6 +247,7 @@ * - LV_OS_CMSIS_RTOS2 * - LV_OS_RTTHREAD * - LV_OS_WINDOWS + * - LV_OS_MQX * - LV_OS_CUSTOM */ #ifndef LV_USE_OS #ifdef CONFIG_LV_USE_OS @@ -229,7 +273,7 @@ /*Align the stride of all layers and images to this bytes*/ #ifndef LV_DRAW_BUF_STRIDE_ALIGN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_DRAW_BUF_STRIDE_ALIGN #define LV_DRAW_BUF_STRIDE_ALIGN CONFIG_LV_DRAW_BUF_STRIDE_ALIGN #else @@ -249,6 +293,18 @@ #endif #endif +/*Using matrix for transformations. + *Requirements: + `LV_USE_MATRIX = 1`. + The rendering engine needs to support 3x3 matrix transformations.*/ +#ifndef LV_DRAW_TRANSFORM_USE_MATRIX + #ifdef CONFIG_LV_DRAW_TRANSFORM_USE_MATRIX + #define LV_DRAW_TRANSFORM_USE_MATRIX CONFIG_LV_DRAW_TRANSFORM_USE_MATRIX + #else + #define LV_DRAW_TRANSFORM_USE_MATRIX 0 + #endif +#endif + /* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers @@ -263,8 +319,19 @@ #endif #endif +/* The stack size of the drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#ifndef LV_DRAW_THREAD_STACK_SIZE + #ifdef CONFIG_LV_DRAW_THREAD_STACK_SIZE + #define LV_DRAW_THREAD_STACK_SIZE CONFIG_LV_DRAW_THREAD_STACK_SIZE + #else + #define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /*[bytes]*/ + #endif +#endif + #ifndef LV_USE_DRAW_SW - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_DRAW_SW #define LV_USE_DRAW_SW CONFIG_LV_USE_DRAW_SW #else @@ -275,11 +342,119 @@ #endif #endif #if LV_USE_DRAW_SW == 1 - /* Set the number of draw unit. + + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ + + #ifndef LV_DRAW_SW_SUPPORT_RGB565 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB565 + #define LV_DRAW_SW_SUPPORT_RGB565 CONFIG_LV_DRAW_SW_SUPPORT_RGB565 + #else + #define LV_DRAW_SW_SUPPORT_RGB565 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB565 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_RGB565A8 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB565A8 + #define LV_DRAW_SW_SUPPORT_RGB565A8 CONFIG_LV_DRAW_SW_SUPPORT_RGB565A8 + #else + #define LV_DRAW_SW_SUPPORT_RGB565A8 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB565A8 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_RGB888 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB888 + #define LV_DRAW_SW_SUPPORT_RGB888 CONFIG_LV_DRAW_SW_SUPPORT_RGB888 + #else + #define LV_DRAW_SW_SUPPORT_RGB888 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_XRGB8888 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_XRGB8888 + #define LV_DRAW_SW_SUPPORT_XRGB8888 CONFIG_LV_DRAW_SW_SUPPORT_XRGB8888 + #else + #define LV_DRAW_SW_SUPPORT_XRGB8888 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_XRGB8888 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_ARGB8888 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_ARGB8888 + #define LV_DRAW_SW_SUPPORT_ARGB8888 CONFIG_LV_DRAW_SW_SUPPORT_ARGB8888 + #else + #define LV_DRAW_SW_SUPPORT_ARGB8888 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_L8 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_L8 + #define LV_DRAW_SW_SUPPORT_L8 CONFIG_LV_DRAW_SW_SUPPORT_L8 + #else + #define LV_DRAW_SW_SUPPORT_L8 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_L8 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_AL88 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_AL88 + #define LV_DRAW_SW_SUPPORT_AL88 CONFIG_LV_DRAW_SW_SUPPORT_AL88 + #else + #define LV_DRAW_SW_SUPPORT_AL88 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_AL88 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_A8 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_A8 + #define LV_DRAW_SW_SUPPORT_A8 CONFIG_LV_DRAW_SW_SUPPORT_A8 + #else + #define LV_DRAW_SW_SUPPORT_A8 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_A8 1 + #endif + #endif + #ifndef LV_DRAW_SW_SUPPORT_I1 + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_I1 + #define LV_DRAW_SW_SUPPORT_I1 CONFIG_LV_DRAW_SW_SUPPORT_I1 + #else + #define LV_DRAW_SW_SUPPORT_I1 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_I1 1 + #endif + #endif + + /* Set the number of draw unit. * > 1 requires an operating system enabled in `LV_USE_OS` - * > 1 means multiply threads will render the screen in parallel */ + * > 1 means multiple threads will render the screen in parallel */ #ifndef LV_DRAW_SW_DRAW_UNIT_CNT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_DRAW_SW_DRAW_UNIT_CNT #define LV_DRAW_SW_DRAW_UNIT_CNT CONFIG_LV_DRAW_SW_DRAW_UNIT_CNT #else @@ -307,11 +482,11 @@ #define LV_USE_NATIVE_HELIUM_ASM 0 #endif #endif - + /* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only * 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */ #ifndef LV_DRAW_SW_COMPLEX - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_DRAW_SW_COMPLEX #define LV_DRAW_SW_COMPLEX CONFIG_LV_DRAW_SW_COMPLEX #else @@ -364,6 +539,15 @@ #endif #endif #endif + + /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + #ifndef LV_USE_DRAW_SW_COMPLEX_GRADIENTS + #ifdef CONFIG_LV_USE_DRAW_SW_COMPLEX_GRADIENTS + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS CONFIG_LV_USE_DRAW_SW_COMPLEX_GRADIENTS + #else + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 + #endif + #endif #endif /* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ @@ -386,16 +570,31 @@ #endif #if LV_USE_OS - /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ - #ifndef LV_USE_VGLITE_DRAW_ASYNC - #ifdef _LV_KCONFIG_PRESENT - #ifdef CONFIG_LV_USE_VGLITE_DRAW_ASYNC - #define LV_USE_VGLITE_DRAW_ASYNC CONFIG_LV_USE_VGLITE_DRAW_ASYNC + /* Use additional draw thread for VG-Lite processing.*/ + #ifndef LV_USE_VGLITE_DRAW_THREAD + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_VGLITE_DRAW_THREAD + #define LV_USE_VGLITE_DRAW_THREAD CONFIG_LV_USE_VGLITE_DRAW_THREAD #else - #define LV_USE_VGLITE_DRAW_ASYNC 0 + #define LV_USE_VGLITE_DRAW_THREAD 0 #endif #else - #define LV_USE_VGLITE_DRAW_ASYNC 1 + #define LV_USE_VGLITE_DRAW_THREAD 1 + #endif + #endif + + #if LV_USE_VGLITE_DRAW_THREAD + /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ + #ifndef LV_USE_VGLITE_DRAW_ASYNC + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_VGLITE_DRAW_ASYNC + #define LV_USE_VGLITE_DRAW_ASYNC CONFIG_LV_USE_VGLITE_DRAW_ASYNC + #else + #define LV_USE_VGLITE_DRAW_ASYNC 0 + #endif + #else + #define LV_USE_VGLITE_DRAW_ASYNC 1 + #endif #endif #endif #endif @@ -420,6 +619,21 @@ #endif #if LV_USE_DRAW_PXP + #if LV_USE_OS + /* Use additional draw thread for PXP processing.*/ + #ifndef LV_USE_PXP_DRAW_THREAD + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_PXP_DRAW_THREAD + #define LV_USE_PXP_DRAW_THREAD CONFIG_LV_USE_PXP_DRAW_THREAD + #else + #define LV_USE_PXP_DRAW_THREAD 0 + #endif + #else + #define LV_USE_PXP_DRAW_THREAD 1 + #endif + #endif + #endif + /* Enable PXP asserts. */ #ifndef LV_USE_PXP_ASSERT #ifdef CONFIG_LV_USE_PXP_ASSERT @@ -458,54 +672,64 @@ #endif #if LV_USE_DRAW_VG_LITE -/* Enable VG-Lite custom external 'gpu_init()' function */ -#ifndef LV_VG_LITE_USE_GPU_INIT - #ifdef CONFIG_LV_VG_LITE_USE_GPU_INIT - #define LV_VG_LITE_USE_GPU_INIT CONFIG_LV_VG_LITE_USE_GPU_INIT - #else - #define LV_VG_LITE_USE_GPU_INIT 0 + /* Enable VG-Lite custom external 'gpu_init()' function */ + #ifndef LV_VG_LITE_USE_GPU_INIT + #ifdef CONFIG_LV_VG_LITE_USE_GPU_INIT + #define LV_VG_LITE_USE_GPU_INIT CONFIG_LV_VG_LITE_USE_GPU_INIT + #else + #define LV_VG_LITE_USE_GPU_INIT 0 + #endif #endif -#endif -/* Enable VG-Lite assert. */ -#ifndef LV_VG_LITE_USE_ASSERT - #ifdef CONFIG_LV_VG_LITE_USE_ASSERT - #define LV_VG_LITE_USE_ASSERT CONFIG_LV_VG_LITE_USE_ASSERT - #else - #define LV_VG_LITE_USE_ASSERT 0 + /* Enable VG-Lite assert. */ + #ifndef LV_VG_LITE_USE_ASSERT + #ifdef CONFIG_LV_VG_LITE_USE_ASSERT + #define LV_VG_LITE_USE_ASSERT CONFIG_LV_VG_LITE_USE_ASSERT + #else + #define LV_VG_LITE_USE_ASSERT 0 + #endif #endif -#endif -/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ -#ifndef LV_VG_LITE_FLUSH_MAX_COUNT - #ifdef CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT - #define LV_VG_LITE_FLUSH_MAX_COUNT CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT - #else - #define LV_VG_LITE_FLUSH_MAX_COUNT 8 + /* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ + #ifndef LV_VG_LITE_FLUSH_MAX_COUNT + #ifdef CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT + #define LV_VG_LITE_FLUSH_MAX_COUNT CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT + #else + #define LV_VG_LITE_FLUSH_MAX_COUNT 8 + #endif #endif -#endif -/* Enable border to simulate shadow - * NOTE: which usually improves performance, - * but does not guarantee the same rendering quality as the software. */ -#ifndef LV_VG_LITE_USE_BOX_SHADOW - #ifdef CONFIG_LV_VG_LITE_USE_BOX_SHADOW - #define LV_VG_LITE_USE_BOX_SHADOW CONFIG_LV_VG_LITE_USE_BOX_SHADOW - #else - #define LV_VG_LITE_USE_BOX_SHADOW 0 + /* Enable border to simulate shadow + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ + #ifndef LV_VG_LITE_USE_BOX_SHADOW + #ifdef CONFIG_LV_VG_LITE_USE_BOX_SHADOW + #define LV_VG_LITE_USE_BOX_SHADOW CONFIG_LV_VG_LITE_USE_BOX_SHADOW + #else + #define LV_VG_LITE_USE_BOX_SHADOW 0 + #endif #endif -#endif -/* VG-Lite gradient image maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ -#ifndef LV_VG_LITE_GRAD_CACHE_SIZE - #ifdef CONFIG_LV_VG_LITE_GRAD_CACHE_SIZE - #define LV_VG_LITE_GRAD_CACHE_SIZE CONFIG_LV_VG_LITE_GRAD_CACHE_SIZE - #else - #define LV_VG_LITE_GRAD_CACHE_SIZE 32 + /* VG-Lite gradient maximum cache number. + * NOTE: The memory usage of a single gradient image is 4K bytes. + */ + #ifndef LV_VG_LITE_GRAD_CACHE_CNT + #ifdef CONFIG_LV_VG_LITE_GRAD_CACHE_CNT + #define LV_VG_LITE_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_GRAD_CACHE_CNT + #else + #define LV_VG_LITE_GRAD_CACHE_CNT 32 + #endif + #endif + + /* VG-Lite stroke maximum cache number. + */ + #ifndef LV_VG_LITE_STROKE_CACHE_CNT + #ifdef CONFIG_LV_VG_LITE_STROKE_CACHE_CNT + #define LV_VG_LITE_STROKE_CACHE_CNT CONFIG_LV_VG_LITE_STROKE_CACHE_CNT + #else + #define LV_VG_LITE_STROKE_CACHE_CNT 32 + #endif #endif -#endif #endif @@ -552,10 +776,15 @@ #endif #endif + /*Set callback to print the logs. + *E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)` + *Can be overwritten by `lv_log_register_print_cb`*/ + //#define LV_LOG_PRINT_CB + /*1: Enable print timestamp; *0: Disable print timestamp*/ #ifndef LV_LOG_USE_TIMESTAMP - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_USE_TIMESTAMP #define LV_LOG_USE_TIMESTAMP CONFIG_LV_LOG_USE_TIMESTAMP #else @@ -569,7 +798,7 @@ /*1: Print file and line number of the log; *0: Do not print file and line number of the log*/ #ifndef LV_LOG_USE_FILE_LINE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_USE_FILE_LINE #define LV_LOG_USE_FILE_LINE CONFIG_LV_LOG_USE_FILE_LINE #else @@ -580,9 +809,10 @@ #endif #endif + /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ #ifndef LV_LOG_TRACE_MEM - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_MEM #define LV_LOG_TRACE_MEM CONFIG_LV_LOG_TRACE_MEM #else @@ -593,7 +823,7 @@ #endif #endif #ifndef LV_LOG_TRACE_TIMER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_TIMER #define LV_LOG_TRACE_TIMER CONFIG_LV_LOG_TRACE_TIMER #else @@ -604,7 +834,7 @@ #endif #endif #ifndef LV_LOG_TRACE_INDEV - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_INDEV #define LV_LOG_TRACE_INDEV CONFIG_LV_LOG_TRACE_INDEV #else @@ -615,7 +845,7 @@ #endif #endif #ifndef LV_LOG_TRACE_DISP_REFR - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_DISP_REFR #define LV_LOG_TRACE_DISP_REFR CONFIG_LV_LOG_TRACE_DISP_REFR #else @@ -626,7 +856,7 @@ #endif #endif #ifndef LV_LOG_TRACE_EVENT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_EVENT #define LV_LOG_TRACE_EVENT CONFIG_LV_LOG_TRACE_EVENT #else @@ -637,7 +867,7 @@ #endif #endif #ifndef LV_LOG_TRACE_OBJ_CREATE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_OBJ_CREATE #define LV_LOG_TRACE_OBJ_CREATE CONFIG_LV_LOG_TRACE_OBJ_CREATE #else @@ -648,7 +878,7 @@ #endif #endif #ifndef LV_LOG_TRACE_LAYOUT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_LAYOUT #define LV_LOG_TRACE_LAYOUT CONFIG_LV_LOG_TRACE_LAYOUT #else @@ -659,7 +889,7 @@ #endif #endif #ifndef LV_LOG_TRACE_ANIM - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_ANIM #define LV_LOG_TRACE_ANIM CONFIG_LV_LOG_TRACE_ANIM #else @@ -670,7 +900,7 @@ #endif #endif #ifndef LV_LOG_TRACE_CACHE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_CACHE #define LV_LOG_TRACE_CACHE CONFIG_LV_LOG_TRACE_CACHE #else @@ -690,7 +920,7 @@ /*Enable asserts if an operation is failed or an invalid data is found. *If LV_USE_LOG is enabled an error message will be printed on failure*/ #ifndef LV_USE_ASSERT_NULL - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_ASSERT_NULL #define LV_USE_ASSERT_NULL CONFIG_LV_USE_ASSERT_NULL #else @@ -701,7 +931,7 @@ #endif #endif #ifndef LV_USE_ASSERT_MALLOC - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_ASSERT_MALLOC #define LV_USE_ASSERT_MALLOC CONFIG_LV_USE_ASSERT_MALLOC #else @@ -864,12 +1094,30 @@ #endif #endif -/* Use lvgl builtin method for obj ID */ -#ifndef LV_USE_OBJ_ID_BUILTIN - #ifdef CONFIG_LV_USE_OBJ_ID_BUILTIN - #define LV_USE_OBJ_ID_BUILTIN CONFIG_LV_USE_OBJ_ID_BUILTIN +/* Automatically assign an ID when obj is created */ +#ifndef LV_OBJ_ID_AUTO_ASSIGN + #ifdef CONFIG_LV_OBJ_ID_AUTO_ASSIGN + #define LV_OBJ_ID_AUTO_ASSIGN CONFIG_LV_OBJ_ID_AUTO_ASSIGN #else - #define LV_USE_OBJ_ID_BUILTIN 0 + #define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + #endif +#endif + +/*Use the builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return e.g. "button3" +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#ifndef LV_USE_OBJ_ID_BUILTIN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OBJ_ID_BUILTIN + #define LV_USE_OBJ_ID_BUILTIN CONFIG_LV_USE_OBJ_ID_BUILTIN + #else + #define LV_USE_OBJ_ID_BUILTIN 0 + #endif + #else + #define LV_USE_OBJ_ID_BUILTIN 1 #endif #endif @@ -882,6 +1130,19 @@ #endif #endif +/*Enable property name support*/ +#ifndef LV_USE_OBJ_PROPERTY_NAME + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OBJ_PROPERTY_NAME + #define LV_USE_OBJ_PROPERTY_NAME CONFIG_LV_USE_OBJ_PROPERTY_NAME + #else + #define LV_USE_OBJ_PROPERTY_NAME 0 + #endif + #else + #define LV_USE_OBJ_PROPERTY_NAME 1 + #endif +#endif + /* VG-Lite Simulator */ /*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ #ifndef LV_USE_VG_LITE_THORVG @@ -912,9 +1173,18 @@ #endif #endif + /*Enable Linear gradient extension support*/ + #ifndef LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #else + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + #endif + #endif + /*Enable 16 pixels alignment*/ #ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN #define LV_VG_LITE_THORVG_16PIXELS_ALIGN CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN #else @@ -987,7 +1257,7 @@ /*Required alignment size for buffers*/ #ifndef LV_ATTRIBUTE_MEM_ALIGN_SIZE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE #define LV_ATTRIBUTE_MEM_ALIGN_SIZE CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE #else @@ -1036,7 +1306,7 @@ #endif /*Export integer constant to binding. This macro is used with constants in the form of LV_ that - *should also appear on LVGL binding API such as Micropython.*/ + *should also appear on LVGL binding API such as MicroPython.*/ #ifndef LV_EXPORT_CONST_INT #ifdef CONFIG_LV_EXPORT_CONST_INT #define LV_EXPORT_CONST_INT CONFIG_LV_EXPORT_CONST_INT @@ -1063,6 +1333,25 @@ #endif #endif +/*Enable matrix support + *Requires `LV_USE_FLOAT = 1`*/ +#ifndef LV_USE_MATRIX + #ifdef CONFIG_LV_USE_MATRIX + #define LV_USE_MATRIX CONFIG_LV_USE_MATRIX + #else + #define LV_USE_MATRIX 0 + #endif +#endif + +/*Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default*/ +#ifndef LV_USE_PRIVATE_API + #ifdef CONFIG_LV_USE_PRIVATE_API + #define LV_USE_PRIVATE_API CONFIG_LV_USE_PRIVATE_API + #else + #define LV_USE_PRIVATE_API 0 + #endif +#endif + /*================== * FONT USAGE *===================*/ @@ -1091,7 +1380,7 @@ #endif #endif #ifndef LV_FONT_MONTSERRAT_14 - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_FONT_MONTSERRAT_14 #define LV_FONT_MONTSERRAT_14 CONFIG_LV_FONT_MONTSERRAT_14 #else @@ -1236,6 +1525,13 @@ #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ #endif #endif +#ifndef LV_FONT_SIMSUN_14_CJK + #ifdef CONFIG_LV_FONT_SIMSUN_14_CJK + #define LV_FONT_SIMSUN_14_CJK CONFIG_LV_FONT_SIMSUN_14_CJK + #else + #define LV_FONT_SIMSUN_14_CJK 0 /*1000 most common CJK radicals*/ + #endif +#endif #ifndef LV_FONT_SIMSUN_16_CJK #ifdef CONFIG_LV_FONT_SIMSUN_16_CJK #define LV_FONT_SIMSUN_16_CJK CONFIG_LV_FONT_SIMSUN_16_CJK @@ -1302,7 +1598,7 @@ /*Enable drawing placeholders when glyph dsc is not found*/ #ifndef LV_USE_FONT_PLACEHOLDER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_FONT_PLACEHOLDER #define LV_USE_FONT_PLACEHOLDER CONFIG_LV_USE_FONT_PLACEHOLDER #else @@ -1395,7 +1691,7 @@ #endif /*Enable Arabic/Persian processing - *In these languages characters should be replaced with an other form based on their position in the text*/ + *In these languages characters should be replaced with another form based on their position in the text*/ #ifndef LV_USE_ARABIC_PERSIAN_CHARS #ifdef CONFIG_LV_USE_ARABIC_PERSIAN_CHARS #define LV_USE_ARABIC_PERSIAN_CHARS CONFIG_LV_USE_ARABIC_PERSIAN_CHARS @@ -1411,7 +1707,7 @@ /*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ #ifndef LV_WIDGETS_HAS_DEFAULT_VALUE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_WIDGETS_HAS_DEFAULT_VALUE #define LV_WIDGETS_HAS_DEFAULT_VALUE CONFIG_LV_WIDGETS_HAS_DEFAULT_VALUE #else @@ -1423,7 +1719,7 @@ #endif #ifndef LV_USE_ANIMIMG - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_ANIMIMG #define LV_USE_ANIMIMG CONFIG_LV_USE_ANIMIMG #else @@ -1435,7 +1731,7 @@ #endif #ifndef LV_USE_ARC - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_ARC #define LV_USE_ARC CONFIG_LV_USE_ARC #else @@ -1447,7 +1743,7 @@ #endif #ifndef LV_USE_BAR - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_BAR #define LV_USE_BAR CONFIG_LV_USE_BAR #else @@ -1459,7 +1755,7 @@ #endif #ifndef LV_USE_BUTTON - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_BUTTON #define LV_USE_BUTTON CONFIG_LV_USE_BUTTON #else @@ -1471,7 +1767,7 @@ #endif #ifndef LV_USE_BUTTONMATRIX - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_BUTTONMATRIX #define LV_USE_BUTTONMATRIX CONFIG_LV_USE_BUTTONMATRIX #else @@ -1483,7 +1779,7 @@ #endif #ifndef LV_USE_CALENDAR - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_CALENDAR #define LV_USE_CALENDAR CONFIG_LV_USE_CALENDAR #else @@ -1527,7 +1823,7 @@ #endif #endif #ifndef LV_USE_CALENDAR_HEADER_ARROW - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_CALENDAR_HEADER_ARROW #define LV_USE_CALENDAR_HEADER_ARROW CONFIG_LV_USE_CALENDAR_HEADER_ARROW #else @@ -1538,7 +1834,7 @@ #endif #endif #ifndef LV_USE_CALENDAR_HEADER_DROPDOWN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN #define LV_USE_CALENDAR_HEADER_DROPDOWN CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN #else @@ -1548,10 +1844,17 @@ #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 #endif #endif + #ifndef LV_USE_CALENDAR_CHINESE + #ifdef CONFIG_LV_USE_CALENDAR_CHINESE + #define LV_USE_CALENDAR_CHINESE CONFIG_LV_USE_CALENDAR_CHINESE + #else + #define LV_USE_CALENDAR_CHINESE 0 + #endif + #endif #endif /*LV_USE_CALENDAR*/ #ifndef LV_USE_CANVAS - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_CANVAS #define LV_USE_CANVAS CONFIG_LV_USE_CANVAS #else @@ -1563,7 +1866,7 @@ #endif #ifndef LV_USE_CHART - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_CHART #define LV_USE_CHART CONFIG_LV_USE_CHART #else @@ -1575,7 +1878,7 @@ #endif #ifndef LV_USE_CHECKBOX - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_CHECKBOX #define LV_USE_CHECKBOX CONFIG_LV_USE_CHECKBOX #else @@ -1587,7 +1890,7 @@ #endif #ifndef LV_USE_DROPDOWN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_DROPDOWN #define LV_USE_DROPDOWN CONFIG_LV_USE_DROPDOWN #else @@ -1599,7 +1902,7 @@ #endif #ifndef LV_USE_IMAGE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_IMAGE #define LV_USE_IMAGE CONFIG_LV_USE_IMAGE #else @@ -1611,7 +1914,7 @@ #endif #ifndef LV_USE_IMAGEBUTTON - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_IMAGEBUTTON #define LV_USE_IMAGEBUTTON CONFIG_LV_USE_IMAGEBUTTON #else @@ -1623,7 +1926,7 @@ #endif #ifndef LV_USE_KEYBOARD - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_KEYBOARD #define LV_USE_KEYBOARD CONFIG_LV_USE_KEYBOARD #else @@ -1635,7 +1938,7 @@ #endif #ifndef LV_USE_LABEL - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_LABEL #define LV_USE_LABEL CONFIG_LV_USE_LABEL #else @@ -1647,7 +1950,7 @@ #endif #if LV_USE_LABEL #ifndef LV_LABEL_TEXT_SELECTION - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LABEL_TEXT_SELECTION #define LV_LABEL_TEXT_SELECTION CONFIG_LV_LABEL_TEXT_SELECTION #else @@ -1658,7 +1961,7 @@ #endif #endif #ifndef LV_LABEL_LONG_TXT_HINT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LABEL_LONG_TXT_HINT #define LV_LABEL_LONG_TXT_HINT CONFIG_LV_LABEL_LONG_TXT_HINT #else @@ -1678,7 +1981,7 @@ #endif #ifndef LV_USE_LED - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_LED #define LV_USE_LED CONFIG_LV_USE_LED #else @@ -1690,7 +1993,7 @@ #endif #ifndef LV_USE_LINE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_LINE #define LV_USE_LINE CONFIG_LV_USE_LINE #else @@ -1702,7 +2005,7 @@ #endif #ifndef LV_USE_LIST - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_LIST #define LV_USE_LIST CONFIG_LV_USE_LIST #else @@ -1713,8 +2016,16 @@ #endif #endif +#ifndef LV_USE_LOTTIE + #ifdef CONFIG_LV_USE_LOTTIE + #define LV_USE_LOTTIE CONFIG_LV_USE_LOTTIE + #else + #define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ + #endif +#endif + #ifndef LV_USE_MENU - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_MENU #define LV_USE_MENU CONFIG_LV_USE_MENU #else @@ -1726,7 +2037,7 @@ #endif #ifndef LV_USE_MSGBOX - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_MSGBOX #define LV_USE_MSGBOX CONFIG_LV_USE_MSGBOX #else @@ -1738,7 +2049,7 @@ #endif #ifndef LV_USE_ROLLER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_ROLLER #define LV_USE_ROLLER CONFIG_LV_USE_ROLLER #else @@ -1750,7 +2061,7 @@ #endif #ifndef LV_USE_SCALE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_SCALE #define LV_USE_SCALE CONFIG_LV_USE_SCALE #else @@ -1762,7 +2073,7 @@ #endif #ifndef LV_USE_SLIDER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_SLIDER #define LV_USE_SLIDER CONFIG_LV_USE_SLIDER #else @@ -1774,7 +2085,7 @@ #endif #ifndef LV_USE_SPAN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_SPAN #define LV_USE_SPAN CONFIG_LV_USE_SPAN #else @@ -1796,7 +2107,7 @@ #endif #ifndef LV_USE_SPINBOX - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_SPINBOX #define LV_USE_SPINBOX CONFIG_LV_USE_SPINBOX #else @@ -1808,7 +2119,7 @@ #endif #ifndef LV_USE_SPINNER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_SPINNER #define LV_USE_SPINNER CONFIG_LV_USE_SPINNER #else @@ -1820,7 +2131,7 @@ #endif #ifndef LV_USE_SWITCH - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_SWITCH #define LV_USE_SWITCH CONFIG_LV_USE_SWITCH #else @@ -1832,7 +2143,7 @@ #endif #ifndef LV_USE_TEXTAREA - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_TEXTAREA #define LV_USE_TEXTAREA CONFIG_LV_USE_TEXTAREA #else @@ -1853,7 +2164,7 @@ #endif #ifndef LV_USE_TABLE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_TABLE #define LV_USE_TABLE CONFIG_LV_USE_TABLE #else @@ -1865,7 +2176,7 @@ #endif #ifndef LV_USE_TABVIEW - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_TABVIEW #define LV_USE_TABVIEW CONFIG_LV_USE_TABVIEW #else @@ -1877,7 +2188,7 @@ #endif #ifndef LV_USE_TILEVIEW - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_TILEVIEW #define LV_USE_TILEVIEW CONFIG_LV_USE_TILEVIEW #else @@ -1889,7 +2200,7 @@ #endif #ifndef LV_USE_WIN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_WIN #define LV_USE_WIN CONFIG_LV_USE_WIN #else @@ -1906,7 +2217,7 @@ /*A simple, impressive and very complete theme*/ #ifndef LV_USE_THEME_DEFAULT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_THEME_DEFAULT #define LV_USE_THEME_DEFAULT CONFIG_LV_USE_THEME_DEFAULT #else @@ -1929,7 +2240,7 @@ /*1: Enable grow on press*/ #ifndef LV_THEME_DEFAULT_GROW - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_THEME_DEFAULT_GROW #define LV_THEME_DEFAULT_GROW CONFIG_LV_THEME_DEFAULT_GROW #else @@ -1952,7 +2263,7 @@ /*A very simple theme that is a good starting point for a custom theme*/ #ifndef LV_USE_THEME_SIMPLE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_THEME_SIMPLE #define LV_USE_THEME_SIMPLE CONFIG_LV_USE_THEME_SIMPLE #else @@ -1965,7 +2276,7 @@ /*A theme designed for monochrome displays*/ #ifndef LV_USE_THEME_MONO - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_THEME_MONO #define LV_USE_THEME_MONO CONFIG_LV_USE_THEME_MONO #else @@ -1982,7 +2293,7 @@ /*A layout similar to Flexbox in CSS.*/ #ifndef LV_USE_FLEX - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_FLEX #define LV_USE_FLEX CONFIG_LV_USE_FLEX #else @@ -1995,7 +2306,7 @@ /*A layout similar to Grid in CSS.*/ #ifndef LV_USE_GRID - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_GRID #define LV_USE_GRID CONFIG_LV_USE_GRID #else @@ -2012,6 +2323,15 @@ /*File system interfaces for common APIs */ +/*Setting a default driver letter allows skipping the driver prefix in filepaths*/ +#ifndef LV_FS_DEFAULT_DRIVE_LETTER + #ifdef CONFIG_LV_FS_DEFAULT_DRIVE_LETTER + #define LV_FS_DEFAULT_DRIVE_LETTER CONFIG_LV_FS_DEFAULT_DRIVE_LETTER + #else + #define LV_FS_DEFAULT_DRIVE_LETTER '\0' + #endif +#endif + /*API for fopen, fread, etc*/ #ifndef LV_USE_FS_STDIO #ifdef CONFIG_LV_USE_FS_STDIO @@ -2169,6 +2489,42 @@ #endif #endif +/*API for Arduino LittleFs. */ +#ifndef LV_USE_FS_ARDUINO_ESP_LITTLEFS + #ifdef CONFIG_LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_USE_FS_ARDUINO_ESP_LITTLEFS CONFIG_LV_USE_FS_ARDUINO_ESP_LITTLEFS + #else + #define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 + #endif +#endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #ifndef LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #ifdef CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #else + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #endif + #endif +#endif + +/*API for Arduino Sd. */ +#ifndef LV_USE_FS_ARDUINO_SD + #ifdef CONFIG_LV_USE_FS_ARDUINO_SD + #define LV_USE_FS_ARDUINO_SD CONFIG_LV_USE_FS_ARDUINO_SD + #else + #define LV_USE_FS_ARDUINO_SD 0 + #endif +#endif +#if LV_USE_FS_ARDUINO_SD + #ifndef LV_FS_ARDUINO_SD_LETTER + #ifdef CONFIG_LV_FS_ARDUINO_SD_LETTER + #define LV_FS_ARDUINO_SD_LETTER CONFIG_LV_FS_ARDUINO_SD_LETTER + #else + #define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #endif + #endif +#endif + /*LODEPNG decoder library*/ #ifndef LV_USE_LODEPNG #ifdef CONFIG_LV_USE_LODEPNG @@ -2225,15 +2581,15 @@ #endif #endif #if LV_USE_GIF -/*GIF decoder accelerate*/ -#ifndef LV_GIF_CACHE_DECODE_DATA - #ifdef CONFIG_LV_GIF_CACHE_DECODE_DATA - #define LV_GIF_CACHE_DECODE_DATA CONFIG_LV_GIF_CACHE_DECODE_DATA - #else - #define LV_GIF_CACHE_DECODE_DATA 0 + /*GIF decoder accelerate*/ + #ifndef LV_GIF_CACHE_DECODE_DATA + #ifdef CONFIG_LV_GIF_CACHE_DECODE_DATA + #define LV_GIF_CACHE_DECODE_DATA CONFIG_LV_GIF_CACHE_DECODE_DATA + #else + #define LV_GIF_CACHE_DECODE_DATA 0 + #endif #endif #endif -#endif /*Decode bin images to RAM*/ @@ -2318,6 +2674,13 @@ #define LV_TINY_TTF_FILE_SUPPORT 0 #endif #endif + #ifndef LV_TINY_TTF_CACHE_GLYPH_CNT + #ifdef CONFIG_LV_TINY_TTF_CACHE_GLYPH_CNT + #define LV_TINY_TTF_CACHE_GLYPH_CNT CONFIG_LV_TINY_TTF_CACHE_GLYPH_CNT + #else + #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 + #endif + #endif #endif /*Rlottie library*/ @@ -2329,7 +2692,8 @@ #endif #endif -/*Enable Vector Graphic APIs*/ +/*Enable Vector Graphic APIs + *Requires `LV_USE_MATRIX = 1`*/ #ifndef LV_USE_VECTOR_GRAPHIC #ifdef CONFIG_LV_USE_VECTOR_GRAPHIC #define LV_USE_VECTOR_GRAPHIC CONFIG_LV_USE_VECTOR_GRAPHIC @@ -2486,7 +2850,7 @@ #if LV_USE_PROFILER /*1: Enable the built-in profiler*/ #ifndef LV_USE_PROFILER_BUILTIN - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_PROFILER_BUILTIN #define LV_USE_PROFILER_BUILTIN CONFIG_LV_USE_PROFILER_BUILTIN #else @@ -2591,7 +2955,7 @@ /*1: Enable an observer pattern implementation*/ #ifndef LV_USE_OBSERVER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_OBSERVER #define LV_USE_OBSERVER CONFIG_LV_USE_OBSERVER #else @@ -2613,9 +2977,9 @@ #endif #if LV_USE_IME_PINYIN /*1: Use default thesaurus*/ - /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ + /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus*/ #ifndef LV_IME_PINYIN_USE_DEFAULT_DICT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT #define LV_IME_PINYIN_USE_DEFAULT_DICT CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT #else @@ -2637,7 +3001,7 @@ /*Use 9 key input(k9)*/ #ifndef LV_IME_PINYIN_USE_K9_MODE - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_IME_PINYIN_USE_K9_MODE #define LV_IME_PINYIN_USE_K9_MODE CONFIG_LV_IME_PINYIN_USE_K9_MODE #else @@ -2679,7 +3043,7 @@ /*Quick access bar, 1:use, 0:not use*/ /*Requires: lv_list*/ #ifndef LV_FILE_EXPLORER_QUICK_ACCESS - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_FILE_EXPLORER_QUICK_ACCESS #define LV_FILE_EXPLORER_QUICK_ACCESS CONFIG_LV_FILE_EXPLORER_QUICK_ACCESS #else @@ -2719,7 +3083,7 @@ #endif #endif #ifndef LV_SDL_BUF_COUNT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_SDL_BUF_COUNT #define LV_SDL_BUF_COUNT CONFIG_LV_SDL_BUF_COUNT #else @@ -2729,6 +3093,17 @@ #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ #endif #endif + #ifndef LV_SDL_ACCELERATED + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_SDL_ACCELERATED + #define LV_SDL_ACCELERATED CONFIG_LV_SDL_ACCELERATED + #else + #define LV_SDL_ACCELERATED 0 + #endif + #else + #define LV_SDL_ACCELERATED 1 /*1: Use hardware acceleration*/ + #endif + #endif #ifndef LV_SDL_FULLSCREEN #ifdef CONFIG_LV_SDL_FULLSCREEN #define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN @@ -2737,7 +3112,7 @@ #endif #endif #ifndef LV_SDL_DIRECT_EXIT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_SDL_DIRECT_EXIT #define LV_SDL_DIRECT_EXIT CONFIG_LV_SDL_DIRECT_EXIT #else @@ -2766,7 +3141,7 @@ #endif #if LV_USE_X11 #ifndef LV_X11_DIRECT_EXIT - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_X11_DIRECT_EXIT #define LV_X11_DIRECT_EXIT CONFIG_LV_X11_DIRECT_EXIT #else @@ -2777,19 +3152,19 @@ #endif #endif #ifndef LV_X11_DOUBLE_BUFFER - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_X11_DOUBLE_BUFFER #define LV_X11_DOUBLE_BUFFER CONFIG_LV_X11_DOUBLE_BUFFER #else #define LV_X11_DOUBLE_BUFFER 0 #endif #else - #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/ + #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for rendering*/ #endif #endif /*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/ #ifndef LV_X11_RENDER_MODE_PARTIAL - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_X11_RENDER_MODE_PARTIAL #define LV_X11_RENDER_MODE_PARTIAL CONFIG_LV_X11_RENDER_MODE_PARTIAL #else @@ -2815,6 +3190,31 @@ #endif #endif +/*Use Wayland to open a window and handle input on Linux or BSD desktops */ +#ifndef LV_USE_WAYLAND + #ifdef CONFIG_LV_USE_WAYLAND + #define LV_USE_WAYLAND CONFIG_LV_USE_WAYLAND + #else + #define LV_USE_WAYLAND 0 + #endif +#endif +#if LV_USE_WAYLAND + #ifndef LV_WAYLAND_WINDOW_DECORATIONS + #ifdef CONFIG_LV_WAYLAND_WINDOW_DECORATIONS + #define LV_WAYLAND_WINDOW_DECORATIONS CONFIG_LV_WAYLAND_WINDOW_DECORATIONS + #else + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /*Draw client side window decorations only necessary on Mutter/GNOME*/ + #endif + #endif + #ifndef LV_WAYLAND_WL_SHELL + #ifdef CONFIG_LV_WAYLAND_WL_SHELL + #define LV_WAYLAND_WL_SHELL CONFIG_LV_WAYLAND_WL_SHELL + #else + #define LV_WAYLAND_WL_SHELL 0 /*Use the legacy wl_shell protocol instead of the default XDG shell*/ + #endif + #endif +#endif + /*Driver for /dev/fb*/ #ifndef LV_USE_LINUX_FBDEV #ifdef CONFIG_LV_USE_LINUX_FBDEV @@ -2987,28 +3387,28 @@ #ifdef CONFIG_LV_USE_ST7735 #define LV_USE_ST7735 CONFIG_LV_USE_ST7735 #else - #define LV_USE_ST7735 0 + #define LV_USE_ST7735 0 #endif #endif #ifndef LV_USE_ST7789 #ifdef CONFIG_LV_USE_ST7789 #define LV_USE_ST7789 CONFIG_LV_USE_ST7789 #else - #define LV_USE_ST7789 0 + #define LV_USE_ST7789 0 #endif #endif #ifndef LV_USE_ST7796 #ifdef CONFIG_LV_USE_ST7796 #define LV_USE_ST7796 CONFIG_LV_USE_ST7796 #else - #define LV_USE_ST7796 0 + #define LV_USE_ST7796 0 #endif #endif #ifndef LV_USE_ILI9341 #ifdef CONFIG_LV_USE_ILI9341 #define LV_USE_ILI9341 CONFIG_LV_USE_ILI9341 #else - #define LV_USE_ILI9341 0 + #define LV_USE_ILI9341 0 #endif #endif @@ -3020,6 +3420,15 @@ #endif #endif +/*Driver for Renesas GLCD*/ +#ifndef LV_USE_RENESAS_GLCDC + #ifdef CONFIG_LV_USE_RENESAS_GLCDC + #define LV_USE_RENESAS_GLCDC CONFIG_LV_USE_RENESAS_GLCDC + #else + #define LV_USE_RENESAS_GLCDC 0 + #endif +#endif + /* LVGL Windows backend */ #ifndef LV_USE_WINDOWS #ifdef CONFIG_LV_USE_WINDOWS @@ -3029,13 +3438,57 @@ #endif #endif +/* Use OpenGL to open window on PC and handle mouse and keyboard */ +#ifndef LV_USE_OPENGLES + #ifdef CONFIG_LV_USE_OPENGLES + #define LV_USE_OPENGLES CONFIG_LV_USE_OPENGLES + #else + #define LV_USE_OPENGLES 0 + #endif +#endif +#if LV_USE_OPENGLES + #ifndef LV_USE_OPENGLES_DEBUG + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_OPENGLES_DEBUG + #define LV_USE_OPENGLES_DEBUG CONFIG_LV_USE_OPENGLES_DEBUG + #else + #define LV_USE_OPENGLES_DEBUG 0 + #endif + #else + #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ + #endif + #endif +#endif + +/* QNX Screen display and input drivers */ +#ifndef LV_USE_QNX + #ifdef CONFIG_LV_USE_QNX + #define LV_USE_QNX CONFIG_LV_USE_QNX + #else + #define LV_USE_QNX 0 + #endif +#endif +#if LV_USE_QNX + #ifndef LV_QNX_BUF_COUNT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_QNX_BUF_COUNT + #define LV_QNX_BUF_COUNT CONFIG_LV_QNX_BUF_COUNT + #else + #define LV_QNX_BUF_COUNT 0 + #endif + #else + #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ + #endif + #endif +#endif + /*================== * EXAMPLES *==================*/ /*Enable the examples to be built with the library*/ #ifndef LV_BUILD_EXAMPLES - #ifdef _LV_KCONFIG_PRESENT + #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_BUILD_EXAMPLES #define LV_BUILD_EXAMPLES CONFIG_LV_BUILD_EXAMPLES #else @@ -3187,6 +3640,7 @@ #endif + /*---------------------------------- * End of parsing lv_conf_template.h -----------------------------------*/ @@ -3197,7 +3651,7 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_STRIDE_ALIGN); LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #endif -#undef _LV_KCONFIG_PRESENT +#undef LV_KCONFIG_PRESENT /*Set some defines if a dependency is disabled*/ #if LV_USE_LOG == 0 @@ -3212,6 +3666,11 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #define LV_LOG_TRACE_ANIM 0 #endif /*LV_USE_LOG*/ +#if LV_USE_SYSMON == 0 + #define LV_USE_PERF_MONITOR 0 + #define LV_USE_MEM_MONITOR 0 +#endif /*LV_USE_SYSMON*/ + #ifndef LV_USE_LZ4 #define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL) #endif @@ -3220,6 +3679,17 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #define LV_USE_THORVG (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL) #endif +#if LV_USE_OS + #if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024) + #warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG." + #endif + + #if defined(LV_DRAW_THREAD_STACKSIZE) && !defined(LV_DRAW_THREAD_STACK_SIZE) + #warning "LV_DRAW_THREAD_STACKSIZE was renamed to LV_DRAW_THREAD_STACK_SIZE. Please update lv_conf.h or run menuconfig again." + #define LV_DRAW_THREAD_STACK_SIZE LV_DRAW_THREAD_STACKSIZE + #endif +#endif + /*If running without lv_conf.h add typedefs with default value*/ #ifdef LV_CONF_SKIP #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /*Disable warnings for Visual Studio*/ diff --git a/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h b/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h index 7f7cbcb0c..a36eaf775 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h @@ -194,6 +194,8 @@ extern "C" { # define CONFIG_LV_FONT_DEFAULT &lv_font_montserrat_28_compressed #elif defined(CONFIG_LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW) # define CONFIG_LV_FONT_DEFAULT &lv_font_dejavu_16_persian_hebrew +#elif defined(CONFIG_LV_FONT_DEFAULT_SIMSUN_14_CJK) +# define CONFIG_LV_FONT_DEFAULT &lv_font_simsun_14_cjk #elif defined(CONFIG_LV_FONT_DEFAULT_SIMSUN_16_CJK) # define CONFIG_LV_FONT_DEFAULT &lv_font_simsun_16_cjk #elif defined(CONFIG_LV_FONT_DEFAULT_UNSCII_8) diff --git a/lib/libesp32_lvgl/lvgl/src/lv_init.c b/lib/libesp32_lvgl/lvgl/src/lv_init.c index cb4f23c85..26897a7bc 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_init.c +++ b/lib/libesp32_lvgl/lvgl/src/lv_init.c @@ -6,11 +6,21 @@ /********************* * INCLUDES *********************/ +#include "others/sysmon/lv_sysmon_private.h" +#include "misc/lv_timer_private.h" +#include "misc/lv_profiler_builtin_private.h" +#include "misc/lv_anim_private.h" +#include "draw/lv_image_decoder_private.h" +#include "draw/lv_draw_buf_private.h" +#include "core/lv_refr_private.h" +#include "core/lv_obj_style_private.h" +#include "core/lv_group_private.h" +#include "lv_init.h" #include "core/lv_global.h" #include "core/lv_obj.h" #include "display/lv_display_private.h" #include "indev/lv_indev_private.h" -#include "layouts/lv_layout.h" +#include "layouts/lv_layout_private.h" #include "libs/bin_decoder/lv_bin_decoder.h" #include "libs/bmp/lv_bmp.h" #include "libs/ffmpeg/lv_ffmpeg.h" @@ -21,9 +31,15 @@ #include "libs/libjpeg_turbo/lv_libjpeg_turbo.h" #include "libs/lodepng/lv_lodepng.h" #include "libs/libpng/lv_libpng.h" +#include "libs/tiny_ttf/lv_tiny_ttf.h" #include "draw/lv_draw.h" #include "misc/lv_async.h" +#include "misc/lv_fs_private.h" +#include "widgets/span/lv_span.h" +#include "themes/simple/lv_theme_simple.h" #include "misc/lv_fs.h" +#include "osal/lv_os_private.h" + #if LV_USE_DRAW_VGLITE #include "draw/nxp/vglite/lv_draw_vglite.h" #endif @@ -86,30 +102,35 @@ static inline void lv_global_init(lv_global_t * global) lv_memzero(global, sizeof(lv_global_t)); - _lv_ll_init(&(global->disp_ll), sizeof(lv_display_t)); - _lv_ll_init(&(global->indev_ll), sizeof(lv_indev_t)); + lv_ll_init(&(global->disp_ll), sizeof(lv_display_t)); + lv_ll_init(&(global->indev_ll), sizeof(lv_indev_t)); global->memory_zero = ZERO_MEM_SENTINEL; global->style_refresh = true; - global->layout_count = _LV_LAYOUT_LAST; - global->style_last_custom_prop_id = (uint32_t)_LV_STYLE_LAST_BUILT_IN_PROP; - global->event_last_register_id = _LV_EVENT_LAST; + global->layout_count = LV_LAYOUT_LAST; + global->style_last_custom_prop_id = (uint32_t)LV_STYLE_LAST_BUILT_IN_PROP; + global->event_last_register_id = LV_EVENT_LAST; lv_rand_set_seed(0x1234ABCD); +#ifdef LV_LOG_PRINT_CB + void LV_LOG_PRINT_CB(lv_log_level_t, const char * txt); + global->custom_log_print_cb = LV_LOG_PRINT_CB; +#endif + #if defined(LV_DRAW_SW_SHADOW_CACHE_SIZE) && LV_DRAW_SW_SHADOW_CACHE_SIZE > 0 global->sw_shadow_cache.cache_size = -1; global->sw_shadow_cache.cache_r = -1; #endif } -static inline void _lv_cleanup_devices(lv_global_t * global) +static inline void lv_cleanup_devices(lv_global_t * global) { LV_ASSERT_NULL(global); if(global) { /* cleanup indev and display */ - _lv_ll_clear_custom(&(global->indev_ll), (void (*)(void *)) lv_indev_delete); - _lv_ll_clear_custom(&(global->disp_ll), (void (*)(void *)) lv_display_delete); + lv_ll_clear_custom(&(global->indev_ll), (void (*)(void *)) lv_indev_delete); + lv_ll_clear_custom(&(global->disp_ll), (void (*)(void *)) lv_display_delete); } } @@ -143,7 +164,7 @@ void lv_init(void) lv_mem_init(); - _lv_draw_buf_init_handlers(); + lv_draw_buf_init_handlers(); #if LV_USE_SPAN != 0 lv_span_stack_init(); @@ -155,15 +176,17 @@ void lv_init(void) lv_profiler_builtin_init(&profiler_config); #endif - _lv_timer_core_init(); + lv_os_init(); - _lv_fs_init(); + lv_timer_core_init(); - _lv_layout_init(); + lv_fs_init(); - _lv_anim_core_init(); + lv_layout_init(); - _lv_group_init(); + lv_anim_core_init(); + + lv_group_init(); lv_draw_init(); @@ -191,16 +214,16 @@ void lv_init(void) lv_windows_platform_init(); #endif - _lv_obj_style_init(); + lv_obj_style_init(); /*Initialize the screen refresh system*/ - _lv_refr_init(); + lv_refr_init(); #if LV_USE_SYSMON - _lv_sysmon_builtin_init(); + lv_sysmon_builtin_init(); #endif - _lv_image_decoder_init(); + lv_image_decoder_init(LV_CACHE_DEF_SIZE, LV_IMAGE_HEADER_CACHE_DEF_CNT); lv_bin_decoder_init(); /*LVGL built-in binary image decoder*/ #if LV_USE_DRAW_VG_LITE @@ -268,6 +291,14 @@ void lv_init(void) lv_fs_littlefs_init(); #endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + lv_fs_arduino_esp_littlefs_init(); +#endif + +#if LV_USE_FS_ARDUINO_SD + lv_fs_arduino_sd_init(); +#endif + #if LV_USE_LODEPNG lv_lodepng_init(); #endif @@ -299,10 +330,6 @@ void lv_init(void) lv_freetype_init(LV_FREETYPE_CACHE_FT_GLYPH_CNT); #endif -#if LV_USE_TINY_TTF - lv_tiny_ttf_init(); -#endif - lv_initialized = true; LV_LOG_TRACE("finished"); @@ -321,12 +348,12 @@ void lv_deinit(void) lv_deinit_in_progress = true; #if LV_USE_SYSMON - _lv_sysmon_builtin_deinit(); + lv_sysmon_builtin_deinit(); #endif lv_display_set_default(NULL); - _lv_cleanup_devices(LV_GLOBAL_DEFAULT()); + lv_cleanup_devices(LV_GLOBAL_DEFAULT()); #if LV_USE_SPAN != 0 lv_span_stack_deinit(); @@ -340,10 +367,6 @@ void lv_deinit(void) lv_freetype_uninit(); #endif -#if LV_USE_TINY_TTF - lv_tiny_ttf_deinit(); -#endif - #if LV_USE_THEME_DEFAULT lv_theme_default_deinit(); #endif @@ -356,11 +379,11 @@ void lv_deinit(void) lv_theme_mono_deinit(); #endif - _lv_image_decoder_deinit(); + lv_image_decoder_deinit(); - _lv_refr_deinit(); + lv_refr_deinit(); - _lv_obj_style_deinit(); + lv_obj_style_deinit(); #if LV_USE_DRAW_PXP lv_draw_pxp_deinit(); @@ -380,21 +403,21 @@ void lv_deinit(void) lv_draw_deinit(); - _lv_group_deinit(); + lv_group_deinit(); - _lv_anim_core_deinit(); + lv_anim_core_deinit(); - _lv_layout_deinit(); + lv_layout_deinit(); - _lv_fs_deinit(); + lv_fs_deinit(); - _lv_timer_core_deinit(); + lv_timer_core_deinit(); #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN lv_profiler_builtin_uninit(); #endif -#if LV_USE_OBJ_ID_BUILTIN +#if LV_USE_OBJ_ID && LV_USE_OBJ_ID_BUILTIN lv_objid_builtin_destroy(); #endif diff --git a/lib/libesp32_lvgl/lvgl/src/lv_init.h b/lib/libesp32_lvgl/lvgl/src/lv_init.h index e5b551f05..0815142cb 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_init.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_init.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include #include "lv_conf_internal.h" +#include "misc/lv_types.h" /********************* * DEFINES diff --git a/lib/libesp32_lvgl/lvgl/src/lvgl.h b/lib/libesp32_lvgl/lvgl/src/lvgl.h index e4533da11..f49fcc71c 100644 --- a/lib/libesp32_lvgl/lvgl/src/lvgl.h +++ b/lib/libesp32_lvgl/lvgl/src/lvgl.h @@ -36,4 +36,4 @@ extern "C" { } /*extern "C"*/ #endif -#endif /*LVGL_SRC_H*/ +#endif /* LVGL_SRC_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/lvgl_private.h b/lib/libesp32_lvgl/lvgl/src/lvgl_private.h index c6fc5990a..cda92217b 100644 --- a/lib/libesp32_lvgl/lvgl/src/lvgl_private.h +++ b/lib/libesp32_lvgl/lvgl/src/lvgl_private.h @@ -13,8 +13,95 @@ extern "C" { /********************* * INCLUDES *********************/ +#include "core/lv_global.h" + #include "display/lv_display_private.h" #include "indev/lv_indev_private.h" +#include "misc/lv_text_private.h" +#include "misc/cache/lv_cache_entry_private.h" +#include "misc/cache/lv_cache_private.h" +#include "layouts/lv_layout_private.h" +#include "stdlib/lv_mem_private.h" +#include "others/file_explorer/lv_file_explorer_private.h" +#include "others/sysmon/lv_sysmon_private.h" +#include "others/monkey/lv_monkey_private.h" +#include "others/ime/lv_ime_pinyin_private.h" +#include "others/fragment/lv_fragment_private.h" +#include "others/observer/lv_observer_private.h" +#include "libs/qrcode/lv_qrcode_private.h" +#include "libs/barcode/lv_barcode_private.h" +#include "libs/gif/lv_gif_private.h" +#include "draw/lv_draw_triangle_private.h" +#include "draw/lv_draw_private.h" +#include "draw/lv_draw_rect_private.h" +#include "draw/lv_draw_image_private.h" +#include "draw/lv_image_decoder_private.h" +#include "draw/lv_draw_label_private.h" +#include "draw/lv_draw_vector_private.h" +#include "draw/lv_draw_buf_private.h" +#include "draw/lv_draw_mask_private.h" +#include "draw/sw/lv_draw_sw_gradient_private.h" +#include "draw/sw/lv_draw_sw_private.h" +#include "draw/sw/lv_draw_sw_mask_private.h" +#include "draw/sw/blend/lv_draw_sw_blend_private.h" +#include "drivers/libinput/lv_xkb_private.h" +#include "drivers/libinput/lv_libinput_private.h" +#include "font/lv_font_fmt_txt_private.h" +#include "themes/lv_theme_private.h" +#include "core/lv_refr_private.h" +#include "core/lv_obj_style_private.h" +#include "core/lv_obj_private.h" +#include "core/lv_obj_scroll_private.h" +#include "core/lv_obj_draw_private.h" +#include "core/lv_obj_class_private.h" +#include "core/lv_group_private.h" +#include "core/lv_obj_event_private.h" +#include "misc/lv_timer_private.h" +#include "misc/lv_area_private.h" +#include "misc/lv_fs_private.h" +#include "misc/lv_profiler_builtin_private.h" +#include "misc/lv_event_private.h" +#include "misc/lv_bidi_private.h" +#include "misc/lv_rb_private.h" +#include "misc/lv_style_private.h" +#include "misc/lv_color_op_private.h" +#include "misc/lv_anim_private.h" +#include "widgets/msgbox/lv_msgbox_private.h" +#include "widgets/buttonmatrix/lv_buttonmatrix_private.h" +#include "widgets/slider/lv_slider_private.h" +#include "widgets/switch/lv_switch_private.h" +#include "widgets/calendar/lv_calendar_chinese_private.h" +#include "widgets/calendar/lv_calendar_private.h" +#include "widgets/imagebutton/lv_imagebutton_private.h" +#include "widgets/bar/lv_bar_private.h" +#include "widgets/image/lv_image_private.h" +#include "widgets/textarea/lv_textarea_private.h" +#include "widgets/table/lv_table_private.h" +#include "widgets/checkbox/lv_checkbox_private.h" +#include "widgets/roller/lv_roller_private.h" +#include "widgets/win/lv_win_private.h" +#include "widgets/keyboard/lv_keyboard_private.h" +#include "widgets/line/lv_line_private.h" +#include "widgets/animimage/lv_animimage_private.h" +#include "widgets/dropdown/lv_dropdown_private.h" +#include "widgets/menu/lv_menu_private.h" +#include "widgets/chart/lv_chart_private.h" +#include "widgets/button/lv_button_private.h" +#include "widgets/scale/lv_scale_private.h" +#include "widgets/led/lv_led_private.h" +#include "widgets/arc/lv_arc_private.h" +#include "widgets/tileview/lv_tileview_private.h" +#include "widgets/spinbox/lv_spinbox_private.h" +#include "widgets/span/lv_span_private.h" +#include "widgets/label/lv_label_private.h" +#include "widgets/canvas/lv_canvas_private.h" +#include "widgets/tabview/lv_tabview_private.h" +#include "tick/lv_tick_private.h" +#include "stdlib/builtin/lv_tlsf_private.h" +#include "libs/rlottie/lv_rlottie_private.h" +#include "libs/ffmpeg/lv_ffmpeg_private.h" +#include "widgets/lottie/lv_lottie_private.h" +#include "osal/lv_os_private.h" /********************* * DEFINES diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.c index e22cd9e42..0518ab5e1 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.c @@ -81,18 +81,32 @@ lv_cache_entry_t * lv_cache_acquire(lv_cache_t * cache, const void * key, void * LV_ASSERT_NULL(cache); LV_ASSERT_NULL(key); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); + + if(cache->size == 0) { + lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; + return NULL; + } + lv_cache_entry_t * entry = cache->clz->get_cb(cache, key, user_data); if(entry != NULL) { lv_cache_entry_acquire_data(entry); } lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; return entry; } void lv_cache_release(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_data) { LV_ASSERT_NULL(entry); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); lv_cache_entry_release_data(entry, user_data); @@ -101,19 +115,31 @@ void lv_cache_release(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_ lv_cache_entry_delete(entry); } lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; } lv_cache_entry_t * lv_cache_add(lv_cache_t * cache, const void * key, void * user_data) { LV_ASSERT_NULL(cache); LV_ASSERT_NULL(key); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); + if(cache->max_size == 0) { + lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; + return NULL; + } + lv_cache_entry_t * entry = cache_add_internal_no_lock(cache, key, user_data); if(entry != NULL) { lv_cache_entry_acquire_data(entry); } lv_mutex_unlock(&cache->lock); + LV_PROFILER_END; return entry; } lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * key, void * user_data) @@ -121,16 +147,34 @@ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * k LV_ASSERT_NULL(cache); LV_ASSERT_NULL(key); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); - lv_cache_entry_t * entry = cache->clz->get_cb(cache, key, user_data); - if(entry != NULL) { - lv_cache_entry_acquire_data(entry); - lv_mutex_unlock(&cache->lock); - return entry; + lv_cache_entry_t * entry = NULL; + + if(cache->size != 0) { + entry = cache->clz->get_cb(cache, key, user_data); + if(entry != NULL) { + lv_cache_entry_acquire_data(entry); + lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; + return entry; + } } + + if(cache->max_size == 0) { + lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; + return NULL; + } + entry = cache_add_internal_no_lock(cache, key, user_data); if(entry == NULL) { lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; return NULL; } bool create_res = cache->ops.create_cb(lv_cache_entry_get_data(entry), user_data); @@ -143,44 +187,60 @@ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * k lv_cache_entry_acquire_data(entry); } lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; return entry; } void lv_cache_reserve(lv_cache_t * cache, uint32_t reserved_size, void * user_data) { LV_ASSERT_NULL(cache); + LV_PROFILER_BEGIN; + for(lv_cache_reserve_cond_res_t reserve_cond_res = cache->clz->reserve_cond_cb(cache, NULL, reserved_size, user_data); reserve_cond_res == LV_CACHE_RESERVE_COND_NEED_VICTIM; reserve_cond_res = cache->clz->reserve_cond_cb(cache, NULL, reserved_size, user_data)) cache_evict_one_internal_no_lock(cache, user_data); + LV_PROFILER_END; } void lv_cache_drop(lv_cache_t * cache, const void * key, void * user_data) { LV_ASSERT_NULL(cache); LV_ASSERT_NULL(key); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); cache_drop_internal_no_lock(cache, key, user_data); lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; } bool lv_cache_evict_one(lv_cache_t * cache, void * user_data) { LV_ASSERT_NULL(cache); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); bool res = cache_evict_one_internal_no_lock(cache, user_data); lv_mutex_unlock(&cache->lock); + LV_PROFILER_END; return res; } void lv_cache_drop_all(lv_cache_t * cache, void * user_data) { LV_ASSERT_NULL(cache); + LV_PROFILER_BEGIN; + lv_mutex_lock(&cache->lock); cache->clz->drop_all_cb(cache, user_data); lv_mutex_unlock(&cache->lock); + + LV_PROFILER_END; } void lv_cache_set_max_size(lv_cache_t * cache, size_t max_size, void * user_data) @@ -203,6 +263,10 @@ size_t lv_cache_get_free_size(lv_cache_t * cache, void * user_data) LV_UNUSED(user_data); return cache->max_size - cache->size; } +bool lv_cache_is_enabled(lv_cache_t * cache) +{ + return cache->max_size > 0; +} void lv_cache_set_compare_cb(lv_cache_t * cache, lv_cache_compare_cb_t compare_cb, void * user_data) { LV_UNUSED(user_data); @@ -218,6 +282,15 @@ void lv_cache_set_free_cb(lv_cache_t * cache, lv_cache_free_cb_t free_cb, void * LV_UNUSED(user_data); cache->ops.free_cb = free_cb; } +void lv_cache_set_name(lv_cache_t * cache, const char * name) +{ + if(cache == NULL) return; + cache->name = name; +} +const char * lv_cache_get_name(lv_cache_t * cache) +{ + return cache->name; +} /********************** * STATIC FUNCTIONS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.h index 25db6fce4..ab488bec6 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.h @@ -1,10 +1,10 @@ /** -* @file lv_cache.h -* -*/ + * @file lv_cache.h + * + */ -#ifndef LV_CACHE1_H -#define LV_CACHE1_H +#ifndef LV_CACHE_H +#define LV_CACHE_H #ifdef __cplusplus extern "C" { @@ -15,12 +15,12 @@ extern "C" { *********************/ #include "lv_cache_entry.h" #include "lv_cache_private.h" -#include -#include +#include "../lv_types.h" -#include "_lv_cache_lru_rb.h" +#include "lv_cache_lru_rb.h" #include "lv_image_cache.h" +#include "lv_image_header_cache.h" /********************* * DEFINES *********************/ @@ -36,14 +36,14 @@ extern "C" { /** * Create a cache object with the given parameters. * @param cache_class The class of the cache. Currently only support one two builtin classes: - * @lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. - * @lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. + * - lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. + * - lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. * @param node_size The node size is the size of the data stored in the cache.. * @param max_size The max size is the maximum amount of memory or count that the cache can hold. - * @lv_cache_class_lru_rb_count: max_size is the maximum count of nodes in the cache. - * @lv_cache_class_lru_rb_size: max_size is the maximum size of the cache in bytes. - * @param ops A set of operations that can be performed on the cache. See @lv_cache_ops_t for details. - * @return Returns a pointer to the created cache object on success, @NULL on error. + * - lv_cache_class_lru_rb_count: max_size is the maximum count of nodes in the cache. + * - lv_cache_class_lru_rb_size: max_size is the maximum size of the cache in bytes. + * @param ops A set of operations that can be performed on the cache. See lv_cache_ops_t for details. + * @return Returns a pointer to the created cache object on success, `NULL` on error. */ lv_cache_t * lv_cache_create(const lv_cache_class_t * cache_class, size_t node_size, size_t max_size, @@ -57,25 +57,25 @@ lv_cache_t * lv_cache_create(const lv_cache_class_t * cache_class, void lv_cache_destroy(lv_cache_t * cache, void * user_data); /** - * Acquire a cache entry with the given key. If the entry is not in the cache, it will return @NULL as it is not found. - * If the entry is found, it's priority will be changed by the cache's policy. And the @lv_entry_t::ref count will be incremented. + * Acquire a cache entry with the given key. If entry not in cache, it will return `NULL` (not found). + * If the entry is found, it's priority will be changed by the cache's policy. And the `lv_cache_entry_t::ref_cnt` will be incremented. * @param cache The cache object pointer to acquire the entry. * @param key The key of the entry to acquire. * @param user_data A user data pointer that will be passed to the create callback. - * @return Returns a pointer to the acquired cache entry on success with @lv_entry_t::ref count incremented, @NULL on error. + * @return Returns a pointer to the acquired cache entry on success with `lv_cache_entry_t::ref_cnt` incremented, `NULL` on error. */ lv_cache_entry_t * lv_cache_acquire(lv_cache_t * cache, const void * key, void * user_data); /** * Acquire a cache entry with the given key. If the entry is not in the cache, it will create a new entry with the given key. - * If the entry is found, it's priority will be changed by the cache's policy. And the @lv_entry_t::ref count will be incremented. - * If you want to use this API to simplify the code, you should provide a @lv_cache_ops_t::create_cb that creates a new entry with the given key. - * This API is a combination of @lv_cache_acquire and @lv_cache_add. The effect is the same as calling @lv_cache_acquire and @lv_cache_add separately. + * If the entry is found, it's priority will be changed by the cache's policy. And the `lv_cache_entry_t::ref_cnt` will be incremented. + * If you want to use this API to simplify the code, you should provide a `lv_cache_ops_t::create_cb` that creates a new entry with the given key. + * This API is a combination of lv_cache_acquire() and lv_cache_add(). The effect is the same as calling lv_cache_acquire() and lv_cache_add() separately. * And the internal impact on cache is also consistent with these two APIs. * @param cache The cache object pointer to acquire the entry. * @param key The key of the entry to acquire or create. * @param user_data A user data pointer that will be passed to the create callback. - * @return Returns a pointer to the acquired or created cache entry on success with @lv_entry_t::ref count incremented, @NULL on error. + * @return Returns a pointer to the acquired or created cache entry on success with `lv_cache_entry_t::ref_cnt` incremented, `NULL` on error. */ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * key, void * user_data); @@ -84,12 +84,12 @@ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * k * @param cache The cache object pointer to add the entry. * @param key The key of the entry to add. * @param user_data A user data pointer that will be passed to the create callback. - * @return Returns a pointer to the added cache entry on success with @lv_entry_t::ref count incremented, @NULL on error. + * @return Returns a pointer to the added cache entry on success with `lv_cache_entry_t::ref_cnt` incremented, `NULL` on error. */ lv_cache_entry_t * lv_cache_add(lv_cache_t * cache, const void * key, void * user_data); /** - * Release a cache entry. The @lv_entry_t::ref count will be decremented. If the @lv_entry_t::ref count is zero, it will issue an error. + * Release a cache entry. The `lv_cache_entry_t::ref_cnt` will be decremented. If the `lv_cache_entry_t::ref_cnt` is zero, it will issue an error. * If the entry passed to this function is the last reference to the data and the entry is marked as invalid, the cache's policy will be used to evict the entry. * @param cache The cache object pointer to release the entry. * @param entry The cache entry pointer to release. @@ -110,8 +110,8 @@ void lv_cache_reserve(lv_cache_t * cache, uint32_t reserved_size, void * user_da /** * Drop a cache entry with the given key. If the entry is not in the cache, nothing will happen to it. * If the entry is found, it will be removed from the cache and its data will be freed when the last reference to it is released. - * @note The data will not be freed immediately but when the last reference to it is released. But this entry will not be found by @lv_cache_acquire. - * If you want cache a same key again, you should use @lv_cache_add or @lv_cache_acquire_or_create. + * @note The data will not be freed immediately but when the last reference to it is released. But this entry will not be found by lv_cache_acquire(). + * If you want cache a same key again, you should use lv_cache_add() or lv_cache_acquire_or_create(). * @param cache The cache object pointer to drop the entry. * @param key The key of the entry to drop. * @param user_data A user data pointer that will be passed to the free callback. @@ -137,6 +137,7 @@ bool lv_cache_evict_one(lv_cache_t * cache, void * user_data); /** * Set the maximum size of the cache. * If the current cache size is greater than the new maximum size, the cache's policy will be used to evict entries until the new maximum size is reached. + * If set to 0, the cache will be disabled. * @note But this behavior will happen only new entries are added to the cache. * @param cache The cache object pointer to set the maximum size. * @param max_size The new maximum size of the cache. @@ -168,6 +169,14 @@ size_t lv_cache_get_size(lv_cache_t * cache, void * user_data); */ size_t lv_cache_get_free_size(lv_cache_t * cache, void * user_data); +/** + * Return true if the cache is enabled. + * Disabled cache means that when the max_size of the cache is 0. In this case, all cache operations will be no-op. + * @param cache The cache object pointer to check if it's disabled. + * @return Returns true if the cache is enabled, false otherwise. + */ +bool lv_cache_is_enabled(lv_cache_t * cache); + /** * Set the compare callback of the cache. * @param cache The cache object pointer to set the compare callback. @@ -191,6 +200,21 @@ void lv_cache_set_create_cb(lv_cache_t * cache, lv_cache_create_cb_t alloc_cb, * @param user_data A user data pointer. */ void lv_cache_set_free_cb(lv_cache_t * cache, lv_cache_free_cb_t free_cb, void * user_data); + +/** + * Give a name for a cache object. Only the pointer of the string is saved. + * @param cache The cache object pointer to set the name. + * @param name The name of the cache. + */ +void lv_cache_set_name(lv_cache_t * cache, const char * name); + +/** + * Get the name of a cache object. + * @param cache The cache object pointer to get the name. + * @return Returns the name of the cache. + */ +const char * lv_cache_get_name(lv_cache_t * cache); + /************************* * GLOBAL VARIABLES *************************/ @@ -203,4 +227,4 @@ void lv_cache_set_free_cb(lv_cache_t * cache, lv_cache_free_cb_t free_cb, void } /*extern "C"*/ #endif -#endif /*LV_CACHE_H*/ +#endif /* LV_CACHE_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.c index 242e1a0f2..e0cc66434 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.c @@ -19,7 +19,7 @@ /********************** * TYPEDEFS **********************/ -struct _lv_cache_entry_t { +struct lv_cache_entry_t { const lv_cache_t * cache; int32_t ref_cnt; uint32_t node_size; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.h index 0cd2fb2e1..947f71d72 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry.h @@ -16,8 +16,6 @@ extern "C" { #include "../../osal/lv_os.h" #include "../lv_types.h" #include "lv_cache_private.h" -#include -#include /********************* * DEFINES *********************/ @@ -45,7 +43,7 @@ uint32_t lv_cache_entry_get_size(const uint32_t node_size); int32_t lv_cache_entry_get_ref(lv_cache_entry_t * entry); /** - * Get the node size of a cache entry. Which is the same size with @lv_cache_entry_get_size's node_size parameter. + * Get the node size of a cache entry. Which is the same size with lv_cache_entry_get_size()'s node_size parameter. * @param entry The cache entry to get the node size of. * @return The node size of the cache entry. */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry_private.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry_private.h index 227585e1e..f8d41bb9f 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_entry_private.h @@ -1,10 +1,10 @@ /** -* @file lv_cache_entry_private.h -* + * @file lv_cache_entry_private.h + * */ -#ifndef LV_CACHE_ENTRY_PRIVATE -#define LV_CACHE_ENTRY_PRIVATE +#ifndef LV_CACHE_ENTRY_PRIVATE_H +#define LV_CACHE_ENTRY_PRIVATE_H #ifdef __cplusplus extern "C" { @@ -14,9 +14,8 @@ extern "C" { * INCLUDES *********************/ #include "../lv_types.h" -#include -#include #include "../../osal/lv_os.h" +#include "../lv_profiler.h" /********************* * DEFINES *********************/ @@ -48,4 +47,4 @@ void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data); } /*extern "C"*/ #endif -#endif /*LV_CACHE_ENTRY_PRIVATE*/ +#endif /* LV_CACHE_ENTRY_PRIVATE_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/_lv_cache_lru_rb.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.c similarity index 94% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/_lv_cache_lru_rb.c rename to lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.c index 097f764f0..0a73102d1 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/_lv_cache_lru_rb.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.c @@ -1,5 +1,5 @@ /** -* @file _lv_cache_lru_rb.c +* @file lv_cache_lru_rb.c * */ @@ -43,11 +43,11 @@ /********************* * INCLUDES *********************/ -#include "_lv_cache_lru_rb.h" +#include "lv_cache_lru_rb.h" #include "../../stdlib/lv_sprintf.h" #include "../../stdlib/lv_string.h" #include "../lv_ll.h" -#include "../lv_rb.h" +#include "../lv_rb_private.h" /********************* * DEFINES @@ -58,7 +58,7 @@ **********************/ typedef uint32_t (get_data_size_cb_t)(const void * data); -struct _lv_lru_rb_t { +struct lv_lru_rb_t { lv_cache_t cache; lv_rb_t rb; @@ -66,7 +66,7 @@ struct _lv_lru_rb_t { get_data_size_cb_t * get_data_size_cb; }; -typedef struct _lv_lru_rb_t lv_lru_rb_t_; +typedef struct lv_lru_rb_t lv_lru_rb_t_; /********************** * STATIC PROTOTYPES **********************/ @@ -155,7 +155,7 @@ static void * alloc_new_node(lv_lru_rb_t_ * lru, void * key, void * user_data) lv_cache_entry_t * entry = lv_cache_entry_get_entry(data, lru->cache.node_size); lv_memcpy(data, key, lru->cache.node_size); - void * lru_node = _lv_ll_ins_head(&lru->ll); + void * lru_node = lv_ll_ins_head(&lru->ll); if(lru_node == NULL) goto FAILED_HANDLER1; @@ -198,8 +198,7 @@ static bool init_cnt_cb(lv_cache_t * cache) LV_ASSERT_NULL(lru->cache.ops.free_cb); LV_ASSERT(lru->cache.node_size > 0); - if(lru->cache.node_size <= 0 || lru->cache.max_size <= 0 - || lru->cache.ops.compare_cb == NULL || lru->cache.ops.free_cb == NULL) { + if(lru->cache.node_size <= 0 || lru->cache.ops.compare_cb == NULL || lru->cache.ops.free_cb == NULL) { return false; } @@ -207,7 +206,7 @@ static bool init_cnt_cb(lv_cache_t * cache) if(!lv_rb_init(&lru->rb, lru->cache.ops.compare_cb, lv_cache_entry_get_size(lru->cache.node_size) + sizeof(void *))) { return false; } - _lv_ll_init(&lru->ll, sizeof(void *)); + lv_ll_init(&lru->ll, sizeof(void *)); lru->get_data_size_cb = cnt_get_data_size_cb; @@ -222,8 +221,7 @@ static bool init_size_cb(lv_cache_t * cache) LV_ASSERT_NULL(lru->cache.ops.free_cb); LV_ASSERT(lru->cache.node_size > 0); - if(lru->cache.node_size <= 0 || lru->cache.max_size <= 0 - || lru->cache.ops.compare_cb == NULL || lru->cache.ops.free_cb == NULL) { + if(lru->cache.node_size <= 0 || lru->cache.ops.compare_cb == NULL || lru->cache.ops.free_cb == NULL) { return false; } @@ -231,7 +229,7 @@ static bool init_size_cb(lv_cache_t * cache) if(!lv_rb_init(&lru->rb, lru->cache.ops.compare_cb, lv_cache_entry_get_size(lru->cache.node_size) + sizeof(void *))) { return false; } - _lv_ll_init(&lru->ll, sizeof(void *)); + lv_ll_init(&lru->ll, sizeof(void *)); lru->get_data_size_cb = size_get_data_size_cb; @@ -267,7 +265,7 @@ static lv_cache_entry_t * get_cb(lv_cache_t * cache, const void * key, void * us } /*try the first ll node first*/ - void * head = _lv_ll_get_head(&lru->ll); + void * head = lv_ll_get_head(&lru->ll); if(head) { lv_rb_node_t * node = *(lv_rb_node_t **)head; void * data = node->data; @@ -281,8 +279,8 @@ static lv_cache_entry_t * get_cb(lv_cache_t * cache, const void * key, void * us /*cache hit*/ if(node) { void * lru_node = *get_lru_node(lru, node); - head = _lv_ll_get_head(&lru->ll); - _lv_ll_move_before(&lru->ll, lru_node, head); + head = lv_ll_get_head(&lru->ll); + lv_ll_move_before(&lru->ll, lru_node, head); lv_cache_entry_t * entry = lv_cache_entry_get_entry(node->data, cache->node_size); return entry; @@ -336,7 +334,7 @@ static void remove_cb(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_ void * lru_node = *get_lru_node(lru, node); lv_rb_remove_node(&lru->rb, node); - _lv_ll_remove(&lru->ll, lru_node); + lv_ll_remove(&lru->ll, lru_node); lv_free(lru_node); cache->size -= lru->get_data_size_cb(data); @@ -369,7 +367,7 @@ static void drop_cb(lv_cache_t * cache, const void * key, void * user_data) lv_rb_remove_node(&lru->rb, node); lv_cache_entry_delete(entry); - _lv_ll_remove(&lru->ll, lru_node); + lv_ll_remove(&lru->ll, lru_node); lv_free(lru_node); } @@ -385,7 +383,7 @@ static void drop_all_cb(lv_cache_t * cache, void * user_data) uint32_t used_cnt = 0; lv_rb_node_t ** node; - _LV_LL_READ(&lru->ll, node) { + LV_LL_READ(&lru->ll, node) { /*free user handled data and do other clean up*/ void * search_key = (*node)->data; lv_cache_entry_t * entry = lv_cache_entry_get_entry(search_key, cache->node_size); @@ -402,7 +400,7 @@ static void drop_all_cb(lv_cache_t * cache, void * user_data) } lv_rb_destroy(&lru->rb); - _lv_ll_clear(&lru->ll); + lv_ll_clear(&lru->ll); cache->size = 0; } @@ -416,7 +414,7 @@ static lv_cache_entry_t * get_victim_cb(lv_cache_t * cache, void * user_data) LV_ASSERT_NULL(lru); lv_rb_node_t ** tail; - _LV_LL_READ_BACK(&lru->ll, tail) { + LV_LL_READ_BACK(&lru->ll, tail) { lv_rb_node_t * tail_node = *tail; lv_cache_entry_t * entry = lv_cache_entry_get_entry(tail_node->data, cache->node_size); if(lv_cache_entry_get_ref(entry) == 0) { diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/_lv_cache_lru_rb.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.h similarity index 96% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/_lv_cache_lru_rb.h rename to lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.h index a27110b94..c0f44f396 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/_lv_cache_lru_rb.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.h @@ -1,5 +1,5 @@ /** -* @file _lv_cache_lru_rb.h +* @file lv_cache_lru_rb.h * */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_private.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_private.h index 4dbafd17e..c8ac24993 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_private.h @@ -14,8 +14,6 @@ extern "C" { * INCLUDES *********************/ #include "../lv_types.h" -#include -#include #include "../../osal/lv_os.h" /********************* @@ -36,15 +34,15 @@ typedef enum { LV_CACHE_RESERVE_COND_ERROR /**< An error occurred while checking the condition */ } lv_cache_reserve_cond_res_t; -struct _lv_cache_ops_t; -struct _lv_cache_t; -struct _lv_cache_class_t; -struct _lv_cache_entry_t; +struct lv_cache_ops_t; +struct lv_cache_t; +struct lv_cache_class_t; +struct lv_cache_entry_t; -typedef struct _lv_cache_ops_t lv_cache_ops_t; -typedef struct _lv_cache_t lv_cache_t; -typedef struct _lv_cache_class_t lv_cache_class_t; -typedef struct _lv_cache_entry_t lv_cache_entry_t; +typedef struct lv_cache_ops_t lv_cache_ops_t; +typedef struct lv_cache_t lv_cache_t; +typedef struct lv_cache_class_t lv_cache_class_t; +typedef struct lv_cache_entry_t lv_cache_entry_t; typedef int8_t lv_cache_compare_res_t; typedef bool (*lv_cache_create_cb_t)(void * node, void * user_data); @@ -70,7 +68,7 @@ typedef void (*lv_cache_destroy_cb_t)(lv_cache_t * cache, void * user_data); /** * The cache get function, used by the cache class to get a cache entry by its key. - * @return @NULL if the key is not found. + * @return `NULL` if the key is not found. */ typedef lv_cache_entry_t * (*lv_cache_get_cb_t)(lv_cache_t * cache, const void * key, void * user_data); @@ -104,7 +102,7 @@ typedef lv_cache_entry_t * (*lv_cache_get_victim_cb)(lv_cache_t * cache, void * /** * The cache reserve condition function, used by the cache class to check if a new entry can be added to the cache without exceeding its maximum size. - * See @lv_cache_reserve_cond_res_t for the possible results. + * See lv_cache_reserve_cond_res_t for the possible results. */ typedef lv_cache_reserve_cond_res_t (*lv_cache_reserve_cond_cb)(lv_cache_t * cache, const void * key, size_t size, void * user_data); @@ -112,7 +110,7 @@ typedef lv_cache_reserve_cond_res_t (*lv_cache_reserve_cond_cb)(lv_cache_t * cac /** * The cache operations struct */ -struct _lv_cache_ops_t { +struct lv_cache_ops_t { lv_cache_compare_cb_t compare_cb; /**< Compare function for keys */ lv_cache_create_cb_t create_cb; /**< Create function for nodes */ lv_cache_free_cb_t free_cb; /**< Free function for nodes */ @@ -121,27 +119,31 @@ struct _lv_cache_ops_t { /** * The cache entry struct */ -struct _lv_cache_t { - const lv_cache_class_t * clz; /**< The cache class. There are two built-in classes: - * @lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. - * @lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. */ +struct lv_cache_t { + const lv_cache_class_t * clz; /**< Cache class. There are two built-in classes: + * - lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. + * - lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. */ - uint32_t node_size; /**< The size of a node */ + uint32_t node_size; /**< Size of a node */ - uint32_t max_size; /**< The maximum size of the cache */ - uint32_t size; /**< The current size of the cache */ + uint32_t max_size; /**< Maximum size of the cache */ + uint32_t size; /**< Current size of the cache */ - lv_cache_ops_t ops; /**< The cache operations struct @lv_cache_ops_t */ + lv_cache_ops_t ops; /**< Cache operations struct lv_cache_ops_t */ - lv_mutex_t lock; /**< The cache lock used to protect the cache in multithreading environments */ + lv_mutex_t lock; /**< Cache lock used to protect the cache in multithreading environments */ + + const char * name; /**< Name of the cache */ }; /** - * The cache class struct for building custom cache classes, and there are two built-in classes for examples: - * @lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. - * @lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. + * Cache class struct for building custom cache classes + * + * Examples: + * - lv_cache_class_lru_rb_count for LRU-based cache with count-based eviction policy. + * - lv_cache_class_lru_rb_size for LRU-based cache with size-based eviction policy. */ -struct _lv_cache_class_t { +struct lv_cache_class_t { lv_cache_alloc_cb_t alloc_cb; /**< The allocation function for cache entries */ lv_cache_init_cb_t init_cb; /**< The initialization function for cache entries */ lv_cache_destroy_cb_t destroy_cb; /**< The destruction function for cache entries */ @@ -150,7 +152,7 @@ struct _lv_cache_class_t { lv_cache_add_cb_t add_cb; /**< The add function for cache entries */ lv_cache_remove_cb_t remove_cb; /**< The remove function for cache entries */ lv_cache_drop_cb_t drop_cb; /**< The drop function for cache entries */ - lv_cache_drop_all_cb_t drop_all_cb; /**< The drop all function for cache entries */ + lv_cache_drop_all_cb_t drop_all_cb; /**< The drop all function for cache entries */ lv_cache_get_victim_cb get_victim_cb; /**< The get victim function for cache entries */ lv_cache_reserve_cond_cb reserve_cond_cb; /**< The reserve condition function for cache entries */ }; @@ -159,16 +161,17 @@ struct _lv_cache_class_t { * Cache entry slot *----------------*/ -struct _lv_cache_slot_size_t; +struct lv_cache_slot_size_t; -typedef struct _lv_cache_slot_size_t lv_cache_slot_size_t; +typedef struct lv_cache_slot_size_t lv_cache_slot_size_t; /** - * The cache entry slot struct - * To add new fields to the cache entry, add them to a new struct and add it to the first field of the cache data struct. - * And this one is a size slot for the cache entry. + * Cache entry slot struct + * + * To add new fields to the cache entry, add them to a new struct and add it to the first + * field of the cache data struct. And this one is a size slot for the cache entry. */ -struct _lv_cache_slot_size_t { +struct lv_cache_slot_size_t { size_t size; }; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c index 28f0aec75..c2ca4354e 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c @@ -6,14 +6,23 @@ /********************* * INCLUDES *********************/ + +#include "../../draw/lv_image_decoder_private.h" #include "../lv_assert.h" -#include "lv_image_cache.h" #include "../../core/lv_global.h" + +#include "lv_image_cache.h" +#include "lv_image_header_cache.h" + /********************* * DEFINES *********************/ + +#define CACHE_NAME "IMAGE" + #define img_cache_p (LV_GLOBAL_DEFAULT()->img_cache) -#define img_header_cache_p (LV_GLOBAL_DEFAULT()->img_header_cache) +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) + /********************** * TYPEDEFS **********************/ @@ -22,6 +31,10 @@ * STATIC PROTOTYPES **********************/ +static lv_cache_compare_res_t image_cache_compare_cb(const lv_image_cache_data_t * lhs, + const lv_image_cache_data_t * rhs); +static void image_cache_free_cb(lv_image_cache_data_t * entry, void * user_data); + /********************** * GLOBAL VARIABLES **********************/ @@ -37,12 +50,37 @@ /********************** * GLOBAL FUNCTIONS **********************/ + +lv_result_t lv_image_cache_init(uint32_t size) +{ + if(img_cache_p != NULL) { + return LV_RESULT_OK; + } + + img_cache_p = lv_cache_create(&lv_cache_class_lru_rb_size, + sizeof(lv_image_cache_data_t), size, (lv_cache_ops_t) { + .compare_cb = (lv_cache_compare_cb_t) image_cache_compare_cb, + .create_cb = NULL, + .free_cb = (lv_cache_free_cb_t) image_cache_free_cb, + }); + + lv_cache_set_name(img_cache_p, CACHE_NAME); + return img_cache_p != NULL ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +void lv_image_cache_resize(uint32_t new_size, bool evict_now) +{ + lv_cache_set_max_size(img_cache_p, new_size, NULL); + if(evict_now) { + lv_cache_reserve(img_cache_p, new_size, NULL); + } +} + void lv_image_cache_drop(const void * src) { /*If user invalidate image, the header cache should be invalidated too.*/ lv_image_header_cache_drop(src); -#if LV_CACHE_DEF_SIZE > 0 if(src == NULL) { lv_cache_drop_all(img_cache_p, NULL); return; @@ -54,56 +92,54 @@ void lv_image_cache_drop(const void * src) }; lv_cache_drop(img_cache_p, &search_key, NULL); -#else - LV_UNUSED(src); -#endif } -void lv_image_cache_resize(uint32_t new_size, bool evict_now) +bool lv_image_cache_is_enabled(void) { -#if LV_CACHE_DEF_SIZE > 0 - lv_cache_set_max_size(img_cache_p, new_size, NULL); - if(evict_now) { - lv_cache_reserve(img_cache_p, new_size, NULL); - } -#else - LV_UNUSED(new_size); - LV_UNUSED(evict_now); -#endif -} - -void lv_image_header_cache_drop(const void * src) -{ -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 - if(src == NULL) { - lv_cache_drop_all(img_header_cache_p, NULL); - return; - } - - lv_image_header_cache_data_t search_key = { - .src = src, - .src_type = lv_image_src_get_type(src), - }; - - lv_cache_drop(img_header_cache_p, &search_key, NULL); -#else - LV_UNUSED(src); -#endif -} - -void lv_image_header_cache_resize(uint32_t new_size, bool evict_now) -{ -#if LV_IMAGE_HEADER_CACHE_DEF_CNT > 0 - lv_cache_set_max_size(img_header_cache_p, new_size, NULL); - if(evict_now) { - lv_cache_reserve(img_header_cache_p, new_size, NULL); - } -#else - LV_UNUSED(new_size); - LV_UNUSED(evict_now); -#endif + return lv_cache_is_enabled(img_cache_p); } /********************** * STATIC FUNCTIONS **********************/ + +inline static lv_cache_compare_res_t image_cache_common_compare(const void * lhs_src, lv_image_src_t lhs_src_type, + const void * rhs_src, lv_image_src_t rhs_src_type) +{ + if(lhs_src_type == rhs_src_type) { + if(lhs_src_type == LV_IMAGE_SRC_FILE) { + int32_t cmp_res = lv_strcmp(lhs_src, rhs_src); + if(cmp_res != 0) { + return cmp_res > 0 ? 1 : -1; + } + } + else if(lhs_src_type == LV_IMAGE_SRC_VARIABLE) { + if(lhs_src != rhs_src) { + return lhs_src > rhs_src ? 1 : -1; + } + } + return 0; + } + return lhs_src_type > rhs_src_type ? 1 : -1; +} + +static lv_cache_compare_res_t image_cache_compare_cb( + const lv_image_cache_data_t * lhs, + const lv_image_cache_data_t * rhs) +{ + return image_cache_common_compare(lhs->src, lhs->src_type, rhs->src, rhs->src_type); +} + +static void image_cache_free_cb(lv_image_cache_data_t * entry, void * user_data) +{ + LV_UNUSED(user_data); + + /* Destroy the decoded draw buffer if necessary. */ + lv_draw_buf_t * decoded = (lv_draw_buf_t *)entry->decoded; + if(lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_ALLOCATED)) { + lv_draw_buf_destroy(decoded); + } + + /*Free the duplicated file name*/ + if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src); +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h index f8a590349..1900b98e0 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h @@ -13,7 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_cache_private.h" + +#include "../../lv_conf_internal.h" +#include "../lv_types.h" /********************* * DEFINES @@ -28,31 +30,31 @@ extern "C" { **********************/ /** - * Invalidate image cache. Use NULL to invalidate all images. - * @param src pointer to an image source. + * Initialize image cache. + * @param size size of the cache in bytes. + * @return LV_RESULT_OK: initialization succeeded, LV_RESULT_INVALID: failed. */ -void lv_image_cache_drop(const void * src); +lv_result_t lv_image_cache_init(uint32_t size); /** * Resize image cache. + * If set to 0, the cache will be disabled. * @param new_size new size of the cache in bytes. * @param evict_now true: evict the images should be removed by the eviction policy, false: wait for the next cache cleanup. */ void lv_image_cache_resize(uint32_t new_size, bool evict_now); /** - * Invalidate image header cache. Use NULL to invalidate all image headers. - * It's also automatically called when an image is invalidated. + * Invalidate image cache. Use NULL to invalidate all images. * @param src pointer to an image source. */ -void lv_image_header_cache_drop(const void * src); +void lv_image_cache_drop(const void * src); /** - * Resize image header cache. - * @param new_size new size of the cache in count of image headers. - * @param evict_now true: evict the image headers should be removed by the eviction policy, false: wait for the next cache cleanup. + * Return true if the image cache is enabled. + * @return true: enabled, false: disabled. */ -void lv_image_header_cache_resize(uint32_t new_size, bool evict_now); +bool lv_image_cache_is_enabled(void); /************************* * GLOBAL VARIABLES diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.c new file mode 100644 index 000000000..ef124fb0a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.c @@ -0,0 +1,133 @@ +/** +* @file lv_image_header_cache.c +* + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../draw/lv_image_decoder_private.h" +#include "../lv_assert.h" +#include "../../core/lv_global.h" + +#include "lv_image_header_cache.h" + +/********************* + * DEFINES + *********************/ + +#define CACHE_NAME "IMAGE_HEADER" + +#define img_header_cache_p (LV_GLOBAL_DEFAULT()->img_header_cache) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_cache_compare_res_t image_header_cache_compare_cb(const lv_image_header_cache_data_t * lhs, + const lv_image_header_cache_data_t * rhs); +static void image_header_cache_free_cb(lv_image_header_cache_data_t * entry, void * user_data); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_image_header_cache_init(uint32_t count) +{ + if(img_header_cache_p != NULL) { + return LV_RESULT_OK; + } + + img_header_cache_p = lv_cache_create(&lv_cache_class_lru_rb_count, + sizeof(lv_image_header_cache_data_t), count, (lv_cache_ops_t) { + .compare_cb = (lv_cache_compare_cb_t) image_header_cache_compare_cb, + .create_cb = NULL, + .free_cb = (lv_cache_free_cb_t) image_header_cache_free_cb + }); + + lv_cache_set_name(img_header_cache_p, CACHE_NAME); + return img_header_cache_p != NULL ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +void lv_image_header_cache_resize(uint32_t count, bool evict_now) +{ + lv_cache_set_max_size(img_header_cache_p, count, NULL); + if(evict_now) { + lv_cache_reserve(img_header_cache_p, count, NULL); + } +} + +void lv_image_header_cache_drop(const void * src) +{ + if(src == NULL) { + lv_cache_drop_all(img_header_cache_p, NULL); + return; + } + + lv_image_header_cache_data_t search_key = { + .src = src, + .src_type = lv_image_src_get_type(src), + }; + + lv_cache_drop(img_header_cache_p, &search_key, NULL); +} + +bool lv_image_header_cache_is_enabled(void) +{ + return lv_cache_is_enabled(img_header_cache_p); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +inline static lv_cache_compare_res_t image_cache_common_compare(const void * lhs_src, lv_image_src_t lhs_src_type, + const void * rhs_src, lv_image_src_t rhs_src_type) +{ + if(lhs_src_type == rhs_src_type) { + if(lhs_src_type == LV_IMAGE_SRC_FILE) { + int32_t cmp_res = lv_strcmp(lhs_src, rhs_src); + if(cmp_res != 0) { + return cmp_res > 0 ? 1 : -1; + } + } + else if(lhs_src_type == LV_IMAGE_SRC_VARIABLE) { + if(lhs_src != rhs_src) { + return lhs_src > rhs_src ? 1 : -1; + } + } + return 0; + } + return lhs_src_type > rhs_src_type ? 1 : -1; +} + +static lv_cache_compare_res_t image_header_cache_compare_cb( + const lv_image_header_cache_data_t * lhs, + const lv_image_header_cache_data_t * rhs) +{ + return image_cache_common_compare(lhs->src, lhs->src_type, rhs->src, rhs->src_type); +} + +static void image_header_cache_free_cb(lv_image_header_cache_data_t * entry, void * user_data) +{ + LV_UNUSED(user_data); /*Unused*/ + + if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src); +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h new file mode 100644 index 000000000..bcecfaf6e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h @@ -0,0 +1,72 @@ +/** +* @file lv_image_header_cache.h +* + */ + +#ifndef LV_IMAGE_HEADER_CACHE_H +#define LV_IMAGE_HEADER_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#include "../lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize image header cache. + * @param count initial size of the cache in count of image headers. + * @return LV_RESULT_OK: initialization succeeded, LV_RESULT_INVALID: failed. + */ +lv_result_t lv_image_header_cache_init(uint32_t count); + +/** + * Resize image header cache. + * If set to 0, the cache is disabled. + * @param count new max count of cached image headers. + * @param evict_now true: evict the image headers should be removed by the eviction policy, false: wait for the next cache cleanup. + */ +void lv_image_header_cache_resize(uint32_t count, bool evict_now); + +/** + * Invalidate image header cache. Use NULL to invalidate all image headers. + * It's also automatically called when an image is invalidated. + * @param src pointer to an image source. + */ +void lv_image_header_cache_drop(const void * src); + +/** + * Return true if the image header cache is enabled. + * @return true: enabled, false: disabled. + */ +bool lv_image_header_cache_is_enabled(void); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_HEADER_CACHE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c index b33c5993c..0e57f2435 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_anim.h" +#include "lv_anim_private.h" #include "../core/lv_global.h" #include "../tick/lv_tick.h" @@ -39,6 +39,7 @@ static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1, static uint32_t convert_speed_to_time(uint32_t speed, int32_t start, int32_t end); static void resolve_time(lv_anim_t * a); static bool remove_concurrent_anims(lv_anim_t * a_current); +static void remove_anim(void * a); /********************** * STATIC VARIABLES @@ -57,16 +58,16 @@ static bool remove_concurrent_anims(lv_anim_t * a_current); * GLOBAL FUNCTIONS **********************/ -void _lv_anim_core_init(void) +void lv_anim_core_init(void) { - _lv_ll_init(anim_ll_p, sizeof(lv_anim_t)); + lv_ll_init(anim_ll_p, sizeof(lv_anim_t)); state.timer = lv_timer_create(anim_timer, LV_DEF_REFR_PERIOD, NULL); anim_mark_list_change(); /*Turn off the animation timer*/ state.anim_list_changed = false; state.anim_run_round = false; } -void _lv_anim_core_deinit(void) +void lv_anim_core_deinit(void) { lv_anim_delete_all(); } @@ -87,7 +88,7 @@ lv_anim_t * lv_anim_start(const lv_anim_t * a) LV_TRACE_ANIM("begin"); /*Add the new animation to the animation linked list*/ - lv_anim_t * new_anim = _lv_ll_ins_head(anim_ll_p); + lv_anim_t * new_anim = lv_ll_ins_head(anim_ll_p); LV_ASSERT_MALLOC(new_anim); if(new_anim == NULL) return NULL; @@ -133,8 +134,8 @@ uint32_t lv_anim_get_playtime(const lv_anim_t * a) return LV_ANIM_PLAYTIME_INFINITE; } - uint32_t repeate_cnt = a->repeat_cnt; - if(repeate_cnt < 1) repeate_cnt = 1; + uint32_t repeat_cnt = a->repeat_cnt; + if(repeat_cnt < 1) repeat_cnt = 1; uint32_t playtime = a->repeat_delay + a->duration + a->playback_delay + a->playback_duration; playtime = playtime * a->repeat_cnt; @@ -145,13 +146,11 @@ bool lv_anim_delete(void * var, lv_anim_exec_xcb_t exec_cb) { lv_anim_t * a; bool del_any = false; - a = _lv_ll_get_head(anim_ll_p); + a = lv_ll_get_head(anim_ll_p); while(a != NULL) { bool del = false; if((a->var == var || var == NULL) && (a->exec_cb == exec_cb || exec_cb == NULL)) { - _lv_ll_remove(anim_ll_p, a); - if(a->deleted_cb != NULL) a->deleted_cb(a); - lv_free(a); + remove_anim(a); anim_mark_list_change(); /*Read by `anim_timer`. It need to know if a delete occurred in the linked list*/ del_any = true; @@ -160,7 +159,7 @@ bool lv_anim_delete(void * var, lv_anim_exec_xcb_t exec_cb) /*Always start from the head on delete, because we don't know *how `anim_ll_p` was changes in `a->deleted_cb` */ - a = del ? _lv_ll_get_head(anim_ll_p) : _lv_ll_get_next(anim_ll_p, a); + a = del ? lv_ll_get_head(anim_ll_p) : lv_ll_get_next(anim_ll_p, a); } return del_any; @@ -168,14 +167,14 @@ bool lv_anim_delete(void * var, lv_anim_exec_xcb_t exec_cb) void lv_anim_delete_all(void) { - _lv_ll_clear(anim_ll_p); + lv_ll_clear_custom(anim_ll_p, remove_anim); anim_mark_list_change(); } lv_anim_t * lv_anim_get(void * var, lv_anim_exec_xcb_t exec_cb) { lv_anim_t * a; - _LV_LL_READ(anim_ll_p, a) { + LV_LL_READ(anim_ll_p, a) { if(a->var == var && (a->exec_cb == exec_cb || exec_cb == NULL)) { return a; } @@ -193,7 +192,7 @@ uint16_t lv_anim_count_running(void) { uint16_t cnt = 0; lv_anim_t * a; - _LV_LL_READ(anim_ll_p, a) cnt++; + LV_LL_READ(anim_ll_p, a) cnt++; return cnt; } @@ -228,6 +227,16 @@ uint32_t lv_anim_speed(uint32_t speed) return lv_anim_speed_clamped(speed, 0, 10000); } +uint32_t lv_anim_speed_to_time(uint32_t speed, int32_t start, int32_t end) +{ + uint32_t d = LV_ABS(start - end); + uint32_t time = (d * 1000) / speed; + + time = time == 0 ? 1 : time; + + return time; +} + void lv_anim_refr_now(void) { anim_timer(NULL); @@ -282,37 +291,38 @@ int32_t lv_anim_path_bounce(const lv_anim_t * a) if(t < 408) { /*Go down*/ t = (t * 2500) >> LV_BEZIER_VAL_SHIFT; /*[0..1024] range*/ + t = LV_BEZIER_VAL_MAX - t; } else if(t >= 408 && t < 614) { /*First bounce back*/ t -= 408; t = t * 5; /*to [0..1024] range*/ - t = LV_BEZIER_VAL_MAX - t; diff = diff / 20; } else if(t >= 614 && t < 819) { /*Fall back*/ t -= 614; t = t * 5; /*to [0..1024] range*/ + t = LV_BEZIER_VAL_MAX - t; diff = diff / 20; } else if(t >= 819 && t < 921) { /*Second bounce back*/ t -= 819; t = t * 10; /*to [0..1024] range*/ - t = LV_BEZIER_VAL_MAX - t; diff = diff / 40; } else if(t >= 921 && t <= LV_BEZIER_VAL_MAX) { /*Fall back*/ t -= 921; t = t * 10; /*to [0..1024] range*/ + t = LV_BEZIER_VAL_MAX - t; diff = diff / 40; } if(t > LV_BEZIER_VAL_MAX) t = LV_BEZIER_VAL_MAX; if(t < 0) t = 0; - int32_t step = lv_bezier3(t, LV_BEZIER_VAL_MAX, 800, 500, 0); + int32_t step = lv_bezier3(t, 0, 500, 800, LV_BEZIER_VAL_MAX); int32_t new_value; new_value = step * diff; @@ -332,10 +342,147 @@ int32_t lv_anim_path_step(const lv_anim_t * a) int32_t lv_anim_path_custom_bezier3(const lv_anim_t * a) { - const struct _lv_anim_bezier3_para_t * para = &a->parameter.bezier3; + const lv_anim_bezier3_para_t * para = &a->parameter.bezier3; return lv_anim_path_cubic_bezier(a, para->x1, para->y1, para->x2, para->y2); } +void lv_anim_set_var(lv_anim_t * a, void * var) +{ + a->var = var; +} + +void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb) +{ + a->exec_cb = exec_cb; +} + +void lv_anim_set_duration(lv_anim_t * a, uint32_t duration) +{ + a->duration = duration; +} + +void lv_anim_set_time(lv_anim_t * a, uint32_t duration) +{ + lv_anim_set_duration(a, duration); +} + +void lv_anim_set_delay(lv_anim_t * a, uint32_t delay) +{ + a->act_time = -(int32_t)(delay); +} + +void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end) +{ + a->start_value = start; + a->current_value = INT32_MIN; + a->end_value = end; +} + +void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +{ + a->custom_exec_cb = exec_cb; +} + +void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) +{ + a->path_cb = path_cb; +} + +void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_cb) +{ + a->start_cb = start_cb; +} + +void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb) +{ + a->get_value_cb = get_value_cb; +} + +void lv_anim_set_completed_cb(lv_anim_t * a, lv_anim_completed_cb_t completed_cb) +{ + a->completed_cb = completed_cb; +} + +void lv_anim_set_deleted_cb(lv_anim_t * a, lv_anim_deleted_cb_t deleted_cb) +{ + a->deleted_cb = deleted_cb; +} + +void lv_anim_set_playback_duration(lv_anim_t * a, uint32_t duration) +{ + a->playback_duration = duration; +} + +void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration) +{ + lv_anim_set_playback_duration(a, duration); +} + +void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay) +{ + a->playback_delay = delay; +} + +void lv_anim_set_repeat_count(lv_anim_t * a, uint32_t cnt) +{ + a->repeat_cnt = cnt; +} + +void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay) +{ + a->repeat_delay = delay; +} + +void lv_anim_set_early_apply(lv_anim_t * a, bool en) +{ + a->early_apply = en; +} + +void lv_anim_set_user_data(lv_anim_t * a, void * user_data) +{ + a->user_data = user_data; +} + +void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2) +{ + lv_anim_bezier3_para_t * para = &a->parameter.bezier3; + + para->x1 = x1; + para->x2 = x2; + para->y1 = y1; + para->y2 = y2; +} + +uint32_t lv_anim_get_delay(const lv_anim_t * a) +{ + return -a->act_time; +} + +uint32_t lv_anim_get_time(const lv_anim_t * a) +{ + return a->duration; +} + +uint32_t lv_anim_get_repeat_count(const lv_anim_t * a) +{ + return a->repeat_cnt; +} + +void * lv_anim_get_user_data(const lv_anim_t * a) +{ + return a->user_data; +} + +bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +{ + return lv_anim_delete(a ? a->var : NULL, (lv_anim_exec_xcb_t)exec_cb); +} + +lv_anim_t * lv_anim_custom_get(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) +{ + return lv_anim_get(a ? a->var : NULL, (lv_anim_exec_xcb_t)exec_cb); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -350,12 +497,9 @@ static void anim_timer(lv_timer_t * param) /*Flip the run round*/ state.anim_run_round = state.anim_run_round ? false : true; - lv_anim_t * a = _lv_ll_get_head(anim_ll_p); + lv_anim_t * a = lv_ll_get_head(anim_ll_p); while(a != NULL) { - - // printf("%p, %d\n", a, a->start_value); - uint32_t elaps = lv_tick_elaps(a->last_timer_run); a->act_time += elaps; @@ -411,9 +555,9 @@ static void anim_timer(lv_timer_t * param) /*If the linked list changed due to anim. delete then it's not safe to continue *the reading of the list from here -> start from the head*/ if(state.anim_list_changed) - a = _lv_ll_get_head(anim_ll_p); + a = lv_ll_get_head(anim_ll_p); else - a = _lv_ll_get_next(anim_ll_p, a); + a = lv_ll_get_next(anim_ll_p, a); } } @@ -437,7 +581,7 @@ static void anim_completed_handler(lv_anim_t * a) /*Delete the animation from the list. * This way the `completed_cb` will see the animations like it's animation is already deleted*/ - _lv_ll_remove(anim_ll_p, a); + lv_ll_remove(anim_ll_p, a); /*Flag that the list has changed*/ anim_mark_list_change(); @@ -471,7 +615,7 @@ static void anim_completed_handler(lv_anim_t * a) static void anim_mark_list_change(void) { state.anim_list_changed = true; - if(_lv_ll_get_head(anim_ll_p) == NULL) + if(lv_ll_get_head(anim_ll_p) == NULL) lv_timer_pause(state.timer); else lv_timer_resume(state.timer); @@ -525,7 +669,7 @@ static bool remove_concurrent_anims(lv_anim_t * a_current) lv_anim_t * a; bool del_any = false; - a = _lv_ll_get_head(anim_ll_p); + a = lv_ll_get_head(anim_ll_p); while(a != NULL) { bool del = false; /*We can't test for custom_exec_cb equality because in the MicroPython binding @@ -536,7 +680,7 @@ static bool remove_concurrent_anims(lv_anim_t * a_current) (a->var == a_current->var) && ((a->exec_cb && a->exec_cb == a_current->exec_cb) /*|| (a->custom_exec_cb && a->custom_exec_cb == a_current->custom_exec_cb)*/)) { - _lv_ll_remove(anim_ll_p, a); + lv_ll_remove(anim_ll_p, a); if(a->deleted_cb != NULL) a->deleted_cb(a); lv_free(a); /*Read by `anim_timer`. It need to know if a delete occurred in the linked list*/ @@ -548,8 +692,16 @@ static bool remove_concurrent_anims(lv_anim_t * a_current) /*Always start from the head on delete, because we don't know *how `anim_ll_p` was changes in `a->deleted_cb` */ - a = del ? _lv_ll_get_head(anim_ll_p) : _lv_ll_get_next(anim_ll_p, a); + a = del ? lv_ll_get_head(anim_ll_p) : lv_ll_get_next(anim_ll_p, a); } return del_any; } + +static void remove_anim(void * a) +{ + lv_anim_t * anim = a; + lv_ll_remove(anim_ll_p, a); + if(anim->deleted_cb != NULL) anim->deleted_cb(anim); + lv_free(a); +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h index bff3b33a4..0d626c89b 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h @@ -19,15 +19,11 @@ extern "C" { #include "lv_timer.h" #include "lv_ll.h" -#include -#include -#include - /********************* * DEFINES *********************/ -#define LV_ANIM_REPEAT_INFINITE 0xFFFF +#define LV_ANIM_REPEAT_INFINITE 0xFFFFFFFF #define LV_ANIM_PLAYTIME_INFINITE 0xFFFFFFFF /* @@ -46,7 +42,7 @@ extern "C" { */ #define _PARA(a, x1, y1, x2, y2) ((a)->parameter.bezier3 = \ -(struct _lv_anim_bezier3_para_t) { \ +(lv_anim_bezier3_para_t) { \ LV_BEZIER_VAL_FLOAT(x1), LV_BEZIER_VAL_FLOAT(y1), \ LV_BEZIER_VAL_FLOAT(x2), LV_BEZIER_VAL_FLOAT(y2) } \ ) @@ -89,13 +85,6 @@ typedef enum { LV_ANIM_ON, } lv_anim_enable_t; -typedef struct { - bool anim_list_changed; - bool anim_run_round; - lv_timer_t * timer; - lv_ll_t anim_ll; -} lv_anim_state_t; - /** Get the current value during an animation*/ typedef int32_t (*lv_anim_path_cb_t)(const lv_anim_t *); @@ -123,61 +112,51 @@ typedef int32_t (*lv_anim_get_value_cb_t)(lv_anim_t *); /** Callback used when the animation is deleted*/ typedef void (*lv_anim_deleted_cb_t)(lv_anim_t *); -typedef struct _lv_anim_bezier3_para_t { +/** Parameter used when path is custom_bezier */ +typedef struct { int16_t x1; int16_t y1; int16_t x2; int16_t y2; -} lv_anim_bezier3_para_t; /**< Parameter used when path is custom_bezier*/ +} lv_anim_bezier3_para_t; /** Describes an animation*/ -struct _lv_anim_t { - void * var; /**var = var; -} +void lv_anim_set_var(lv_anim_t * a, void * var); /** * Set a function to animate `var` @@ -206,38 +182,26 @@ static inline void lv_anim_set_var(lv_anim_t * a, void * var) * LVGL's built-in functions can be used. * E.g. lv_obj_set_x */ -static inline void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb) -{ - a->exec_cb = exec_cb; -} +void lv_anim_set_exec_cb(lv_anim_t * a, lv_anim_exec_xcb_t exec_cb); /** * Set the duration of an animation * @param a pointer to an initialized `lv_anim_t` variable * @param duration duration of the animation in milliseconds */ -static inline void lv_anim_set_duration(lv_anim_t * a, uint32_t duration) -{ - a->duration = duration; -} +void lv_anim_set_duration(lv_anim_t * a, uint32_t duration); /** * Legacy `lv_anim_set_time` API will be removed soon, use `lv_anim_set_duration` instead. */ -static inline void lv_anim_set_time(lv_anim_t * a, uint32_t duration) -{ - lv_anim_set_duration(a, duration); -} +void lv_anim_set_time(lv_anim_t * a, uint32_t duration); /** * Set a delay before starting the animation * @param a pointer to an initialized `lv_anim_t` variable * @param delay delay before the animation in milliseconds */ -static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay) -{ - a->act_time = -(int32_t)(delay); -} +void lv_anim_set_delay(lv_anim_t * a, uint32_t delay); /** * Set the start and end values of an animation @@ -245,12 +209,7 @@ static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay) * @param start the start value * @param end the end value */ -static inline void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end) -{ - a->start_value = start; - a->current_value = INT32_MIN; - a->end_value = end; -} +void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end); /** * Similar to `lv_anim_set_exec_cb` but `lv_anim_custom_exec_cb_t` receives @@ -260,30 +219,21 @@ static inline void lv_anim_set_values(lv_anim_t * a, int32_t start, int32_t end) * @param a pointer to an initialized `lv_anim_t` variable * @param exec_cb a function to execute. */ -static inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) -{ - a->custom_exec_cb = exec_cb; -} +void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb); /** * Set the path (curve) of the animation. * @param a pointer to an initialized `lv_anim_t` variable * @param path_cb a function to set the current value of the animation. */ -static inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb) -{ - a->path_cb = path_cb; -} +void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb); /** * Set a function call when the animation really starts (considering `delay`) * @param a pointer to an initialized `lv_anim_t` variable * @param start_cb a function call when the animation starts */ -static inline void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_cb) -{ - a->start_cb = start_cb; -} +void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_cb); /** * Set a function to use the current value of the variable and make start and end value @@ -291,78 +241,54 @@ static inline void lv_anim_set_start_cb(lv_anim_t * a, lv_anim_start_cb_t start_ * @param a pointer to an initialized `lv_anim_t` variable * @param get_value_cb a function call when the animation starts */ -static inline void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb) -{ - a->get_value_cb = get_value_cb; -} +void lv_anim_set_get_value_cb(lv_anim_t * a, lv_anim_get_value_cb_t get_value_cb); /** * Set a function call when the animation is completed * @param a pointer to an initialized `lv_anim_t` variable * @param completed_cb a function call when the animation is fully completed */ -static inline void lv_anim_set_completed_cb(lv_anim_t * a, lv_anim_completed_cb_t completed_cb) -{ - a->completed_cb = completed_cb; -} +void lv_anim_set_completed_cb(lv_anim_t * a, lv_anim_completed_cb_t completed_cb); /** * Set a function call when the animation is deleted. * @param a pointer to an initialized `lv_anim_t` variable * @param deleted_cb a function call when the animation is deleted */ -static inline void lv_anim_set_deleted_cb(lv_anim_t * a, lv_anim_deleted_cb_t deleted_cb) -{ - a->deleted_cb = deleted_cb; -} +void lv_anim_set_deleted_cb(lv_anim_t * a, lv_anim_deleted_cb_t deleted_cb); /** * Make the animation to play back to when the forward direction is ready * @param a pointer to an initialized `lv_anim_t` variable - * @param time the duration of the playback animation in milliseconds. 0: disable playback + * @param duration duration of playback animation in milliseconds. 0: disable playback */ -static inline void lv_anim_set_playback_duration(lv_anim_t * a, uint32_t duration) -{ - a->playback_duration = duration; -} +void lv_anim_set_playback_duration(lv_anim_t * a, uint32_t duration); /** * Legacy `lv_anim_set_playback_time` API will be removed soon, use `lv_anim_set_playback_duration` instead. */ -static inline void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration) -{ - lv_anim_set_playback_duration(a, duration); -} +void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration); /** * Make the animation to play back to when the forward direction is ready * @param a pointer to an initialized `lv_anim_t` variable * @param delay delay in milliseconds before starting the playback animation. */ -static inline void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay) -{ - a->playback_delay = delay; -} +void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay); /** * Make the animation repeat itself. * @param a pointer to an initialized `lv_anim_t` variable * @param cnt repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: to disable repetition. */ -static inline void lv_anim_set_repeat_count(lv_anim_t * a, uint16_t cnt) -{ - a->repeat_cnt = cnt; -} +void lv_anim_set_repeat_count(lv_anim_t * a, uint32_t cnt); /** * Set a delay before repeating the animation. * @param a pointer to an initialized `lv_anim_t` variable * @param delay delay in milliseconds before repeating the animation. */ -static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay) -{ - a->repeat_delay = delay; -} +void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay); /** * Set a whether the animation's should be applied immediately or only when the delay expired. @@ -370,37 +296,24 @@ static inline void lv_anim_set_repeat_delay(lv_anim_t * a, uint32_t delay) * @param en true: apply the start value immediately in `lv_anim_start`; * false: apply the start value only when `delay` ms is elapsed and the animations really starts */ -static inline void lv_anim_set_early_apply(lv_anim_t * a, bool en) -{ - a->early_apply = en; -} +void lv_anim_set_early_apply(lv_anim_t * a, bool en); /** * Set the custom user data field of the animation. * @param a pointer to an initialized `lv_anim_t` variable * @param user_data pointer to the new user_data. */ -static inline void lv_anim_set_user_data(lv_anim_t * a, void * user_data) -{ - a->user_data = user_data; -} +void lv_anim_set_user_data(lv_anim_t * a, void * user_data); /** * Set parameter for cubic bezier path * @param a pointer to an initialized `lv_anim_t` variable - * @param x1 first control point - * @param y1 - * @param y1 second control point + * @param x1 first control point X + * @param y1 first control point Y + * @param x2 second control point X + * @param y2 second control point Y */ -static inline void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2) -{ - struct _lv_anim_bezier3_para_t * para = &a->parameter.bezier3; - - para->x1 = x1; - para->x2 = x2; - para->y1 = y1; - para->y2 = y2; -} +void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2); /** * Create an animation @@ -414,10 +327,7 @@ lv_anim_t * lv_anim_start(const lv_anim_t * a); * @param a pointer to an initialized `lv_anim_t` variable * @return delay before the animation in milliseconds */ -static inline uint32_t lv_anim_get_delay(const lv_anim_t * a) -{ - return -a->act_time; -} +uint32_t lv_anim_get_delay(const lv_anim_t * a); /** * Get the time used to play the animation. @@ -431,30 +341,21 @@ uint32_t lv_anim_get_playtime(const lv_anim_t * a); * @param a pointer to an initialized `lv_anim_t` variable * @return the duration of the animation in milliseconds */ -static inline uint32_t lv_anim_get_time(const lv_anim_t * a) -{ - return a->duration; -} +uint32_t lv_anim_get_time(const lv_anim_t * a); /** * Get the repeat count of the animation. * @param a pointer to an initialized `lv_anim_t` variable * @return the repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: disabled repetition. */ -static inline uint16_t lv_anim_get_repeat_count(const lv_anim_t * a) -{ - return a->repeat_cnt; -} +uint32_t lv_anim_get_repeat_count(const lv_anim_t * a); /** * Get the user_data field of the animation * @param a pointer to an initialized `lv_anim_t` variable * @return the pointer to the custom user_data of the animation */ -static inline void * lv_anim_get_user_data(const lv_anim_t * a) -{ - return a->user_data; -} +void * lv_anim_get_user_data(const lv_anim_t * a); /** * Delete animation(s) of a variable with a given animator function @@ -495,10 +396,7 @@ lv_timer_t * lv_anim_get_timer(void); * or NULL to ignore it and delete all the animations of 'var * @return true: at least 1 animation is deleted, false: no animation is deleted */ -static inline bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) -{ - return lv_anim_delete(a ? a->var : NULL, (lv_anim_exec_xcb_t)exec_cb); -} +bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb); /** * Get the animation of a variable and its `exec_cb`. @@ -509,10 +407,7 @@ static inline bool lv_anim_custom_delete(lv_anim_t * a, lv_anim_custom_exec_cb_t * @param exec_cb a function pointer which is animating 'var', or NULL to return first matching 'var' * @return pointer to the animation. */ -static inline lv_anim_t * lv_anim_custom_get(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb) -{ - return lv_anim_get(a ? a->var : NULL, (lv_anim_exec_xcb_t)exec_cb); -} +lv_anim_t * lv_anim_custom_get(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb); /** * Get the number of currently running animations @@ -541,6 +436,15 @@ uint32_t lv_anim_speed(uint32_t speed); */ uint32_t lv_anim_speed_clamped(uint32_t speed, uint32_t min_time, uint32_t max_time); +/** + * Calculate the time of an animation based on its speed, start and end values. + * @param speed the speed of the animation + * @param start the start value + * @param end the end value + * @return the time of the animation in milliseconds + */ +uint32_t lv_anim_speed_to_time(uint32_t speed, int32_t start, int32_t end); + /** * Manually refresh the state of the animations. * Useful to make the animations running in a blocking process where diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_private.h new file mode 100644 index 000000000..5c2585017 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_private.h @@ -0,0 +1,56 @@ +/** + * @file lv_anim_private.h + * + */ + +#ifndef LV_ANIM_PRIVATE_H +#define LV_ANIM_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_anim.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + bool anim_list_changed; + bool anim_run_round; + lv_timer_t * timer; + lv_ll_t anim_ll; +} lv_anim_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init the animation module + */ +void lv_anim_core_init(void); + +/** + * Deinit the animation module + */ +void lv_anim_core_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.c index 0acd24312..f9cd53056 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "lv_anim_private.h" #include "lv_assert.h" #include "lv_anim_timeline.h" #include "../stdlib/lv_mem.h" @@ -22,14 +23,18 @@ typedef struct { lv_anim_t anim; uint32_t start_time; + uint8_t is_started : 1; + uint8_t is_completed : 1; } lv_anim_timeline_dsc_t; /*Data of anim_timeline*/ -struct _lv_anim_timeline_t { +struct lv_anim_timeline_t { lv_anim_timeline_dsc_t * anim_dsc; /**< Dynamically allocated anim dsc array*/ uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/ uint32_t act_time; /**< Current time of the animation*/ bool reverse; /**< Reverse playback*/ + uint32_t repeat_count; /**< Repeat count*/ + uint32_t repeat_delay; /**< Wait before repeat*/ }; /********************** @@ -86,10 +91,19 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at) LV_ASSERT_NULL(at); uint32_t playtime = lv_anim_timeline_get_playtime(at); + uint32_t repeat = at->repeat_count; + uint32_t delay = at->repeat_delay; uint32_t start = at->act_time; uint32_t end = at->reverse ? 0 : playtime; uint32_t duration = end > start ? end - start : start - end; + if((!at->reverse && at->act_time == 0) || (at->reverse && at->act_time == playtime)) { + for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) { + at->anim_dsc[i].is_started = 0; + at->anim_dsc[i].is_completed = 0; + } + } + lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, at); @@ -97,6 +111,8 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at) lv_anim_set_values(&a, start, end); lv_anim_set_time(&a, duration); lv_anim_set_path_cb(&a, anim_timeline_path_cb); + lv_anim_set_repeat_count(&a, repeat); + lv_anim_set_repeat_delay(&a, delay); lv_anim_start(&a); return playtime; } @@ -114,6 +130,18 @@ void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse) at->reverse = reverse; } +void lv_anim_timeline_set_repeat_count(lv_anim_timeline_t * at, uint32_t cnt) +{ + LV_ASSERT_NULL(at); + at->repeat_count = cnt; +} + +void lv_anim_timeline_set_repeat_delay(lv_anim_timeline_t * at, uint32_t delay) +{ + LV_ASSERT_NULL(at); + at->repeat_delay = delay; +} + void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress) { LV_ASSERT_NULL(at); @@ -154,6 +182,18 @@ uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at) return lv_map(at->act_time, 0, playtime, 0, LV_ANIM_TIMELINE_PROGRESS_MAX); } +uint32_t lv_anim_timeline_get_repeat_count(lv_anim_timeline_t * at) +{ + LV_ASSERT_NULL(at); + return at->repeat_count; +} + +uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at) +{ + LV_ASSERT_NULL(at); + return at->repeat_delay; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -161,30 +201,99 @@ uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at) static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_time) { at->act_time = act_time; + bool anim_timeline_is_started = (lv_anim_get(at, anim_timeline_exec_cb) != NULL); for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) { - lv_anim_t * a = &(at->anim_dsc[i].anim); + lv_anim_timeline_dsc_t * anim_dsc = &(at->anim_dsc[i]); + lv_anim_t * a = &(anim_dsc->anim); if(a->exec_cb == NULL && a->custom_exec_cb == NULL) { continue; } - uint32_t start_time = at->anim_dsc[i].start_time; + uint32_t start_time = anim_dsc->start_time; int32_t value = 0; + if(act_time < start_time && a->early_apply) { + if(anim_timeline_is_started) { + if(at->reverse) { + if(!anim_dsc->is_started && a->start_cb) a->start_cb(a); + anim_dsc->is_started = 1; + } + else { + anim_dsc->is_started = 0; + } + } + value = a->start_value; if(a->exec_cb) a->exec_cb(a->var, value); if(a->custom_exec_cb) a->custom_exec_cb(a, value); + + if(anim_timeline_is_started) { + if(at->reverse) { + if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a); + anim_dsc->is_completed = 1; + } + else { + anim_dsc->is_completed = 0; + } + } } else if(act_time >= start_time && act_time <= (start_time + a->duration)) { + if(anim_timeline_is_started) { + if(!anim_dsc->is_started && a->start_cb) a->start_cb(a); + anim_dsc->is_started = 1; + } + a->act_time = act_time - start_time; value = a->path_cb(a); if(a->exec_cb) a->exec_cb(a->var, value); if(a->custom_exec_cb) a->custom_exec_cb(a, value); + + if(anim_timeline_is_started) { + if(at->reverse) { + if(act_time == start_time) { + if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a); + anim_dsc->is_completed = 1; + } + else { + anim_dsc->is_completed = 0; + } + } + else { + if(act_time == (start_time + a->duration)) { + if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a); + anim_dsc->is_completed = 1; + } + else { + anim_dsc->is_completed = 0; + } + } + } } else if(act_time > start_time + a->duration) { + if(anim_timeline_is_started) { + if(at->reverse) { + anim_dsc->is_started = 0; + } + else { + if(!anim_dsc->is_started && a->start_cb) a->start_cb(a); + anim_dsc->is_started = 1; + } + } + value = a->end_value; if(a->exec_cb) a->exec_cb(a->var, value); if(a->custom_exec_cb) a->custom_exec_cb(a, value); + + if(anim_timeline_is_started) { + if(at->reverse) { + anim_dsc->is_completed = 0; + } + else { + if(!anim_dsc->is_completed && a->completed_cb) a->completed_cb(a); + anim_dsc->is_completed = 1; + } + } } } } diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.h index dd2707041..e8fd8be73 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim_timeline.h @@ -25,7 +25,7 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct _lv_anim_timeline_t lv_anim_timeline_t; +typedef struct lv_anim_timeline_t lv_anim_timeline_t; /********************** * GLOBAL PROTOTYPES @@ -71,6 +71,20 @@ void lv_anim_timeline_pause(lv_anim_timeline_t * at); */ void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse); +/** + * Make the animation timeline repeat itself. + * @param at pointer to the animation timeline. + * @param cnt repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: to disable repetition. + */ +void lv_anim_timeline_set_repeat_count(lv_anim_timeline_t * at, uint32_t cnt); + +/** + * Set a delay before repeating the animation timeline. + * @param at pointer to the animation timeline. + * @param delay delay in milliseconds before repeating the animation timeline. + */ +void lv_anim_timeline_set_repeat_delay(lv_anim_timeline_t * at, uint32_t delay); + /** * Set the progress of the animation timeline. * @param at pointer to the animation timeline. @@ -99,6 +113,18 @@ bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at); */ uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at); +/** + * Get repeat count of the animation timeline. + * @param at pointer to the animation timeline. + */ +uint32_t lv_anim_timeline_get_repeat_count(lv_anim_timeline_t * at); + +/** + * Get repeat delay of the animation timeline. + * @param at pointer to the animation timeline. + */ +uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c index 3cfd12144..4410076d6 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c @@ -9,7 +9,7 @@ #include "../lv_conf_internal.h" #include "../core/lv_global.h" -#include "lv_area.h" +#include "lv_area_private.h" #include "lv_math.h" /********************* @@ -56,7 +56,7 @@ void lv_area_set_height(lv_area_t * area_p, int32_t h) area_p->y2 = area_p->y1 + h - 1; } -void _lv_area_set_pos(lv_area_t * area_p, int32_t x, int32_t y) +void lv_area_set_pos(lv_area_t * area_p, int32_t x, int32_t y) { int32_t w = lv_area_get_width(area_p); int32_t h = lv_area_get_height(area_p); @@ -91,7 +91,7 @@ void lv_area_move(lv_area_t * area, int32_t x_ofs, int32_t y_ofs) area->y2 += y_ofs; } -bool _lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p) +bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p) { /*Get the smaller area from 'a1_p' and 'a2_p'*/ res_p->x1 = LV_MAX(a1_p->x1, a2_p->x1); @@ -108,13 +108,13 @@ bool _lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area return union_ok; } -int8_t _lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * a2_p) +int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * a2_p) { /*Areas have no common parts*/ - if(!_lv_area_is_on(a1_p, a2_p)) return -1; + if(!lv_area_is_on(a1_p, a2_p)) return -1; /*No remaining areas after removing common parts*/ - if(_lv_area_is_in(a1_p, a2_p, 0)) return 0; + if(lv_area_is_in(a1_p, a2_p, 0)) return 0; /*Result counter*/ int8_t res_c = 0; @@ -173,7 +173,7 @@ int8_t _lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t return res_c; } -void _lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p) +void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p) { a_res_p->x1 = LV_MIN(a1_p->x1, a2_p->x1); a_res_p->y1 = LV_MIN(a1_p->y1, a2_p->y1); @@ -181,7 +181,7 @@ void _lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t a_res_p->y2 = LV_MAX(a1_p->y2, a2_p->y2); } -bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t radius) +bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t radius) { /*First check the basic area*/ bool is_on_rect = false; @@ -208,7 +208,7 @@ bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t corner_area.x2 = a_p->x1 + radius; corner_area.y1 = a_p->y1; corner_area.y2 = a_p->y1 + radius; - if(_lv_area_is_point_on(&corner_area, p_p, 0)) { + if(lv_area_is_point_on(&corner_area, p_p, 0)) { corner_area.x2 += radius; corner_area.y2 += radius; return lv_point_within_circle(&corner_area, p_p); @@ -216,7 +216,7 @@ bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t /*Bottom left*/ corner_area.y1 = a_p->y2 - radius; corner_area.y2 = a_p->y2; - if(_lv_area_is_point_on(&corner_area, p_p, 0)) { + if(lv_area_is_point_on(&corner_area, p_p, 0)) { corner_area.x2 += radius; corner_area.y1 -= radius; return lv_point_within_circle(&corner_area, p_p); @@ -224,7 +224,7 @@ bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t /*Bottom right*/ corner_area.x1 = a_p->x2 - radius; corner_area.x2 = a_p->x2; - if(_lv_area_is_point_on(&corner_area, p_p, 0)) { + if(lv_area_is_point_on(&corner_area, p_p, 0)) { corner_area.x1 -= radius; corner_area.y1 -= radius; return lv_point_within_circle(&corner_area, p_p); @@ -232,7 +232,7 @@ bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t /*Top right*/ corner_area.y1 = a_p->y1; corner_area.y2 = a_p->y1 + radius; - if(_lv_area_is_point_on(&corner_area, p_p, 0)) { + if(lv_area_is_point_on(&corner_area, p_p, 0)) { corner_area.x1 -= radius; corner_area.y2 += radius; return lv_point_within_circle(&corner_area, p_p); @@ -241,7 +241,7 @@ bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t return true; } -bool _lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p) +bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p) { if((a1_p->x1 <= a2_p->x2) && (a1_p->x2 >= a2_p->x1) && (a1_p->y1 <= a2_p->y2) && (a1_p->y2 >= a2_p->y1)) { return true; @@ -251,7 +251,7 @@ bool _lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p) } } -bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, int32_t radius) +bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, int32_t radius) { bool is_in = false; @@ -267,21 +267,21 @@ bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, int32_ lv_point_t p; lv_point_set(&p, ain_p->x1, ain_p->y1); - if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false; + if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false; lv_point_set(&p, ain_p->x2, ain_p->y1); - if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false; + if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false; lv_point_set(&p, ain_p->x1, ain_p->y2); - if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false; + if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false; lv_point_set(&p, ain_p->x2, ain_p->y2); - if(_lv_area_is_point_on(aholder_p, &p, radius) == false) return false; + if(lv_area_is_point_on(aholder_p, &p, radius) == false) return false; return true; } -bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, int32_t radius) +bool lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, int32_t radius) { if(aout_p->x2 < aholder_p->x1 || aout_p->y2 < aholder_p->y1 || aout_p->x1 > aholder_p->x2 || aout_p->y1 > aholder_p->y2) { @@ -294,21 +294,21 @@ bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, int3 lv_point_t p; lv_point_set(&p, aout_p->x1, aout_p->y1); - if(_lv_area_is_point_on(aholder_p, &p, radius)) return false; + if(lv_area_is_point_on(aholder_p, &p, radius)) return false; lv_point_set(&p, aout_p->x2, aout_p->y1); - if(_lv_area_is_point_on(aholder_p, &p, radius)) return false; + if(lv_area_is_point_on(aholder_p, &p, radius)) return false; lv_point_set(&p, aout_p->x1, aout_p->y2); - if(_lv_area_is_point_on(aholder_p, &p, radius)) return false; + if(lv_area_is_point_on(aholder_p, &p, radius)) return false; lv_point_set(&p, aout_p->x2, aout_p->y2); - if(_lv_area_is_point_on(aholder_p, &p, radius)) return false; + if(lv_area_is_point_on(aholder_p, &p, radius)) return false; return true; } -bool _lv_area_is_equal(const lv_area_t * a, const lv_area_t * b) +bool lv_area_is_equal(const lv_area_t * a, const lv_area_t * b) { return a->x1 == b->x1 && a->x2 == b->x2 && a->y1 == b->y1 && a->y2 == b->y2; } @@ -438,7 +438,7 @@ void lv_area_align(const lv_area_t * base, lv_area_t * to_align, lv_align_t alig to_align->y2 = to_align->y1 + h - 1; } -#define _LV_TRANSFORM_TRIGO_SHIFT 10 +#define LV_TRANSFORM_TRIGO_SHIFT 10 void lv_point_transform(lv_point_t * point, int32_t angle, int32_t scale_x, int32_t scale_y, const lv_point_t * pivot, bool zoom_first) @@ -483,32 +483,100 @@ void lv_point_array_transform(lv_point_t * points, size_t count, int32_t angle, int32_t c2 = lv_trigo_sin(angle_high + 90); int32_t sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10; - sinma = sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT); + sinma = sinma >> (LV_TRIGO_SHIFT - LV_TRANSFORM_TRIGO_SHIFT); int32_t cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10; - cosma = cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT); + cosma = cosma >> (LV_TRIGO_SHIFT - LV_TRANSFORM_TRIGO_SHIFT); for(i = 0; i < count; i++) { int32_t x = points[i].x; int32_t y = points[i].y; if(scale_x == 256 && scale_y == 256) { - points[i].x = ((cosma * x - sinma * y) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; - points[i].y = ((sinma * x + cosma * y) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; + points[i].x = ((cosma * x - sinma * y) >> LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; + points[i].y = ((sinma * x + cosma * y) >> LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; } else { if(zoom_first) { x *= scale_x; y *= scale_y; - points[i].x = (((cosma * x - sinma * y)) >> (_LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->x; - points[i].y = (((sinma * x + cosma * y)) >> (_LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->y; + points[i].x = (((cosma * x - sinma * y)) >> (LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->x; + points[i].y = (((sinma * x + cosma * y)) >> (LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->y; } else { - points[i].x = (((cosma * x - sinma * y) * scale_x) >> (_LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->x; - points[i].y = (((sinma * x + cosma * y) * scale_y) >> (_LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->y; + points[i].x = (((cosma * x - sinma * y) * scale_x) >> (LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->x; + points[i].y = (((sinma * x + cosma * y) * scale_y) >> (LV_TRANSFORM_TRIGO_SHIFT + 8)) + pivot->y; } } } } +int32_t lv_area_get_width(const lv_area_t * area_p) +{ + return (int32_t)(area_p->x2 - area_p->x1 + 1); +} + +int32_t lv_area_get_height(const lv_area_t * area_p) +{ + return (int32_t)(area_p->y2 - area_p->y1 + 1); +} + +lv_point_t lv_point_from_precise(const lv_point_precise_t * p) +{ + lv_point_t point = { + (int32_t)p->x, (int32_t)p->y + }; + + return point; +} + +lv_point_precise_t lv_point_to_precise(const lv_point_t * p) +{ + lv_point_precise_t point = { + (lv_value_precise_t)p->x, (lv_value_precise_t)p->y + }; + + return point; +} + +void lv_point_set(lv_point_t * p, int32_t x, int32_t y) +{ + p->x = x; + p->y = y; +} + +void lv_point_precise_set(lv_point_precise_t * p, lv_value_precise_t x, lv_value_precise_t y) +{ + p->x = x; + p->y = y; +} + +void lv_point_swap(lv_point_t * p1, lv_point_t * p2) +{ + lv_point_t tmp = *p1; + *p1 = *p2; + *p2 = tmp; +} + +void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_precise_t * p2) +{ + lv_point_precise_t tmp = *p1; + *p1 = *p2; + *p2 = tmp; +} + +int32_t lv_pct(int32_t x) +{ + return LV_PCT(x); +} + +int32_t lv_pct_to_px(int32_t v, int32_t base) +{ + if(LV_COORD_IS_PCT(v)) { + return (LV_COORD_GET_PCT(v) * base) / 100; + } + + return v; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_area.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_area.h index 376ab9f6e..0798c74fb 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_area.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_area.h @@ -15,9 +15,7 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" #include "lv_types.h" -#include -#include -#include +#include "lv_math.h" /********************* * DEFINES @@ -50,7 +48,7 @@ typedef struct { /** Alignments*/ -enum _lv_align_t { +typedef enum { LV_ALIGN_DEFAULT = 0, LV_ALIGN_TOP_LEFT, LV_ALIGN_TOP_MID, @@ -74,15 +72,9 @@ enum _lv_align_t { LV_ALIGN_OUT_RIGHT_TOP, LV_ALIGN_OUT_RIGHT_MID, LV_ALIGN_OUT_RIGHT_BOTTOM, -}; +} lv_align_t; -#ifdef DOXYGEN -typedef _lv_align_t lv_align_t; -#else -typedef uint8_t lv_align_t; -#endif /*DOXYGEN*/ - -enum _lv_dir_t { +typedef enum { LV_DIR_NONE = 0x00, LV_DIR_LEFT = (1 << 0), LV_DIR_RIGHT = (1 << 1), @@ -91,13 +83,7 @@ enum _lv_dir_t { LV_DIR_HOR = LV_DIR_LEFT | LV_DIR_RIGHT, LV_DIR_VER = LV_DIR_TOP | LV_DIR_BOTTOM, LV_DIR_ALL = LV_DIR_HOR | LV_DIR_VER, -}; - -#ifdef DOXYGEN -typedef _lv_dir_t lv_dir_t; -#else -typedef uint8_t lv_dir_t; -#endif /*DOXYGEN*/ +} lv_dir_t; /********************** * GLOBAL PROTOTYPES @@ -131,20 +117,14 @@ inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src) * @param area_p pointer to an area * @return the width of the area (if x1 == x2 -> width = 1) */ -static inline int32_t lv_area_get_width(const lv_area_t * area_p) -{ - return (int32_t)(area_p->x2 - area_p->x1 + 1); -} +int32_t lv_area_get_width(const lv_area_t * area_p); /** * Get the height of an area * @param area_p pointer to an area * @return the height of the area (if y1 == y2 -> height = 1) */ -static inline int32_t lv_area_get_height(const lv_area_t * area_p) -{ - return (int32_t)(area_p->y2 - area_p->y1 + 1); -} +int32_t lv_area_get_height(const lv_area_t * area_p); /** * Set the width of an area @@ -160,14 +140,6 @@ void lv_area_set_width(lv_area_t * area_p, int32_t w); */ void lv_area_set_height(lv_area_t * area_p, int32_t h); -/** - * Set the position of an area (width and height will be kept) - * @param area_p pointer to an area - * @param x the new x coordinate of the area - * @param y the new y coordinate of the area - */ -void _lv_area_set_pos(lv_area_t * area_p, int32_t x, int32_t y); - /** * Return with area of an area (x * y) * @param area_p pointer to an area @@ -180,75 +152,7 @@ void lv_area_increase(lv_area_t * area, int32_t w_extra, int32_t h_extra); void lv_area_move(lv_area_t * area, int32_t x_ofs, int32_t y_ofs); /** - * Get the common parts of two areas - * @param res_p pointer to an area, the result will be stored her - * @param a1_p pointer to the first area - * @param a2_p pointer to the second area - * @return false: the two area has NO common parts, res_p is invalid - */ -bool _lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p); - -/** - * Get resulting sub areas after removing the common parts of two areas from the first area - * @param res_p pointer to an array of areas with a count of 4, the resulting areas will be stored here - * @param a1_p pointer to the first area - * @param a2_p pointer to the second area - * @return number of results (max 4) or -1 if no intersect - */ -int8_t _lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * a2_p); - -/** - * Join two areas into a third which involves the other two - * @param a_res_p pointer to an area, the result will be stored here - * @param a1_p pointer to the first area - * @param a2_p pointer to the second area - */ -void _lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p); - -/** - * Check if a point is on an area - * @param a_p pointer to an area - * @param p_p pointer to a point - * @param radius radius of area (e.g. for rounded rectangle) - * @return false:the point is out of the area - */ -bool _lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t radius); - -/** - * Check if two area has common parts - * @param a1_p pointer to an area. - * @param a2_p pointer to an other area - * @return false: a1_p and a2_p has no common parts - */ -bool _lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p); - -/** - * Check if an area is fully on an other - * @param ain_p pointer to an area which could be in 'aholder_p' - * @param aholder_p pointer to an area which could involve 'ain_p' - * @param radius radius of `aholder_p` (e.g. for rounded rectangle) - * @return true: `ain_p` is fully inside `aholder_p` - */ -bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, int32_t radius); - -/** - * Check if an area is fully out of an other - * @param aout_p pointer to an area which could be in 'aholder_p' - * @param aholder_p pointer to an area which could involve 'ain_p' - * @param radius radius of `aholder_p` (e.g. for rounded rectangle) - * @return true: `aout_p` is fully outside `aholder_p` - */ -bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, int32_t radius); - -/** - * Check if 2 area is the same - * @param a pointer to an area - * @param b pointer to another area - */ -bool _lv_area_is_equal(const lv_area_t * a, const lv_area_t * b); - -/** - * Align an area to an other + * Align an area to another * @param base an area where the other will be aligned * @param to_align the area to align * @param align `LV_ALIGN_...` @@ -264,7 +168,7 @@ void lv_area_align(const lv_area_t * base, lv_area_t * to_align, lv_align_t alig * @param scale_x horizontal zoom, 256 means 100% * @param scale_y vertical zoom, 256 means 100% * @param pivot pointer to the pivot point of the transformation - * @param zoom_first true: zoom first and rotate after that; else: opssoite order + * @param zoom_first true: zoom first and rotate after that; else: opposite order */ void lv_point_transform(lv_point_t * point, int32_t angle, int32_t scale_x, int32_t scale_y, const lv_point_t * pivot, bool zoom_first); @@ -277,89 +181,61 @@ void lv_point_transform(lv_point_t * point, int32_t angle, int32_t scale_x, int3 * @param scale_x horizontal zoom, 256 means 100% * @param scale_y vertical zoom, 256 means 100% * @param pivot pointer to the pivot point of the transformation - * @param zoom_first true: zoom first and rotate after that; else: opssoite order + * @param zoom_first true: zoom first and rotate after that; else: opposite order */ void lv_point_array_transform(lv_point_t * points, size_t count, int32_t angle, int32_t scale_x, int32_t scale_y, const lv_point_t * pivot, bool zoom_first); -static inline lv_point_t lv_point_from_precise(const lv_point_precise_t * p) -{ - lv_point_t point = { - (int32_t)p->x, (int32_t)p->y - }; +lv_point_t lv_point_from_precise(const lv_point_precise_t * p); - return point; -} +lv_point_precise_t lv_point_to_precise(const lv_point_t * p); -static inline lv_point_precise_t lv_point_to_precise(const lv_point_t * p) -{ - lv_point_precise_t point = { - (lv_value_precise_t)p->x, (lv_value_precise_t)p->y - }; +void lv_point_set(lv_point_t * p, int32_t x, int32_t y); - return point; -} +void lv_point_precise_set(lv_point_precise_t * p, lv_value_precise_t x, lv_value_precise_t y); -static inline void lv_point_set(lv_point_t * p, int32_t x, int32_t y) -{ - p->x = x; - p->y = y; -} +void lv_point_swap(lv_point_t * p1, lv_point_t * p2); -static inline void lv_point_precise_set(lv_point_precise_t * p, lv_value_precise_t x, lv_value_precise_t y) -{ - p->x = x; - p->y = y; -} - -static inline void lv_point_swap(lv_point_t * p1, lv_point_t * p2) -{ - lv_point_t tmp = *p1; - *p1 = *p2; - *p2 = tmp; -} - -static inline void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_precise_t * p2) -{ - lv_point_precise_t tmp = *p1; - *p1 = *p2; - *p2 = tmp; -} +void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_precise_t * p2); /********************** * MACROS **********************/ -#define _LV_COORD_TYPE_SHIFT (29U) +#define LV_COORD_TYPE_SHIFT (29U) -#define _LV_COORD_TYPE_MASK (3 << _LV_COORD_TYPE_SHIFT) -#define _LV_COORD_TYPE(x) ((x) & _LV_COORD_TYPE_MASK) /*Extract type specifiers*/ -#define _LV_COORD_PLAIN(x) ((x) & ~_LV_COORD_TYPE_MASK) /*Remove type specifiers*/ +#define LV_COORD_TYPE_MASK (3 << LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE(x) ((x) & LV_COORD_TYPE_MASK) /*Extract type specifiers*/ +#define LV_COORD_PLAIN(x) ((x) & ~LV_COORD_TYPE_MASK) /*Remove type specifiers*/ -#define _LV_COORD_TYPE_PX (0 << _LV_COORD_TYPE_SHIFT) -#define _LV_COORD_TYPE_SPEC (1 << _LV_COORD_TYPE_SHIFT) -#define _LV_COORD_TYPE_PX_NEG (3 << _LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE_PX (0 << LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE_SPEC (1 << LV_COORD_TYPE_SHIFT) +#define LV_COORD_TYPE_PX_NEG (3 << LV_COORD_TYPE_SHIFT) -#define LV_COORD_IS_PX(x) (_LV_COORD_TYPE(x) == _LV_COORD_TYPE_PX || _LV_COORD_TYPE(x) == _LV_COORD_TYPE_PX_NEG) -#define LV_COORD_IS_SPEC(x) (_LV_COORD_TYPE(x) == _LV_COORD_TYPE_SPEC) +#define LV_COORD_IS_PX(x) (LV_COORD_TYPE(x) == LV_COORD_TYPE_PX || LV_COORD_TYPE(x) == LV_COORD_TYPE_PX_NEG) +#define LV_COORD_IS_SPEC(x) (LV_COORD_TYPE(x) == LV_COORD_TYPE_SPEC) -#define LV_COORD_SET_SPEC(x) ((x) | _LV_COORD_TYPE_SPEC) +#define LV_COORD_SET_SPEC(x) ((x) | LV_COORD_TYPE_SPEC) + +/** Max coordinate value */ +#define LV_COORD_MAX ((1 << LV_COORD_TYPE_SHIFT) - 1) +#define LV_COORD_MIN (-LV_COORD_MAX) /*Special coordinates*/ -#define LV_PCT(x) (x < 0 ? LV_COORD_SET_SPEC(1000 - (x)) : LV_COORD_SET_SPEC(x)) -#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && _LV_COORD_PLAIN(x) <= 2000)) -#define LV_COORD_GET_PCT(x) (_LV_COORD_PLAIN(x) > 1000 ? 1000 - _LV_COORD_PLAIN(x) : _LV_COORD_PLAIN(x)) -#define LV_SIZE_CONTENT LV_COORD_SET_SPEC(2001) - -LV_EXPORT_CONST_INT(LV_SIZE_CONTENT); - -/*Max coordinate value*/ -#define LV_COORD_MAX ((1 << _LV_COORD_TYPE_SHIFT) - 1) -#define LV_COORD_MIN (-LV_COORD_MAX) +#define LV_SIZE_CONTENT LV_COORD_SET_SPEC(LV_COORD_MAX) +#define LV_PCT_STORED_MAX (LV_COORD_MAX - 1) +#if LV_PCT_STORED_MAX % 2 != 0 +#error LV_PCT_STORED_MAX should be an even number +#endif +#define LV_PCT_POS_MAX (LV_PCT_STORED_MAX / 2) +#define LV_PCT(x) (LV_COORD_SET_SPEC(((x) < 0 ? (LV_PCT_POS_MAX - LV_MAX((x), -LV_PCT_POS_MAX)) : LV_MIN((x), LV_PCT_POS_MAX)))) +#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && LV_COORD_PLAIN(x) <= LV_PCT_STORED_MAX)) +#define LV_COORD_GET_PCT(x) (LV_COORD_PLAIN(x) > LV_PCT_POS_MAX ? LV_PCT_POS_MAX - LV_COORD_PLAIN(x) : LV_COORD_PLAIN(x)) LV_EXPORT_CONST_INT(LV_COORD_MAX); LV_EXPORT_CONST_INT(LV_COORD_MIN); +LV_EXPORT_CONST_INT(LV_SIZE_CONTENT); /** * Convert a percentage value to `int32_t`. @@ -367,19 +243,9 @@ LV_EXPORT_CONST_INT(LV_COORD_MIN); * @param x the percentage (0..1000) * @return a coordinate that stores the percentage */ -static inline int32_t lv_pct(int32_t x) -{ - return LV_PCT(x); -} +int32_t lv_pct(int32_t x); -static inline int32_t lv_pct_to_px(int32_t v, int32_t base) -{ - if(LV_COORD_IS_PCT(v)) { - return (LV_COORD_GET_PCT(v) * base) / 100; - } - - return v; -} +int32_t lv_pct_to_px(int32_t v, int32_t base); #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_area_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_area_private.h new file mode 100644 index 000000000..bebca5940 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_area_private.h @@ -0,0 +1,115 @@ +/** + * @file lv_area_private.h + * + */ + +#ifndef LV_AREA_PRIVATE_H +#define LV_AREA_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_area.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Set the position of an area (width and height will be kept) + * @param area_p pointer to an area + * @param x the new x coordinate of the area + * @param y the new y coordinate of the area + */ +void lv_area_set_pos(lv_area_t * area_p, int32_t x, int32_t y); + +/** + * Get the common parts of two areas + * @param res_p pointer to an area, the result will be stored her + * @param a1_p pointer to the first area + * @param a2_p pointer to the second area + * @return false: the two area has NO common parts, res_p is invalid + */ +bool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Get resulting sub areas after removing the common parts of two areas from the first area + * @param res_p pointer to an array of areas with a count of 4, the resulting areas will be stored here + * @param a1_p pointer to the first area + * @param a2_p pointer to the second area + * @return number of results (max 4) or -1 if no intersect + */ +int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Join two areas into a third which involves the other two + * @param a_res_p pointer to an area, the result will be stored here + * @param a1_p pointer to the first area + * @param a2_p pointer to the second area + */ +void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Check if a point is on an area + * @param a_p pointer to an area + * @param p_p pointer to a point + * @param radius radius of area (e.g. for rounded rectangle) + * @return false:the point is out of the area + */ +bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p, int32_t radius); + +/** + * Check if two area has common parts + * @param a1_p pointer to an area. + * @param a2_p pointer to another area + * @return false: a1_p and a2_p has no common parts + */ +bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p); + +/** + * Check if an area is fully on another + * @param ain_p pointer to an area which could be in 'aholder_p' + * @param aholder_p pointer to an area which could involve 'ain_p' + * @param radius radius of `aholder_p` (e.g. for rounded rectangle) + * @return true: `ain_p` is fully inside `aholder_p` + */ +bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, int32_t radius); + +/** + * Check if an area is fully out of another + * @param aout_p pointer to an area which could be in 'aholder_p' + * @param aholder_p pointer to an area which could involve 'ain_p' + * @param radius radius of `aholder_p` (e.g. for rounded rectangle) + * @return true: `aout_p` is fully outside `aholder_p` + */ +bool lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, int32_t radius); + +/** + * Check if 2 area is the same + * @param a pointer to an area + * @param b pointer to another area + */ +bool lv_area_is_equal(const lv_area_t * a, const lv_area_t * b); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_AREA_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c index cb9620503..39382bcbf 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c @@ -67,6 +67,13 @@ void lv_array_copy(lv_array_t * target, const lv_array_t * source) target->size = source->size; } +void lv_array_shrink(lv_array_t * array) +{ + if(array->size <= array->capacity / LV_ARRAY_DEFAULT_SHRINK_RATIO) { + lv_array_resize(array, array->size); + } +} + lv_result_t lv_array_remove(lv_array_t * array, uint32_t index) { if(index >= array->size) { @@ -75,7 +82,8 @@ lv_result_t lv_array_remove(lv_array_t * array, uint32_t index) /*Shortcut*/ if(index == array->size - 1) { - lv_array_resize(array, array->size - 1); + array->size--; + lv_array_shrink(array); return LV_RESULT_OK; } @@ -83,7 +91,8 @@ lv_result_t lv_array_remove(lv_array_t * array, uint32_t index) uint8_t * remaining = start + array->element_size; uint32_t remaining_size = (array->size - index - 1) * array->element_size; lv_memmove(start, remaining, remaining_size); - lv_array_resize(array, array->size - 1); + array->size--; + lv_array_shrink(array); return LV_RESULT_OK; } @@ -99,7 +108,8 @@ lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end) /*Shortcut*/ if(end == array->size) { - lv_array_resize(array, start); + array->size = start; + lv_array_shrink(array); return LV_RESULT_OK; } @@ -107,7 +117,8 @@ lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end) uint8_t * remaining = start_p + (end - start) * array->element_size; uint32_t remaining_size = (array->size - end) * array->element_size; lv_memcpy(start_p, remaining, remaining_size); - lv_array_resize(array, array->size - (end - start)); + array->size -= (end - start); + lv_array_shrink(array); return LV_RESULT_OK; } @@ -143,7 +154,7 @@ lv_result_t lv_array_push_back(lv_array_t * array, const void * element) if(array->size == array->capacity) { /*array is full*/ - lv_array_resize(array, array->capacity + 1); + lv_array_resize(array, array->capacity + LV_ARRAY_DEFAULT_CAPACITY); } uint8_t * data = array->data + array->size * array->element_size; @@ -170,3 +181,42 @@ lv_result_t lv_array_assign(lv_array_t * array, uint32_t index, const void * val lv_memcpy(data, value, array->element_size); return LV_RESULT_OK; } + +uint32_t lv_array_size(const lv_array_t * array) +{ + return array->size; +} + +uint32_t lv_array_capacity(const lv_array_t * array) +{ + return array->capacity; +} + +bool lv_array_is_empty(const lv_array_t * array) +{ + return array->size == 0; +} + +bool lv_array_is_full(const lv_array_t * array) +{ + return array->size == array->capacity; +} + +void lv_array_clear(lv_array_t * array) +{ + array->size = 0; +} + +void * lv_array_front(const lv_array_t * array) +{ + return lv_array_at(array, 0); +} + +void * lv_array_back(const lv_array_t * array) +{ + return lv_array_at(array, lv_array_size(array) - 1); +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.h index 3cdb1c6c6..e63f56318 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.h @@ -13,16 +13,19 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include -#include - #include "lv_types.h" /********************* * DEFINES *********************/ -#define LV_ARRAY_DEFAULT_CAPACITY 8 + +#ifndef LV_ARRAY_DEFAULT_CAPACITY +#define LV_ARRAY_DEFAULT_CAPACITY 4 +#endif + +#ifndef LV_ARRAY_DEFAULT_SHRINK_RATIO +#define LV_ARRAY_DEFAULT_SHRINK_RATIO 2 +#endif /********************** * TYPEDEFS @@ -67,40 +70,28 @@ void lv_array_deinit(lv_array_t * array); * @param array pointer to an `lv_array_t` variable * @return the number of elements stored in the array */ -static inline uint32_t lv_array_size(const lv_array_t * array) -{ - return array->size; -} +uint32_t lv_array_size(const lv_array_t * array); /** * Return the capacity of the array, i.e. how many elements can be stored. * @param array pointer to an `lv_array_t` variable * @return the capacity of the array */ -static inline uint32_t lv_array_capacity(const lv_array_t * array) -{ - return array->capacity; -} +uint32_t lv_array_capacity(const lv_array_t * array); /** * Return if the array is empty * @param array pointer to an `lv_array_t` variable * @return true: array is empty; false: array is not empty */ -static inline bool lv_array_is_empty(const lv_array_t * array) -{ - return array->size == 0; -} +bool lv_array_is_empty(const lv_array_t * array); /** * Return if the array is full * @param array pointer to an `lv_array_t` variable * @return true: array is full; false: array is not full */ -static inline bool lv_array_is_full(const lv_array_t * array) -{ - return array->size == array->capacity; -} +bool lv_array_is_full(const lv_array_t * array); /** * Copy an array to another. @@ -114,10 +105,13 @@ void lv_array_copy(lv_array_t * target, const lv_array_t * source); * Remove all elements in array. * @param array pointer to an `lv_array_t` variable */ -static inline void lv_array_clear(lv_array_t * array) -{ - array->size = 0; -} +void lv_array_clear(lv_array_t * array); + +/** + * Shrink the memory capacity of array if necessary. + * @param array pointer to an `lv_array_t` variable + */ +void lv_array_shrink(lv_array_t * array); /** * Remove the element at the specified position in the array. @@ -178,19 +172,13 @@ void * lv_array_at(const lv_array_t * array, uint32_t index); * @param array pointer to an `lv_array_t` variable * @return a pointer to the first element in the array */ -static inline void * lv_array_front(const lv_array_t * array) -{ - return lv_array_at(array, 0); -} +void * lv_array_front(const lv_array_t * array); /** * Returns a pointer to the last element in the array. * @param array pointer to an `lv_array_t` variable */ -static inline void * lv_array_back(const lv_array_t * array) -{ - return lv_array_at(array, lv_array_size(array) - 1); -} +void * lv_array_back(const lv_array_t * array); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c index 591d2303f..e1657aeb4 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c @@ -8,7 +8,7 @@ *********************/ #include "lv_async.h" -#include "lv_timer.h" +#include "lv_timer_private.h" #include "../stdlib/lv_mem.h" /********************* @@ -19,7 +19,7 @@ * TYPEDEFS **********************/ -typedef struct _lv_async_info_t { +typedef struct lv_async_info_t { lv_async_cb_t cb; void * user_data; } lv_async_info_t; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.c index 1fa374dfc..44f014e28 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.c @@ -6,9 +6,9 @@ /********************* * INCLUDES *********************/ -#include -#include "lv_bidi.h" -#include "lv_text.h" +#include "lv_bidi_private.h" +#include "lv_text_private.h" +#include "lv_types.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" @@ -17,7 +17,7 @@ /********************* * DEFINES *********************/ -#define LV_BIDI_BRACKLET_DEPTH 4 +#define LV_BIDI_BRACKET_DEPTH 4 // Highest bit of the 16-bit pos_conv value specifies whether this pos is RTL or not #define GET_POS(x) ((x) & 0x7FFF) @@ -28,12 +28,12 @@ * TYPEDEFS **********************/ typedef struct { - uint32_t bracklet_pos; + uint32_t bracket_pos; lv_base_dir_t dir; } bracket_stack_t; typedef struct { - bracket_stack_t br_stack[LV_BIDI_BRACKLET_DEPTH]; + bracket_stack_t br_stack[LV_BIDI_BRACKET_DEPTH]; uint8_t br_stack_p; } lv_bidi_ctx_t; @@ -64,6 +64,7 @@ static uint32_t get_txt_len(const char * txt, uint32_t max_len); **********************/ static const uint8_t bracket_left[] = {"<({["}; static const uint8_t bracket_right[] = {">)}]"}; +static const char * custom_neutrals = NULL; /********************** * MACROS @@ -73,9 +74,9 @@ static const uint8_t bracket_right[] = {">)}]"}; * GLOBAL FUNCTIONS **********************/ -void _lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_dir) +void lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_dir) { - if(base_dir == LV_BASE_DIR_AUTO) base_dir = _lv_bidi_detect_base_dir(str_in); + if(base_dir == LV_BASE_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in); uint32_t par_start = 0; uint32_t par_len; @@ -87,7 +88,7 @@ void _lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_di while(str_in[par_start] != '\0') { par_len = lv_bidi_get_next_paragraph(&str_in[par_start]); - _lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0); + lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0); par_start += par_len; while(str_in[par_start] == '\n' || str_in[par_start] == '\r') { @@ -104,12 +105,12 @@ void _lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_di * @param txt the text to process * @return `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` */ -lv_base_dir_t _lv_bidi_detect_base_dir(const char * txt) +lv_base_dir_t lv_bidi_detect_base_dir(const char * txt) { uint32_t i = 0; uint32_t letter; while(txt[i] != '\0') { - letter = _lv_text_encoded_next(txt, &i); + letter = lv_text_encoded_next(txt, &i); lv_base_dir_t dir; dir = lv_bidi_get_letter_dir(letter); @@ -121,8 +122,8 @@ lv_base_dir_t _lv_bidi_detect_base_dir(const char * txt) else return LV_BIDI_BASE_DIR_DEF; } -uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_base_dir_t base_dir, - uint32_t visual_pos, bool * is_rtl) +uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_base_dir_t base_dir, + uint32_t visual_pos, bool * is_rtl) { uint32_t pos_conv_len = get_txt_len(str_in, len); char * buf = lv_malloc(len + 1); @@ -136,7 +137,7 @@ uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_ if(bidi_txt) *bidi_txt = buf; - _lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len); + lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len); if(is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]); @@ -146,8 +147,8 @@ uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_ return res; } -uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_base_dir_t base_dir, - uint32_t logical_pos, bool * is_rtl) +uint16_t lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_base_dir_t base_dir, + uint32_t logical_pos, bool * is_rtl) { uint32_t pos_conv_len = get_txt_len(str_in, len); char * buf = lv_malloc(len + 1); @@ -161,7 +162,7 @@ uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t if(bidi_txt) *bidi_txt = buf; - _lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len); + lv_bidi_process_paragraph(str_in, bidi_txt ? *bidi_txt : NULL, len, base_dir, pos_conv_buf, pos_conv_len); for(uint16_t i = 0; i < pos_conv_len; i++) { if(GET_POS(pos_conv_buf[i]) == logical_pos) { @@ -178,8 +179,8 @@ uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t return (uint16_t) -1; } -void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_base_dir_t base_dir, - uint16_t * pos_conv_out, uint16_t pos_conv_len) +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_base_dir_t base_dir, + uint16_t * pos_conv_out, uint16_t pos_conv_len) { uint32_t run_len = 0; lv_base_dir_t run_dir; @@ -189,7 +190,7 @@ void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t le uint16_t pos_conv_rd = 0; uint16_t pos_conv_wr; - if(base_dir == LV_BASE_DIR_AUTO) base_dir = _lv_bidi_detect_base_dir(str_in); + if(base_dir == LV_BASE_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in); if(base_dir == LV_BASE_DIR_RTL) { wr = len; pos_conv_wr = pos_conv_len; @@ -209,7 +210,7 @@ void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t le /*Process neutral chars in the beginning*/ while(rd < len) { - uint32_t letter = _lv_text_encoded_next(str_in, &rd); + uint32_t letter = lv_text_encoded_next(str_in, &rd); pos_conv_rd++; dir = lv_bidi_get_letter_dir(letter); if(dir == LV_BASE_DIR_NEUTRAL) dir = bracket_process(&ctx, str_in, rd, len, letter, base_dir); @@ -217,7 +218,7 @@ void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t le } if(rd && str_in[rd] != '\0' && rd < len) { - _lv_text_encoded_prev(str_in, &rd); + lv_text_encoded_prev(str_in, &rd); pos_conv_rd--; } @@ -273,7 +274,7 @@ void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t le void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, const char * txt) { - if(*base_dir == LV_BASE_DIR_AUTO) *base_dir = _lv_bidi_detect_base_dir(txt); + if(*base_dir == LV_BASE_DIR_AUTO) *base_dir = lv_bidi_detect_base_dir(txt); if(*align == LV_TEXT_ALIGN_AUTO) { if(*base_dir == LV_BASE_DIR_RTL) *align = LV_TEXT_ALIGN_RIGHT; @@ -281,6 +282,11 @@ void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, } } +void lv_bidi_set_custom_neutrals_static(const char * neutrals) +{ + custom_neutrals = neutrals; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -294,10 +300,10 @@ static uint32_t lv_bidi_get_next_paragraph(const char * txt) { uint32_t i = 0; - _lv_text_encoded_next(txt, &i); + lv_text_encoded_next(txt, &i); while(txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') { - _lv_text_encoded_next(txt, &i); + lv_text_encoded_next(txt, &i); } return i; @@ -327,7 +333,7 @@ static bool lv_bidi_letter_is_weak(uint32_t letter) static const char weaks[] = "0123456789"; do { - uint32_t x = _lv_text_encoded_next(weaks, &i); + uint32_t x = lv_text_encoded_next(weaks, &i); if(letter == x) { return true; } @@ -364,7 +370,11 @@ static bool lv_bidi_letter_is_rtl(uint32_t letter) static bool lv_bidi_letter_is_neutral(uint32_t letter) { uint16_t i; - static const char neutrals[] = " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|"; + const char * neutrals = " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|"; + if(custom_neutrals) { + neutrals = custom_neutrals; + } + for(i = 0; neutrals[i] != '\0'; i++) { if(letter == (uint32_t)neutrals[i]) return true; } @@ -378,7 +388,7 @@ static uint32_t get_txt_len(const char * txt, uint32_t max_len) uint32_t i = 0; while(i < max_len && txt[i] != '\0') { - _lv_text_encoded_next(txt, &i); + lv_text_encoded_next(txt, &i); len++; } @@ -403,13 +413,13 @@ static lv_base_dir_t get_next_run(lv_bidi_ctx_t * ctx, const char * txt, lv_base uint16_t pos_conv_i = 0; - letter = _lv_text_encoded_next(txt, NULL); + letter = lv_text_encoded_next(txt, NULL); lv_base_dir_t dir = lv_bidi_get_letter_dir(letter); if(dir == LV_BASE_DIR_NEUTRAL) dir = bracket_process(ctx, txt, 0, max_len, letter, base_dir); /*Find the first strong char. Skip the neutrals*/ while(dir == LV_BASE_DIR_NEUTRAL || dir == LV_BASE_DIR_WEAK) { - letter = _lv_text_encoded_next(txt, &i); + letter = lv_text_encoded_next(txt, &i); pos_conv_i++; dir = lv_bidi_get_letter_dir(letter); @@ -434,7 +444,7 @@ static lv_base_dir_t get_next_run(lv_bidi_ctx_t * ctx, const char * txt, lv_base /*Find the next char which has different direction*/ lv_base_dir_t next_dir = base_dir; while(i_prev < max_len && txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') { - letter = _lv_text_encoded_next(txt, &i); + letter = lv_text_encoded_next(txt, &i); pos_conv_i++; next_dir = lv_bidi_get_letter_dir(letter); if(next_dir == LV_BASE_DIR_NEUTRAL) next_dir = bracket_process(ctx, txt, i, max_len, letter, base_dir); @@ -497,7 +507,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t * uint16_t pos_conv_wr = 0; while(i) { - uint32_t letter = _lv_text_encoded_prev(src, &i); + uint32_t letter = lv_text_encoded_prev(src, &i); uint16_t pos_conv_letter = --pos_conv_i; /*Keep weak letters (numbers) as LTR*/ @@ -507,7 +517,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t * uint16_t pos_conv_last_weak = pos_conv_i; uint16_t pos_conv_first_weak = pos_conv_i; while(i) { - letter = _lv_text_encoded_prev(src, &i); + letter = lv_text_encoded_prev(src, &i); pos_conv_letter = --pos_conv_i; /*No need to call `char_change_to_pair` because there not such chars here*/ @@ -515,7 +525,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t * /*Finish on non-weak char*/ /*but treat number and currency related chars as weak*/ if(lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$' && letter != '%') { - _lv_text_encoded_next(src, &i); /*Rewind one letter*/ + lv_text_encoded_next(src, &i); /*Rewind one letter*/ pos_conv_i++; first_weak = i; pos_conv_first_weak = pos_conv_i; @@ -536,7 +546,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t * /*Simply store in reversed order*/ else { - uint32_t letter_size = _lv_text_encoded_size((const char *)&src[i]); + uint32_t letter_size = lv_text_encoded_size((const char *)&src[i]); /*Swap arithmetical symbols*/ if(letter_size == 1) { uint32_t new_letter = letter = char_change_to_pair(letter); @@ -585,7 +595,7 @@ static lv_base_dir_t bracket_process(lv_bidi_ctx_t * ctx, const char * txt, uint *If a char with base dir. direction is found then the brackets will have `base_dir` direction*/ uint32_t txt_i = next_pos; while(txt_i < len) { - uint32_t letter_next = _lv_text_encoded_next(txt, &txt_i); + uint32_t letter_next = lv_text_encoded_next(txt, &txt_i); if(letter_next == bracket_right[i]) { /*Closing bracket found*/ break; @@ -607,9 +617,9 @@ static lv_base_dir_t bracket_process(lv_bidi_ctx_t * ctx, const char * txt, uint /*If there were no matching strong chars in the brackets then check the previous chars*/ txt_i = next_pos; - if(txt_i) _lv_text_encoded_prev(txt, &txt_i); + if(txt_i) lv_text_encoded_prev(txt, &txt_i); while(txt_i > 0) { - uint32_t letter_next = _lv_text_encoded_prev(txt, &txt_i); + uint32_t letter_next = lv_text_encoded_prev(txt, &txt_i); lv_base_dir_t letter_dir = lv_bidi_get_letter_dir(letter_next); if(letter_dir == LV_BASE_DIR_LTR || letter_dir == LV_BASE_DIR_RTL) { bracket_dir = letter_dir; @@ -630,9 +640,9 @@ static lv_base_dir_t bracket_process(lv_bidi_ctx_t * ctx, const char * txt, uint /*The letter was an opening bracket*/ if(bracket_left[i] != '\0') { - if(bracket_dir == LV_BASE_DIR_NEUTRAL || ctx->br_stack_p == LV_BIDI_BRACKLET_DEPTH) return LV_BASE_DIR_NEUTRAL; + if(bracket_dir == LV_BASE_DIR_NEUTRAL || ctx->br_stack_p == LV_BIDI_BRACKET_DEPTH) return LV_BASE_DIR_NEUTRAL; - ctx->br_stack[ctx->br_stack_p].bracklet_pos = i; + ctx->br_stack[ctx->br_stack_p].bracket_pos = i; ctx->br_stack[ctx->br_stack_p].dir = bracket_dir; ctx->br_stack_p++; @@ -640,7 +650,7 @@ static lv_base_dir_t bracket_process(lv_bidi_ctx_t * ctx, const char * txt, uint } else if(ctx->br_stack_p > 0) { /*Is the letter a closing bracket of the last opening?*/ - if(letter == bracket_right[ctx->br_stack[ctx->br_stack_p - 1].bracklet_pos]) { + if(letter == bracket_right[ctx->br_stack[ctx->br_stack_p - 1].bracket_pos]) { bracket_dir = ctx->br_stack[ctx->br_stack_p - 1].dir; ctx->br_stack_p--; return bracket_dir; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.h index e5b19c295..77575efb3 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi.h @@ -14,101 +14,34 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" - -#include -#include +#include "lv_types.h" #include "lv_text.h" /********************* * DEFINES *********************/ -/*Special non printable strong characters. - *They can be inserted to texts to affect the run's direction*/ +/** Special non printable strong characters. + * They can be inserted to texts to affect the run's direction */ #define LV_BIDI_LRO "\xE2\x80\xAD" /*U+202D*/ #define LV_BIDI_RLO "\xE2\x80\xAE" /*U+202E*/ /********************** * TYPEDEFS **********************/ -enum _lv_base_dir_t { +typedef enum { LV_BASE_DIR_LTR = 0x00, LV_BASE_DIR_RTL = 0x01, LV_BASE_DIR_AUTO = 0x02, LV_BASE_DIR_NEUTRAL = 0x20, LV_BASE_DIR_WEAK = 0x21, -}; - -#ifdef DOXYGEN -typedef _lv_base_dir_t lv_base_dir_t; -#else -typedef uint8_t lv_base_dir_t; -#endif /*DOXYGEN*/ +} lv_base_dir_t; /********************** * GLOBAL PROTOTYPES **********************/ #if LV_USE_BIDI -/** - * Convert a text to get the characters in the correct visual order according to - * Unicode Bidirectional Algorithm - * @param str_in the text to process - * @param str_out store the result here. Has the be `strlen(str_in)` length - * @param base_dir `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` - */ -void _lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_dir); - -/** - * Auto-detect the direction of a text based on the first strong character - * @param txt the text to process - * @return `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` - */ -lv_base_dir_t _lv_bidi_detect_base_dir(const char * txt); - -/** - * Get the logical position of a character in a line - * @param str_in the input string. Can be only one line. - * @param bidi_txt internally the text is bidi processed which buffer can be get here. - * If not required anymore has to freed with `lv_free()` - * Can be `NULL` is unused - * @param len length of the line in character count - * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` - * @param visual_pos the visual character position which logical position should be get - * @param is_rtl tell the char at `visual_pos` is RTL or LTR context - * @return the logical character position - */ -uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_base_dir_t base_dir, - uint32_t visual_pos, bool * is_rtl); - -/** - * Get the visual position of a character in a line - * @param str_in the input string. Can be only one line. - * @param bidi_txt internally the text is bidi processed which buffer can be get here. - * If not required anymore has to freed with `lv_free()` - * Can be `NULL` is unused - * @param len length of the line in character count - * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` - * @param logical_pos the logical character position which visual position should be get - * @param is_rtl tell the char at `logical_pos` is RTL or LTR context - * @return the visual character position - */ -uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_base_dir_t base_dir, - uint32_t logical_pos, bool * is_rtl); - -/** - * Bidi process a paragraph of text - * @param str_in the string to process - * @param str_out store the result here - * @param len length of the text - * @param base_dir base dir of the text - * @param pos_conv_out an `uint16_t` array to store the related logical position of the character. - * Can be `NULL` is unused - * @param pos_conv_len length of `pos_conv_out` in element count - */ -void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_base_dir_t base_dir, - uint16_t * pos_conv_out, uint16_t pos_conv_len); - /** * Get the real text alignment from the a text alignment, base direction and a text. * @param align LV_TEXT_ALIGN_..., write back the calculated align here (LV_TEXT_ALIGN_LEFT/RIGHT/CENTER) @@ -117,6 +50,12 @@ void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t le */ void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, const char * txt); +/** + * Set custom neutrals string + * @param neutrals default " \t\n\r.,:;'\"`!?%/\\-=()[]{}<>@#&$|" + */ +void lv_bidi_set_custom_neutrals_static(const char * neutrals); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h new file mode 100644 index 000000000..d197e4ac4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_bidi_private.h @@ -0,0 +1,98 @@ +/** + * @file lv_bidi_private.h + * + */ + +#ifndef LV_BIDI_PRIVATE_H +#define LV_BIDI_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_bidi.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert a text to get the characters in the correct visual order according to + * Unicode Bidirectional Algorithm + * @param str_in the text to process + * @param str_out store the result here. Has the be `strlen(str_in)` length + * @param base_dir `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + */ +void lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_dir); + +/** + * Auto-detect the direction of a text based on the first strong character + * @param txt the text to process + * @return `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + */ +lv_base_dir_t lv_bidi_detect_base_dir(const char * txt); + +/** + * Get the logical position of a character in a line + * @param str_in the input string. Can be only one line. + * @param bidi_txt internally the text is bidi processed which buffer can be get here. + * If not required anymore has to freed with `lv_free()` + * Can be `NULL` is unused + * @param len length of the line in character count + * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + * @param visual_pos the visual character position which logical position should be get + * @param is_rtl tell the char at `visual_pos` is RTL or LTR context + * @return the logical character position + */ +uint16_t lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_base_dir_t base_dir, + uint32_t visual_pos, bool * is_rtl); + +/** + * Get the visual position of a character in a line + * @param str_in the input string. Can be only one line. + * @param bidi_txt internally the text is bidi processed which buffer can be get here. + * If not required anymore has to freed with `lv_free()` + * Can be `NULL` is unused + * @param len length of the line in character count + * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL` + * @param logical_pos the logical character position which visual position should be get + * @param is_rtl tell the char at `logical_pos` is RTL or LTR context + * @return the visual character position + */ +uint16_t lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_base_dir_t base_dir, + uint32_t logical_pos, bool * is_rtl); + +/** + * Bidi process a paragraph of text + * @param str_in the string to process + * @param str_out store the result here + * @param len length of the text + * @param base_dir base dir of the text + * @param pos_conv_out an `uint16_t` array to store the related logical position of the character. + * Can be `NULL` is unused + * @param pos_conv_len length of `pos_conv_out` in element count + */ +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_base_dir_t base_dir, + uint16_t * pos_conv_out, uint16_t pos_conv_len); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BIDI_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c index 74b964f30..d56e355fe 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_color.c * */ @@ -8,7 +8,6 @@ *********************/ #include "lv_color.h" #include "lv_log.h" -#include "../misc/lv_color.h" /********************* * DEFINES @@ -60,6 +59,7 @@ uint8_t lv_color_format_get_bpp(lv_color_format_t cf) case LV_COLOR_FORMAT_RGB565A8: case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_AL88: return 16; case LV_COLOR_FORMAT_ARGB8565: @@ -88,6 +88,7 @@ bool lv_color_format_has_alpha(lv_color_format_t cf) case LV_COLOR_FORMAT_I8: case LV_COLOR_FORMAT_RGB565A8: case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_AL88: return true; default: return false; @@ -239,6 +240,143 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t c) return lv_color_rgb_to_hsv(c.red, c.green, c.blue); } +uint8_t lv_color_format_get_size(lv_color_format_t cf) +{ + return (lv_color_format_get_bpp(cf) + 7) >> 3; +} + +uint32_t lv_color_to_int(lv_color_t c) +{ + uint8_t * tmp = (uint8_t *) &c; + return tmp[0] + (tmp[1] << 8) + (tmp[2] << 16); +} + +bool lv_color_eq(lv_color_t c1, lv_color_t c2) +{ + return lv_color_to_int(c1) == lv_color_to_int(c2); +} + +bool lv_color32_eq(lv_color32_t c1, lv_color32_t c2) +{ + return *((uint32_t *)&c1) == *((uint32_t *)&c2); +} + +lv_color_t lv_color_hex(uint32_t c) +{ + lv_color_t ret; + ret.red = (c >> 16) & 0xff; + ret.green = (c >> 8) & 0xff; + ret.blue = (c >> 0) & 0xff; + return ret; +} + +lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b) +{ + lv_color_t ret; + ret.red = r; + ret.green = g; + ret.blue = b; + return ret; +} + +lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + lv_color32_t ret; + ret.red = r; + ret.green = g; + ret.blue = b; + ret.alpha = a; + return ret; +} + +lv_color_t lv_color_hex3(uint32_t c) +{ + return lv_color_make((uint8_t)(((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), (uint8_t)((c & 0xF0) | ((c & 0xF0) >> 4)), + (uint8_t)((c & 0xF) | ((c & 0xF) << 4))); +} + +uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_16_16_mix(uint16_t c1, uint16_t c2, uint8_t mix) +{ + if(mix == 255) return c1; + if(mix == 0) return c2; + if(c1 == c2) return c1; + + uint16_t ret; + + /* Source: https://stackoverflow.com/a/50012418/1999969*/ + mix = (uint32_t)((uint32_t)mix + 4) >> 3; + + /*0x7E0F81F = 0b00000111111000001111100000011111*/ + uint32_t bg = (uint32_t)(c2 | ((uint32_t)c2 << 16)) & 0x7E0F81F; + uint32_t fg = (uint32_t)(c1 | ((uint32_t)c1 << 16)) & 0x7E0F81F; + uint32_t result = ((((fg - bg) * mix) >> 5) + bg) & 0x7E0F81F; + ret = (uint16_t)(result >> 16) | result; + + return ret; +} + +lv_color_t lv_color_white(void) +{ + return lv_color_make(0xff, 0xff, 0xff); +} + +lv_color_t lv_color_black(void) +{ + return lv_color_make(0x00, 0x00, 0x00); +} + +void lv_color_premultiply(lv_color32_t * c) +{ + if(c->alpha == LV_OPA_COVER) { + return; + } + + if(c->alpha == LV_OPA_TRANSP) { + lv_memzero(c, sizeof(lv_color32_t)); + return; + } + + c->red = LV_OPA_MIX2(c->red, c->alpha); + c->green = LV_OPA_MIX2(c->green, c->alpha); + c->blue = LV_OPA_MIX2(c->blue, c->alpha); +} + +void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a) +{ + if(a == LV_OPA_COVER) { + return; + } + + if(a == LV_OPA_TRANSP) { + lv_memzero(c, sizeof(lv_color16_t)); + return; + } + + c->red = LV_OPA_MIX2(c->red, a); + c->green = LV_OPA_MIX2(c->green, a); + c->blue = LV_OPA_MIX2(c->blue, a); +} + +uint8_t lv_color_luminance(lv_color_t c) +{ + return (uint8_t)((uint16_t)(77u * c.red + 151u * c.green + 28u * c.blue) >> 8); +} + +uint8_t lv_color16_luminance(const lv_color16_t c) +{ + return (uint8_t)((uint16_t)(635u * c.red + 613u * c.green + 231u * c.blue) >> 8); +} + +uint8_t lv_color24_luminance(const uint8_t * c) +{ + return (uint8_t)((uint16_t)(77u * c[2] + 151u * c[1] + 28u * c[0]) >> 8); +} + +uint8_t lv_color32_luminance(lv_color32_t c) +{ + return (uint8_t)((uint16_t)(77u * c.red + 151u * c.green + 28u * c.blue) >> 8); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.h index 943234490..6328c0d2c 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_color.h * */ @@ -17,8 +17,6 @@ extern "C" { #include "lv_assert.h" #include "lv_math.h" #include "lv_types.h" -#include -#include /********************* * DEFINES @@ -26,20 +24,20 @@ extern "C" { LV_EXPORT_CONST_INT(LV_COLOR_DEPTH); #if LV_COLOR_DEPTH == 8 -#define _LV_COLOR_NATIVE_WITH_ALPHA_SIZE 2 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 2 #elif LV_COLOR_DEPTH == 16 -#define _LV_COLOR_NATIVE_WITH_ALPHA_SIZE 3 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 3 #elif LV_COLOR_DEPTH == 24 -#define _LV_COLOR_NATIVE_WITH_ALPHA_SIZE 4 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 4 #elif LV_COLOR_DEPTH == 32 -#define _LV_COLOR_NATIVE_WITH_ALPHA_SIZE 4 +#define LV_COLOR_NATIVE_WITH_ALPHA_SIZE 4 #endif /** * Opacity percentages. */ -enum _lv_opa_t { +enum { LV_OPA_TRANSP = 0, LV_OPA_0 = 0, LV_OPA_10 = 25, @@ -55,15 +53,15 @@ enum _lv_opa_t { LV_OPA_COVER = 255, }; -#ifdef DOXYGEN -typedef _lv_opa_t lv_opa_t; -#else -typedef uint8_t lv_opa_t; -#endif /*DOXYGEN*/ - -#define LV_OPA_MIN 2 /*Opacities below this will be transparent*/ -#define LV_OPA_MAX 253 /*Opacities above this will fully cover*/ +#define LV_OPA_MIN 2 /**< Opacities below this will be transparent */ +#define LV_OPA_MAX 253 /**< Opacities above this will fully cover */ +/** + * Get the pixel size of a color format in bits, bpp + * @param cf a color format (`LV_COLOR_FORMAT_...`) + * @return the pixel size in bits + * @sa lv_color_format_get_bpp + */ #define LV_COLOR_FORMAT_GET_BPP(cf) ( \ (cf) == LV_COLOR_FORMAT_I1 ? 1 : \ (cf) == LV_COLOR_FORMAT_A1 ? 1 : \ @@ -74,6 +72,7 @@ typedef uint8_t lv_opa_t; (cf) == LV_COLOR_FORMAT_L8 ? 8 : \ (cf) == LV_COLOR_FORMAT_A8 ? 8 : \ (cf) == LV_COLOR_FORMAT_I8 ? 8 : \ + (cf) == LV_COLOR_FORMAT_AL88 ? 16 : \ (cf) == LV_COLOR_FORMAT_RGB565 ? 16 : \ (cf) == LV_COLOR_FORMAT_RGB565A8 ? 16 : \ (cf) == LV_COLOR_FORMAT_ARGB8565 ? 24 : \ @@ -83,6 +82,14 @@ typedef uint8_t lv_opa_t; 0 \ ) +/** + * Get the pixel size of a color format in bytes + * @param cf a color format (`LV_COLOR_FORMAT_...`) + * @return the pixel size in bytes + * @sa lv_color_format_get_size + */ +#define LV_COLOR_FORMAT_GET_SIZE(cf) ((LV_COLOR_FORMAT_GET_BPP(cf) + 7) >> 3) + /********************** * TYPEDEFS **********************/ @@ -112,7 +119,12 @@ typedef struct { uint8_t v; } lv_color_hsv_t; -enum _lv_color_format_t { +typedef struct { + uint8_t lumi; + uint8_t alpha; +} lv_color16a_t; + +typedef enum { LV_COLOR_FORMAT_UNKNOWN = 0, LV_COLOR_FORMAT_RAW = 0x01, @@ -129,7 +141,8 @@ enum _lv_color_format_t { /*2 byte (+alpha) formats*/ LV_COLOR_FORMAT_RGB565 = 0x12, LV_COLOR_FORMAT_ARGB8565 = 0x13, /**< Not supported by sw renderer yet. */ - LV_COLOR_FORMAT_RGB565A8 = 0x14 /**< Color array followed by Alpha array*/, + LV_COLOR_FORMAT_RGB565A8 = 0x14, /**< Color array followed by Alpha array*/ + LV_COLOR_FORMAT_AL88 = 0x15, /**< L8 with alpha >*/ /*3 byte (+alpha) formats*/ LV_COLOR_FORMAT_RGB888 = 0x0F, @@ -158,8 +171,12 @@ enum _lv_color_format_t { LV_COLOR_FORMAT_YUV_END = LV_COLOR_FORMAT_UYVY, /*Color formats in which LVGL can render*/ -#if LV_COLOR_DEPTH == 8 +#if LV_COLOR_DEPTH == 1 + LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_I1, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_I1, +#elif LV_COLOR_DEPTH == 8 LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_L8, + LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_AL88, #elif LV_COLOR_DEPTH == 16 LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_RGB565, LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_RGB565A8, @@ -169,14 +186,11 @@ enum _lv_color_format_t { #elif LV_COLOR_DEPTH == 32 LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_XRGB8888, LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_ARGB8888, -#endif -}; - -#ifdef DOXYGEN -typedef _lv_color_format_t lv_color_format_t; #else -typedef uint8_t lv_color_format_t; -#endif /*DOXYGEN*/ +#error "LV_COLOR_DEPTH should be 1, 8, 16, 24 or 32" +#endif + +} lv_color_format_t; #define LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf) ((cf) >= LV_COLOR_FORMAT_A1 && (cf) <= LV_COLOR_FORMAT_A8) #define LV_COLOR_FORMAT_IS_INDEXED(cf) ((cf) >= LV_COLOR_FORMAT_I1 && (cf) <= LV_COLOR_FORMAT_I8) @@ -201,20 +215,19 @@ typedef uint8_t lv_color_format_t; /** * Get the pixel size of a color format in bits, bpp - * @param src_cf a color format (`LV_COLOR_FORMAT_...`) + * @param cf a color format (`LV_COLOR_FORMAT_...`) * @return the pixel size in bits + * @sa LV_COLOR_FORMAT_GET_BPP */ uint8_t lv_color_format_get_bpp(lv_color_format_t cf); /** * Get the pixel size of a color format in bytes - * @param src_cf a color format (`LV_COLOR_FORMAT_...`) + * @param cf a color format (`LV_COLOR_FORMAT_...`) * @return the pixel size in bytes + * @sa LV_COLOR_FORMAT_GET_SIZE */ -static inline uint8_t lv_color_format_get_size(lv_color_format_t cf) -{ - return (lv_color_format_get_bpp(cf) + 7) >> 3; -} +uint8_t lv_color_format_get_size(lv_color_format_t cf); /** * Check if a color format has alpha channel or not @@ -236,11 +249,7 @@ lv_color32_t lv_color_to_32(lv_color_t color, lv_opa_t opa); * @param c an RGB888 color * @return `c` as an integer */ -static inline uint32_t lv_color_to_int(lv_color_t c) -{ - uint8_t * tmp = (uint8_t *) &c; - return tmp[0] + (tmp[1] << 8) + (tmp[2] << 16); -} +uint32_t lv_color_to_int(lv_color_t c); /** * Check if two RGB888 color are equal @@ -248,10 +257,7 @@ static inline uint32_t lv_color_to_int(lv_color_t c) * @param c2 the second color * @return true: equal */ -static inline bool lv_color_eq(lv_color_t c1, lv_color_t c2) -{ - return lv_color_to_int(c1) == lv_color_to_int(c2); -} +bool lv_color_eq(lv_color_t c1, lv_color_t c2); /** * Check if two ARGB8888 color are equal @@ -259,24 +265,14 @@ static inline bool lv_color_eq(lv_color_t c1, lv_color_t c2) * @param c2 the second color * @return true: equal */ -static inline bool lv_color32_eq(lv_color32_t c1, lv_color32_t c2) -{ - return *((uint32_t *)&c1) == *((uint32_t *)&c2); -} +bool lv_color32_eq(lv_color32_t c1, lv_color32_t c2); /** * Create a color from 0x000000..0xffffff input * @param c the hex input * @return the color */ -static inline lv_color_t lv_color_hex(uint32_t c) -{ - lv_color_t ret; - ret.red = (c >> 16) & 0xff; - ret.green = (c >> 8) & 0xff; - ret.blue = (c >> 0) & 0xff; - return ret; -} +lv_color_t lv_color_hex(uint32_t c); /** * Create an RGB888 color @@ -285,14 +281,7 @@ static inline lv_color_t lv_color_hex(uint32_t c) * @param b the blue channel (0..255) * @return the color */ -static inline lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b) -{ - lv_color_t ret; - ret.red = r; - ret.green = g; - ret.blue = b; - return ret; -} +lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b); /** * Create an ARGB8888 color @@ -302,26 +291,14 @@ static inline lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b) * @param a the alpha channel (0..255) * @return the color */ -static inline lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a) -{ - lv_color32_t ret; - ret.red = r; - ret.green = g; - ret.blue = b; - ret.alpha = a; - return ret; -} +lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a); /** * Create a color from 0x000..0xfff input * @param c the hex input (e.g. 0x123 will be 0x112233) * @return the color */ -static inline lv_color_t lv_color_hex3(uint32_t c) -{ - return lv_color_make((uint8_t)(((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), (uint8_t)((c & 0xF0) | ((c & 0xF0) >> 4)), - (uint8_t)((c & 0xF) | ((c & 0xF) << 4))); -} +lv_color_t lv_color_hex3(uint32_t c); /** * Convert am RGB888 color to RGB565 stored in `uint16_t` @@ -346,24 +323,7 @@ uint32_t lv_color_to_u32(lv_color_t color); * mix == 255: c1 * mix == 128: 0.5 x c1 + 0.5 x c2 */ -static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_16_16_mix(uint16_t c1, uint16_t c2, uint8_t mix) -{ - if(mix == 255) return c1; - if(mix == 0) return c2; - - uint16_t ret; - - /* Source: https://stackoverflow.com/a/50012418/1999969*/ - mix = (uint32_t)((uint32_t)mix + 4) >> 3; - - /*0x7E0F81F = 0b00000111111000001111100000011111*/ - uint32_t bg = (uint32_t)(c2 | ((uint32_t)c2 << 16)) & 0x7E0F81F; - uint32_t fg = (uint32_t)(c1 | ((uint32_t)c1 << 16)) & 0x7E0F81F; - uint32_t result = ((((fg - bg) * mix) >> 5) + bg) & 0x7E0F81F; - ret = (uint16_t)(result >> 16) | result; - - return ret; -} +uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_16_16_mix(uint16_t c1, uint16_t c2, uint8_t mix); /** * Mix white to a color @@ -412,33 +372,45 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color); * A helper for white color * @return a white color */ -static inline lv_color_t lv_color_white(void) -{ - return lv_color_make(0xff, 0xff, 0xff); -} +lv_color_t lv_color_white(void); /** * A helper for black color * @return a black color */ -static inline lv_color_t lv_color_black(void) -{ - return lv_color_make(0x00, 0x00, 0x00); -} +lv_color_t lv_color_black(void); -static inline void lv_color_premultiply(lv_color32_t * c) -{ - c->red = LV_OPA_MIX2(c->red, c->alpha); - c->green = LV_OPA_MIX2(c->green, c->alpha); - c->blue = LV_OPA_MIX2(c->blue, c->alpha); -} +void lv_color_premultiply(lv_color32_t * c); -static inline void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a) -{ - c->red = LV_OPA_MIX2(c->red, a); - c->green = LV_OPA_MIX2(c->green, a); - c->blue = LV_OPA_MIX2(c->blue, a); -} +void lv_color16_premultiply(lv_color16_t * c, lv_opa_t a); + +/** + * Get the luminance of a color: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color_luminance(lv_color_t c); + +/** + * Get the luminance of a color16: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color16_luminance(const lv_color16_t c); + +/** + * Get the luminance of a color24: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color24_luminance(const uint8_t * c); + +/** + * Get the luminance of a color32: luminance = 0.3 R + 0.59 G + 0.11 B + * @param c a color + * @return the brightness [0..255] + */ +uint8_t lv_color32_luminance(lv_color32_t c); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c index 5e2fb3455..a26f2b453 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c @@ -6,9 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_color.h" +#include "lv_color_op_private.h" #include "lv_log.h" -#include "../misc/lv_color.h" /********************* * DEFINES @@ -33,3 +32,43 @@ /********************** * GLOBAL FUNCTIONS **********************/ + +lv_color_t LV_ATTRIBUTE_FAST_MEM lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix) +{ + lv_color_t ret; + + ret.red = LV_UDIV255((uint16_t)c1.red * mix + c2.red * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); + ret.green = LV_UDIV255((uint16_t)c1.green * mix + c2.green * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); + ret.blue = LV_UDIV255((uint16_t)c1.blue * mix + c2.blue * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); + return ret; +} + +lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg) +{ + if(fg.alpha >= LV_OPA_MAX) { + fg.alpha = bg.alpha; + return fg; + } + if(fg.alpha <= LV_OPA_MIN) { + return bg; + } + bg.red = (uint32_t)((uint32_t)fg.red * fg.alpha + (uint32_t)bg.red * (255 - fg.alpha)) >> 8; + bg.green = (uint32_t)((uint32_t)fg.green * fg.alpha + (uint32_t)bg.green * (255 - fg.alpha)) >> 8; + bg.blue = (uint32_t)((uint32_t)fg.blue * fg.alpha + (uint32_t)bg.blue * (255 - fg.alpha)) >> 8; + return bg; +} + +uint8_t lv_color_brightness(lv_color_t c) +{ + uint16_t bright = (uint16_t)(3u * c.red + c.green + 4u * c.blue); + return (uint8_t)(bright >> 3); +} + +void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t cb) +{ + dsc->filter_cb = cb; +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h index 1109c9c2c..0a59de35d 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h @@ -16,7 +16,7 @@ extern "C" { #include "lv_assert.h" #include "lv_math.h" #include "lv_color.h" -#include +#include "lv_types.h" /********************* * DEFINES @@ -26,14 +26,14 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_color_filter_dsc_t; +struct lv_color_filter_dsc_t; -typedef lv_color_t (*lv_color_filter_cb_t)(const struct _lv_color_filter_dsc_t *, lv_color_t, lv_opa_t); +typedef lv_color_t (*lv_color_filter_cb_t)(const struct lv_color_filter_dsc_t *, lv_color_t, lv_opa_t); -typedef struct _lv_color_filter_dsc_t { +struct lv_color_filter_dsc_t { lv_color_filter_cb_t filter_cb; void * user_data; -} lv_color_filter_dsc_t; +}; /********************** * GLOBAL PROTOTYPES @@ -46,15 +46,7 @@ typedef struct _lv_color_filter_dsc_t { * @param mix The ratio of the colors. 0: full `c2`, 255: full `c1`, 127: half `c1` and half`c2` * @return the mixed color */ -static inline lv_color_t LV_ATTRIBUTE_FAST_MEM lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix) -{ - lv_color_t ret; - - ret.red = LV_UDIV255((uint16_t)c1.red * mix + c2.red * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); - ret.green = LV_UDIV255((uint16_t)c1.green * mix + c2.green * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); - ret.blue = LV_UDIV255((uint16_t)c1.blue * mix + c2.blue * (255 - mix) + LV_COLOR_MIX_ROUND_OFS); - return ret; -} +lv_color_t LV_ATTRIBUTE_FAST_MEM lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix); /** * @@ -64,38 +56,16 @@ static inline lv_color_t LV_ATTRIBUTE_FAST_MEM lv_color_mix(lv_color_t c1, lv_co * @note Use bg.alpha in the return value * @note Use fg.alpha as mix ratio */ -static inline lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg) -{ - if(fg.alpha >= LV_OPA_MAX) { - fg.alpha = bg.alpha; - return fg; - } - if(fg.alpha <= LV_OPA_MIN) { - return bg; - } - bg.red = (uint32_t)((uint32_t)fg.red * fg.alpha + (uint32_t)bg.red * (255 - fg.alpha)) >> 8; - bg.green = (uint32_t)((uint32_t)fg.green * fg.alpha + (uint32_t)bg.green * (255 - fg.alpha)) >> 8; - bg.blue = (uint32_t)((uint32_t)fg.blue * fg.alpha + (uint32_t)bg.blue * (255 - fg.alpha)) >> 8; - return bg; -} - -//! @endcond +lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg); /** * Get the brightness of a color - * @param color a color - * @return the brightness [0..255] + * @param c a color + * @return brightness in range [0..255] */ -static inline uint8_t lv_color_brightness(lv_color_t c) -{ - uint16_t bright = (uint16_t)(3u * c.red + c.green + 4u * c.blue); - return (uint8_t)(bright >> 3); -} +uint8_t lv_color_brightness(lv_color_t c); -static inline void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t cb) -{ - dsc->filter_cb = cb; -} +void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t cb); /********************** * PREDEFINED COLORS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op_private.h new file mode 100644 index 000000000..d6516ebd0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_color_op_private.h + * + */ + +#ifndef LV_COLOR_OP_PRIVATE_H +#define LV_COLOR_OP_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_color_op.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_COLOR_OP_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c index e991ec0fa..ec985ed25 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c @@ -6,11 +6,11 @@ /********************* * INCLUDES *********************/ -#include "lv_event.h" +#include "lv_event_private.h" #include "../core/lv_global.h" #include "../stdlib/lv_mem.h" #include "lv_assert.h" -#include +#include "lv_types.h" /********************* * DEFINES @@ -45,7 +45,7 @@ * GLOBAL FUNCTIONS **********************/ -void _lv_event_push(lv_event_t * e) +void lv_event_push(lv_event_t * e) { /*Build a simple linked list from the objects used in the events *It's important to know if this object was deleted by a nested event @@ -55,7 +55,7 @@ void _lv_event_push(lv_event_t * e) } -void _lv_event_pop(lv_event_t * e) +void lv_event_pop(lv_event_t * e) { event_head = e->prev; } @@ -209,7 +209,7 @@ uint32_t lv_event_register_id(void) return event_last_id; } -void _lv_event_mark_deleted(void * target) +void lv_event_mark_deleted(void * target) { lv_event_t * e = event_head; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h index 2eeb5cdf5..61518e96a 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h @@ -13,8 +13,6 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include #include "lv_types.h" #include "../lv_conf_internal.h" @@ -30,12 +28,6 @@ extern "C" { typedef void (*lv_event_cb_t)(lv_event_t * e); -typedef struct { - lv_event_cb_t cb; - void * user_data; - uint32_t filter; -} lv_event_dsc_t; - /** * Type of event being sent to the object. */ @@ -63,6 +55,8 @@ typedef enum { LV_EVENT_LEAVE, /**< The object is defocused but still selected*/ LV_EVENT_HIT_TEST, /**< Perform advanced hit-testing*/ LV_EVENT_INDEV_RESET, /**< Indev has been reset*/ + LV_EVENT_HOVER_OVER, /**< Indev hover over object*/ + LV_EVENT_HOVER_LEAVE, /**< Indev hover leave object*/ /** Drawing events*/ LV_EVENT_COVER_CHECK, /**< Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.*/ @@ -113,7 +107,7 @@ typedef enum { LV_EVENT_VSYNC, - _LV_EVENT_LAST, /** Number of default events*/ + LV_EVENT_LAST, /** Number of default events*/ LV_EVENT_PREPROCESS = 0x8000, /** This is a flag that can be set with an event so it's processed before the class default event processing */ @@ -121,32 +115,12 @@ typedef enum { typedef lv_array_t lv_event_list_t; -struct _lv_event_t { - void * current_target; - void * original_target; - lv_event_code_t code; - void * user_data; - void * param; - lv_event_t * prev; - uint8_t deleted : 1; - uint8_t stop_processing : 1; - uint8_t stop_bubbling : 1; -}; - /** * @brief Event callback. * Events are used to notify the user of some action being taken on the object. * For details, see ::lv_event_t. */ -/********************** - * GLOBAL PROTOTYPES - **********************/ - -void _lv_event_push(lv_event_t * e); - -void _lv_event_pop(lv_event_t * e); - lv_result_t lv_event_send(lv_event_list_t * list, lv_event_t * e, bool preprocess); lv_event_dsc_t * lv_event_add(lv_event_list_t * list, lv_event_cb_t cb, lv_event_code_t filter, void * user_data); @@ -218,22 +192,18 @@ void lv_event_stop_processing(lv_event_t * e); * Register a new, custom event ID. * It can be used the same way as e.g. `LV_EVENT_CLICKED` to send custom events * @return the new event id - * @example + * + * Example: + * @code * uint32_t LV_EVENT_MINE = 0; * ... * e = lv_event_register_id(); * ... * lv_obj_send_event(obj, LV_EVENT_MINE, &some_data); + * @endcode */ uint32_t lv_event_register_id(void); -/** - * Nested events can be called and one of them might belong to an object that is being deleted. - * Mark this object's `event_temp_data` deleted to know that its `lv_obj_send_event` should return `LV_RESULT_INVALID` - * @param target pointer to an event target which was deleted - */ -void _lv_event_mark_deleted(void * target); - /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h new file mode 100644 index 000000000..b31ca81b8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h @@ -0,0 +1,73 @@ +/** + * @file lv_event_private.h + * + */ + +#ifndef LV_EVENT_PRIVATE_H +#define LV_EVENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_event.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_event_dsc_t { + lv_event_cb_t cb; + void * user_data; + uint32_t filter; +}; + +struct lv_event_t { + void * current_target; + void * original_target; + lv_event_code_t code; + void * user_data; + void * param; + lv_event_t * prev; + uint8_t deleted : 1; + uint8_t stop_processing : 1; + uint8_t stop_bubbling : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_event_push(lv_event_t * e); + +void lv_event_pop(lv_event_t * e); + +/** + * Nested events can be called and one of them might belong to an object that is being deleted. + * Mark this object's `event_temp_data` deleted to know that its `lv_obj_send_event` should return `LV_RESULT_INVALID` + * @param target pointer to an event target which was deleted + */ +void lv_event_mark_deleted(void * target); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EVENT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c index 921d30658..f71369880 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c @@ -6,10 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_fs.h" +#include "lv_fs_private.h" -#include #include "../misc/lv_assert.h" +#include "../misc/lv_profiler.h" #include "../stdlib/lv_string.h" #include "lv_ll.h" #include "../core/lv_global.h" @@ -17,16 +17,28 @@ /********************* * DEFINES *********************/ + +#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' && (LV_FS_DEFAULT_DRIVE_LETTER < 'A' || 'Z' < LV_FS_DEFAULT_DRIVE_LETTER) + #error "When enabled, LV_FS_DEFAULT_DRIVE_LETTER needs to be a capital ASCII letter (A-Z)" +#endif + #define fsdrv_ll_p &(LV_GLOBAL_DEFAULT()->fsdrv_ll) /********************** * TYPEDEFS **********************/ +typedef struct { + char drive_letter; + const char * real_path; +} resolved_path_t; /********************** * STATIC PROTOTYPES **********************/ -static const char * lv_fs_get_real_path(const char * path); +static resolved_path_t lv_fs_resolve_path(const char * path); +static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t lv_fs_write_cached(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t lv_fs_seek_cached(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence); /********************** * STATIC VARIABLES @@ -40,14 +52,14 @@ static const char * lv_fs_get_real_path(const char * path); * GLOBAL FUNCTIONS **********************/ -void _lv_fs_init(void) +void lv_fs_init(void) { - _lv_ll_init(fsdrv_ll_p, sizeof(lv_fs_drv_t *)); + lv_ll_init(fsdrv_ll_p, sizeof(lv_fs_drv_t *)); } -void _lv_fs_deinit(void) +void lv_fs_deinit(void) { - _lv_ll_clear(fsdrv_ll_p); + lv_ll_clear(fsdrv_ll_p); } bool lv_fs_is_ready(char letter) @@ -68,8 +80,9 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo return LV_FS_RES_INV_PARAM; } - char letter = path[0]; - lv_fs_drv_t * drv = lv_fs_get_drv(letter); + resolved_path_t resolved_path = lv_fs_resolve_path(path); + + lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter); if(drv == NULL) { LV_LOG_WARN("Can't open file (%s): unknown driver letter", path); @@ -88,6 +101,8 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo return LV_FS_RES_NOT_IMP; } + LV_PROFILER_BEGIN; + file_p->drv = drv; /* For memory-mapped files we set the file handle to our file descriptor so that we can access the cache from the file operations */ @@ -95,9 +110,9 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo file_p->file_d = file_p; } else { - const char * real_path = lv_fs_get_real_path(path); - void * file_d = drv->open_cb(drv, real_path, mode); + void * file_d = drv->open_cb(drv, resolved_path.real_path, mode); if(file_d == NULL || file_d == (void *)(-1)) { + LV_PROFILER_END; return LV_FS_RES_UNKNOWN; } file_p->file_d = file_d; @@ -122,6 +137,8 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo } } + LV_PROFILER_END; + return LV_FS_RES_OK; } @@ -144,6 +161,8 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p) return LV_FS_RES_NOT_IMP; } + LV_PROFILER_BEGIN; + lv_fs_res_t res = file_p->drv->close_cb(file_p->drv, file_p->file_d); if(file_p->drv->cache_size && file_p->cache) { @@ -159,90 +178,7 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p) file_p->drv = NULL; file_p->cache = NULL; - return res; -} - -static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, char * buf, uint32_t btr, uint32_t * br) -{ - lv_fs_res_t res = LV_FS_RES_OK; - uint32_t file_position = file_p->cache->file_position; - uint32_t start = file_p->cache->start; - uint32_t end = file_p->cache->end; - char * buffer = file_p->cache->buffer; - uint32_t buffer_size = file_p->drv->cache_size; - - if(start <= file_position && file_position <= end) { - /* Data can be read from cache buffer */ - uint32_t buffer_remaining_length = (uint32_t)end - file_position + 1; - uint32_t buffer_offset = (end - start) - buffer_remaining_length + 1; - - /* Do not allow reading beyond the actual memory block for memory-mapped files */ - if(file_p->drv->cache_size == LV_FS_CACHE_FROM_BUFFER) { - if(btr > buffer_remaining_length) - btr = buffer_remaining_length - 1; - } - - if(btr <= buffer_remaining_length) { - /*Data is in cache buffer, and buffer end not reached, no need to read from FS*/ - lv_memcpy(buf, buffer + buffer_offset, btr); - *br = btr; - } - else { - /*First part of data is in cache buffer, but we need to read rest of data from FS*/ - lv_memcpy(buf, buffer + buffer_offset, buffer_remaining_length); - - file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->end + 1, - LV_FS_SEEK_SET); - - uint32_t bytes_read_to_buffer = 0; - if(btr - buffer_remaining_length > buffer_size) { - /*If remaining data chuck is bigger than buffer size, then do not use cache, instead read it directly from FS*/ - res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)(buf + buffer_remaining_length), - btr - buffer_remaining_length, &bytes_read_to_buffer); - } - else { - /*If remaining data chunk is smaller than buffer size, then read into cache buffer*/ - res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buffer, buffer_size, &bytes_read_to_buffer); - file_p->cache->start = file_p->cache->end + 1; - file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1; - - uint16_t data_chunk_remaining = LV_MIN(btr - buffer_remaining_length, bytes_read_to_buffer); - lv_memcpy(buf + buffer_remaining_length, buffer, data_chunk_remaining); - } - *br = LV_MIN(buffer_remaining_length + bytes_read_to_buffer, btr); - } - } - else { - file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, - LV_FS_SEEK_SET); - - /*Data is not in cache buffer*/ - if(btr > buffer_size) { - /*If bigger data is requested, then do not use cache, instead read it directly*/ - res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buf, btr, br); - } - else { - /*If small data is requested, then read from FS into cache buffer*/ - if(buffer == NULL) { - file_p->cache->buffer = lv_malloc(buffer_size); - LV_ASSERT_MALLOC(file_p->cache->buffer); - buffer = file_p->cache->buffer; - } - - uint32_t bytes_read_to_buffer = 0; - res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buffer, buffer_size, &bytes_read_to_buffer); - file_p->cache->start = file_position; - file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1; - - *br = LV_MIN(btr, bytes_read_to_buffer); - lv_memcpy(buf, buffer, *br); - - } - } - - if(res == LV_FS_RES_OK) { - file_p->cache->file_position += *br; - } + LV_PROFILER_END; return res; } @@ -251,13 +187,21 @@ lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t { if(br != NULL) *br = 0; if(file_p->drv == NULL) return LV_FS_RES_INV_PARAM; - if(file_p->drv->read_cb == NULL) return LV_FS_RES_NOT_IMP; + + if(file_p->drv->cache_size) { + if(file_p->drv->read_cb == NULL || file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP; + } + else { + if(file_p->drv->read_cb == NULL) return LV_FS_RES_NOT_IMP; + } + + LV_PROFILER_BEGIN; uint32_t br_tmp = 0; lv_fs_res_t res; if(file_p->drv->cache_size) { - res = lv_fs_read_cached(file_p, (char *)buf, btr, &br_tmp); + res = lv_fs_read_cached(file_p, buf, btr, &br_tmp); } else { res = file_p->drv->read_cb(file_p->drv, file_p->file_d, buf, btr, &br_tmp); @@ -265,6 +209,8 @@ lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t if(br != NULL) *br = br_tmp; + LV_PROFILER_END; + return res; } @@ -276,24 +222,26 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u return LV_FS_RES_INV_PARAM; } - if(file_p->drv->write_cb == NULL) { - return LV_FS_RES_NOT_IMP; - } - - lv_fs_res_t res = LV_FS_RES_OK; - - /*Need to do FS seek before writing data to FS*/ if(file_p->drv->cache_size) { - res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET); - if(res != LV_FS_RES_OK) return res; + if(file_p->drv->write_cb == NULL || file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP; + } + else { + if(file_p->drv->write_cb == NULL) return LV_FS_RES_NOT_IMP; } + LV_PROFILER_BEGIN; + + lv_fs_res_t res; uint32_t bw_tmp = 0; - res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, &bw_tmp); + if(file_p->drv->cache_size) { + res = lv_fs_write_cached(file_p, buf, btw, &bw_tmp); + } + else { + res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, &bw_tmp); + } if(bw != NULL) *bw = bw_tmp; - if(file_p->drv->cache_size && res == LV_FS_RES_OK) - file_p->cache->file_position += bw_tmp; + LV_PROFILER_END; return res; } @@ -304,52 +252,25 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whenc return LV_FS_RES_INV_PARAM; } - if(file_p->drv->seek_cb == NULL) { - return LV_FS_RES_NOT_IMP; + if(file_p->drv->cache_size) { + if(file_p->drv->seek_cb == NULL || file_p->drv->tell_cb == NULL) return LV_FS_RES_NOT_IMP; + } + else { + if(file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP; } - lv_fs_res_t res = LV_FS_RES_OK; + LV_PROFILER_BEGIN; + + lv_fs_res_t res; if(file_p->drv->cache_size) { - switch(whence) { - case LV_FS_SEEK_SET: { - file_p->cache->file_position = pos; - - /*FS seek if new position is outside cache buffer*/ - if(file_p->cache->file_position < file_p->cache->start || file_p->cache->file_position > file_p->cache->end) { - res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET); - } - - break; - } - case LV_FS_SEEK_CUR: { - file_p->cache->file_position += pos; - - /*FS seek if new position is outside cache buffer*/ - if(file_p->cache->file_position < file_p->cache->start || file_p->cache->file_position > file_p->cache->end) { - res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET); - } - - break; - } - case LV_FS_SEEK_END: { - /*Because we don't know the file size, we do a little trick: do a FS seek, then get the new file position from FS*/ - res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence); - if(res == LV_FS_RES_OK) { - uint32_t tmp_position; - res = file_p->drv->tell_cb(file_p->drv, file_p->file_d, &tmp_position); - - if(res == LV_FS_RES_OK) { - file_p->cache->file_position = tmp_position; - } - } - break; - } - } + res = lv_fs_seek_cached(file_p, pos, whence); } else { res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence); } + LV_PROFILER_END; + return res; } @@ -360,11 +281,13 @@ lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos) return LV_FS_RES_INV_PARAM; } - if(file_p->drv->tell_cb == NULL) { + if(file_p->drv->cache_size == 0 && file_p->drv->tell_cb == NULL) { *pos = 0; return LV_FS_RES_NOT_IMP; } + LV_PROFILER_BEGIN; + lv_fs_res_t res; if(file_p->drv->cache_size) { *pos = file_p->cache->file_position; @@ -374,6 +297,8 @@ lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos) res = file_p->drv->tell_cb(file_p->drv, file_p->file_d, pos); } + LV_PROFILER_END; + return res; } @@ -381,8 +306,9 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path) { if(path == NULL) return LV_FS_RES_INV_PARAM; - char letter = path[0]; - lv_fs_drv_t * drv = lv_fs_get_drv(letter); + resolved_path_t resolved_path = lv_fs_resolve_path(path); + + lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter); if(drv == NULL) { return LV_FS_RES_NOT_EX; @@ -398,16 +324,20 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path) return LV_FS_RES_NOT_IMP; } - const char * real_path = lv_fs_get_real_path(path); - void * dir_d = drv->dir_open_cb(drv, real_path); + LV_PROFILER_BEGIN; + + void * dir_d = drv->dir_open_cb(drv, resolved_path.real_path); if(dir_d == NULL || dir_d == (void *)(-1)) { + LV_PROFILER_END; return LV_FS_RES_UNKNOWN; } rddir_p->drv = drv; rddir_p->dir_d = dir_d; + LV_PROFILER_END; + return LV_FS_RES_OK; } @@ -427,8 +357,12 @@ lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn, uint32_t fn_len) return LV_FS_RES_NOT_IMP; } + LV_PROFILER_BEGIN; + lv_fs_res_t res = rddir_p->drv->dir_read_cb(rddir_p->drv, rddir_p->dir_d, fn, fn_len); + LV_PROFILER_END; + return res; } @@ -442,11 +376,15 @@ lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p) return LV_FS_RES_NOT_IMP; } + LV_PROFILER_BEGIN; + lv_fs_res_t res = rddir_p->drv->dir_close_cb(rddir_p->drv, rddir_p->dir_d); rddir_p->dir_d = NULL; rddir_p->drv = NULL; + LV_PROFILER_END; + return res; } @@ -459,7 +397,7 @@ void lv_fs_drv_register(lv_fs_drv_t * drv_p) { /*Save the new driver*/ lv_fs_drv_t ** new_drv; - new_drv = _lv_ll_ins_head(fsdrv_ll_p); + new_drv = lv_ll_ins_head(fsdrv_ll_p); LV_ASSERT_MALLOC(new_drv); if(new_drv == NULL) return; @@ -470,7 +408,7 @@ lv_fs_drv_t * lv_fs_get_drv(char letter) { lv_fs_drv_t ** drv; - _LV_LL_READ(fsdrv_ll_p, drv) { + LV_LL_READ(fsdrv_ll_p, drv) { if((*drv)->letter == letter) { return *drv; } @@ -484,7 +422,7 @@ char * lv_fs_get_letters(char * buf) lv_fs_drv_t ** drv; uint8_t i = 0; - _LV_LL_READ(fsdrv_ll_p, drv) { + LV_LL_READ(fsdrv_ll_p, drv) { buf[i] = (*drv)->letter; i++; } @@ -565,14 +503,193 @@ const char * lv_fs_get_last(const char * path) **********************/ /** - * Skip the driver letter and the possible : after the letter + * Extract the drive letter and the real path from LVGL's "abstracted file system" path string * @param path path string (E.g. S:/folder/file.txt) - * @return pointer to the beginning of the real path (E.g. /folder/file.txt) */ -static const char * lv_fs_get_real_path(const char * path) +static resolved_path_t lv_fs_resolve_path(const char * path) { - path++; /*Ignore the driver letter*/ - if(*path == ':') path++; + resolved_path_t resolved; - return path; +#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ + bool has_drive_prefix = ('A' <= path[0]) && (path[0] <= 'Z') && (path[1] == ':'); + + if(has_drive_prefix) { + resolved.drive_letter = path[0]; + resolved.real_path = path + 2; + } + else { + resolved.drive_letter = LV_FS_DEFAULT_DRIVE_LETTER; + resolved.real_path = path; + } +# else /*Lean rules for backward compatibility*/ + resolved.drive_letter = path[0]; + + if(*path != '\0') { + path++; /*Ignore the driver letter*/ + if(*path == ':') path++; + } + + resolved.real_path = path; +#endif + + return resolved; +} + +static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + lv_fs_res_t res = LV_FS_RES_OK; + uint32_t file_position = file_p->cache->file_position; + uint32_t start = file_p->cache->start; + uint32_t end = file_p->cache->end; + char * buffer = file_p->cache->buffer; + uint32_t buffer_size = file_p->drv->cache_size; + + if(start <= file_position && file_position <= end) { + /* Data can be read from cache buffer */ + uint32_t buffer_remaining_length = (uint32_t)end - file_position + 1; + uint32_t buffer_offset = (end - start) - buffer_remaining_length + 1; + + /* Do not allow reading beyond the actual memory block for memory-mapped files */ + if(file_p->drv->cache_size == LV_FS_CACHE_FROM_BUFFER) { + if(btr > buffer_remaining_length) + btr = buffer_remaining_length - 1; + } + + if(btr <= buffer_remaining_length) { + /*Data is in cache buffer, and buffer end not reached, no need to read from FS*/ + lv_memcpy(buf, buffer + buffer_offset, btr); + *br = btr; + } + else { + /*First part of data is in cache buffer, but we need to read rest of data from FS*/ + lv_memcpy(buf, buffer + buffer_offset, buffer_remaining_length); + + file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->end + 1, + LV_FS_SEEK_SET); + + uint32_t bytes_read_to_buffer = 0; + if(btr - buffer_remaining_length > buffer_size) { + /*If remaining data chuck is bigger than buffer size, then do not use cache, instead read it directly from FS*/ + res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (char *)buf + buffer_remaining_length, + btr - buffer_remaining_length, &bytes_read_to_buffer); + } + else { + /*If remaining data chunk is smaller than buffer size, then read into cache buffer*/ + res = file_p->drv->read_cb(file_p->drv, file_p->file_d, buffer, buffer_size, &bytes_read_to_buffer); + file_p->cache->start = file_p->cache->end + 1; + file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1; + + uint16_t data_chunk_remaining = LV_MIN(btr - buffer_remaining_length, bytes_read_to_buffer); + lv_memcpy((char *)buf + buffer_remaining_length, buffer, data_chunk_remaining); + } + *br = LV_MIN(buffer_remaining_length + bytes_read_to_buffer, btr); + } + } + else { + file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, + LV_FS_SEEK_SET); + + /*Data is not in cache buffer*/ + if(btr > buffer_size) { + /*If bigger data is requested, then do not use cache, instead read it directly*/ + res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buf, btr, br); + } + else { + /*If small data is requested, then read from FS into cache buffer*/ + if(buffer == NULL) { + file_p->cache->buffer = lv_malloc(buffer_size); + LV_ASSERT_MALLOC(file_p->cache->buffer); + buffer = file_p->cache->buffer; + } + + uint32_t bytes_read_to_buffer = 0; + res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buffer, buffer_size, &bytes_read_to_buffer); + file_p->cache->start = file_position; + file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1; + + *br = LV_MIN(btr, bytes_read_to_buffer); + lv_memcpy(buf, buffer, *br); + + } + } + + if(res == LV_FS_RES_OK) { + file_p->cache->file_position += *br; + } + + return res; +} + +static lv_fs_res_t lv_fs_write_cached(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + lv_fs_res_t res = LV_FS_RES_OK; + + /*Need to do FS seek before writing data to FS*/ + res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET); + if(res != LV_FS_RES_OK) return res; + + res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, bw); + if(res != LV_FS_RES_OK) return res; + + if(file_p->cache->end >= file_p->cache->start) { + uint32_t start_position = file_p->cache->file_position; + uint32_t end_position = file_p->cache->file_position + *bw - 1; + char * cache_buffer = file_p->cache->buffer; + const char * write_buffer = buf; + + if(start_position <= file_p->cache->start && end_position >= file_p->cache->end) { + lv_memcpy(cache_buffer, + write_buffer + (file_p->cache->start - start_position), + file_p->cache->end + 1 - file_p->cache->start); + } + else if(start_position >= file_p->cache->start && end_position <= file_p->cache->end) { + lv_memcpy(cache_buffer + (start_position - file_p->cache->start), + write_buffer, + end_position + 1 - start_position); + } + else if(end_position >= file_p->cache->start && end_position <= file_p->cache->end) { + lv_memcpy(cache_buffer, + write_buffer + (file_p->cache->start - start_position), + end_position + 1 - file_p->cache->start); + } + else if(start_position >= file_p->cache->start && start_position <= file_p->cache->end) { + lv_memcpy(cache_buffer + (start_position - file_p->cache->start), + write_buffer, + file_p->cache->end + 1 - start_position); + } + } + + file_p->cache->file_position += *bw; + + return res; +} + +static lv_fs_res_t lv_fs_seek_cached(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + lv_fs_res_t res = LV_FS_RES_OK; + switch(whence) { + case LV_FS_SEEK_SET: { + file_p->cache->file_position = pos; + break; + } + case LV_FS_SEEK_CUR: { + file_p->cache->file_position += pos; + break; + } + case LV_FS_SEEK_END: { + /*Because we don't know the file size, we do a little trick: do a FS seek, then get the new file position from FS*/ + res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence); + if(res == LV_FS_RES_OK) { + uint32_t tmp_position; + res = file_p->drv->tell_cb(file_p->drv, file_p->file_d, &tmp_position); + + if(res == LV_FS_RES_OK) { + file_p->cache->file_position = tmp_position; + } + } + break; + } + } + + return res; } diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h index ae29456ef..f8ffa1a0e 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h @@ -14,9 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" - -#include -#include +#include "lv_types.h" /********************* * DEFINES @@ -33,7 +31,7 @@ extern "C" { /** * Errors in the file system module. */ -enum _lv_fs_res_t { +typedef enum { LV_FS_RES_OK = 0, LV_FS_RES_HW_ERR, /*Low level hardware error*/ LV_FS_RES_FS_ERR, /*Error in the file system structure*/ @@ -47,27 +45,15 @@ enum _lv_fs_res_t { LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/ LV_FS_RES_INV_PARAM, /*Invalid parameter among arguments*/ LV_FS_RES_UNKNOWN, /*Other unknown error*/ -}; - -#ifdef DOXYGEN -typedef _lv_fs_res_t lv_fs_res_t; -#else -typedef uint8_t lv_fs_res_t; -#endif /*DOXYGEN*/ +} lv_fs_res_t; /** * File open mode. */ -enum _lv_fs_mode_t { +typedef enum { LV_FS_MODE_WR = 0x01, LV_FS_MODE_RD = 0x02, -}; - -#ifdef DOXYGEN -typedef _lv_fs_mode_t lv_fs_mode_t; -#else -typedef uint8_t lv_fs_mode_t; -#endif /*DOXYGEN*/ +} lv_fs_mode_t; /** * Seek modes. @@ -78,9 +64,9 @@ typedef enum { LV_FS_SEEK_END = 0x02, /**< Set the position from the end of the file*/ } lv_fs_whence_t; -struct _lv_fs_drv_t; -typedef struct _lv_fs_drv_t lv_fs_drv_t; -struct _lv_fs_drv_t { +struct lv_fs_drv_t; +typedef struct lv_fs_drv_t lv_fs_drv_t; +struct lv_fs_drv_t { char letter; uint32_t cache_size; bool (*ready_cb)(lv_fs_drv_t * drv); @@ -99,45 +85,16 @@ struct _lv_fs_drv_t { void * user_data; /**< Custom file user data*/ }; -typedef struct { - uint32_t start; - uint32_t end; - uint32_t file_position; - void * buffer; -} lv_fs_file_cache_t; - typedef struct { void * file_d; lv_fs_drv_t * drv; lv_fs_file_cache_t * cache; } lv_fs_file_t; -/* Extended path object to specify the buffer for memory-mapped files */ -typedef struct { - char path[4]; /* This is needed to make it compatible with a normal path */ - const void * buffer; - uint32_t size; -} lv_fs_path_ex_t; - -typedef struct { - void * dir_d; - lv_fs_drv_t * drv; -} lv_fs_dir_t; - /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Initialize the File system interface - */ -void _lv_fs_init(void); - -/** - * Deinitialize the File system interface - */ -void _lv_fs_deinit(void); - /** * Initialize a file system driver with default values. * It is used to ensure all fields have known values and not memory junk. @@ -218,7 +175,7 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u * Set the position of the 'cursor' (read write pointer) in a file * @param file_p pointer to a lv_fs_file_t variable * @param pos the new position expressed in bytes index (0: start of file) - * @param whence tells from where set the position. See @lv_fs_whence_t + * @param whence tells from where to set position. See lv_fs_whence_t * @return LV_FS_RES_OK or any error from lv_fs_res_t enum */ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence); diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h new file mode 100644 index 000000000..e8789e6c0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h @@ -0,0 +1,69 @@ +/** + * @file lv_fs_private.h + * + */ + +#ifndef LV_FS_PRIVATE_H +#define LV_FS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_fs.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_fs_file_cache_t { + uint32_t start; + uint32_t end; + uint32_t file_position; + void * buffer; +}; + +/** Extended path object to specify buffer for memory-mapped files */ +struct lv_fs_path_ex_t { + char path[4]; /**< This is needed to make it compatible with a normal path */ + const void * buffer; + uint32_t size; +}; + +struct lv_fs_dir_t { + void * dir_d; + lv_fs_drv_t * drv; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the File system interface + */ +void lv_fs_init(void); + +/** + * Deinitialize the File system interface + */ +void lv_fs_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FS_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c index 6debda073..ca1339ec5 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c @@ -39,7 +39,7 @@ static void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * nex * GLOBAL FUNCTIONS **********************/ -void _lv_ll_init(lv_ll_t * ll_p, uint32_t node_size) +void lv_ll_init(lv_ll_t * ll_p, uint32_t node_size) { ll_p->head = NULL; ll_p->tail = NULL; @@ -54,7 +54,7 @@ void _lv_ll_init(lv_ll_t * ll_p, uint32_t node_size) ll_p->n_size = node_size; } -void * _lv_ll_ins_head(lv_ll_t * ll_p) +void * lv_ll_ins_head(lv_ll_t * ll_p) { lv_ll_node_t * n_new; @@ -77,14 +77,14 @@ void * _lv_ll_ins_head(lv_ll_t * ll_p) return n_new; } -void * _lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act) +void * lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act) { lv_ll_node_t * n_new; if(NULL == ll_p || NULL == n_act) return NULL; - if(_lv_ll_get_head(ll_p) == n_act) { - n_new = _lv_ll_ins_head(ll_p); + if(lv_ll_get_head(ll_p) == n_act) { + n_new = lv_ll_ins_head(ll_p); if(n_new == NULL) return NULL; } else { @@ -92,7 +92,7 @@ void * _lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act) if(n_new == NULL) return NULL; lv_ll_node_t * n_prev; - n_prev = _lv_ll_get_prev(ll_p, n_act); + n_prev = lv_ll_get_prev(ll_p, n_act); node_set_next(ll_p, n_prev, n_new); node_set_prev(ll_p, n_new, n_prev); node_set_prev(ll_p, n_act, n_new); @@ -102,7 +102,7 @@ void * _lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act) return n_new; } -void * _lv_ll_ins_tail(lv_ll_t * ll_p) +void * lv_ll_ins_tail(lv_ll_t * ll_p) { lv_ll_node_t * n_new; @@ -124,13 +124,13 @@ void * _lv_ll_ins_tail(lv_ll_t * ll_p) return n_new; } -void _lv_ll_remove(lv_ll_t * ll_p, void * node_p) +void lv_ll_remove(lv_ll_t * ll_p, void * node_p) { if(ll_p == NULL) return; - if(_lv_ll_get_head(ll_p) == node_p) { + if(lv_ll_get_head(ll_p) == node_p) { /*The new head will be the node after 'n_act'*/ - ll_p->head = _lv_ll_get_next(ll_p, node_p); + ll_p->head = lv_ll_get_next(ll_p, node_p); if(ll_p->head == NULL) { ll_p->tail = NULL; } @@ -138,9 +138,9 @@ void _lv_ll_remove(lv_ll_t * ll_p, void * node_p) node_set_prev(ll_p, ll_p->head, NULL); } } - else if(_lv_ll_get_tail(ll_p) == node_p) { + else if(lv_ll_get_tail(ll_p) == node_p) { /*The new tail will be the node before 'n_act'*/ - ll_p->tail = _lv_ll_get_prev(ll_p, node_p); + ll_p->tail = lv_ll_get_prev(ll_p, node_p); if(ll_p->tail == NULL) { ll_p->head = NULL; } @@ -149,26 +149,26 @@ void _lv_ll_remove(lv_ll_t * ll_p, void * node_p) } } else { - lv_ll_node_t * n_prev = _lv_ll_get_prev(ll_p, node_p); - lv_ll_node_t * n_next = _lv_ll_get_next(ll_p, node_p); + lv_ll_node_t * n_prev = lv_ll_get_prev(ll_p, node_p); + lv_ll_node_t * n_next = lv_ll_get_next(ll_p, node_p); node_set_next(ll_p, n_prev, n_next); node_set_prev(ll_p, n_next, n_prev); } } -void _lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *)) +void lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *)) { void * i; void * i_next; - i = _lv_ll_get_head(ll_p); + i = lv_ll_get_head(ll_p); i_next = NULL; while(i != NULL) { - i_next = _lv_ll_get_next(ll_p, i); + i_next = lv_ll_get_next(ll_p, i); if(cleanup == NULL) { - _lv_ll_remove(ll_p, i); + lv_ll_remove(ll_p, i); lv_free(i); } else { @@ -178,9 +178,9 @@ void _lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *)) } } -void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head) +void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head) { - _lv_ll_remove(ll_ori_p, node); + lv_ll_remove(ll_ori_p, node); if(head) { /*Set node as head*/ @@ -212,19 +212,19 @@ void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool h } } -void * _lv_ll_get_head(const lv_ll_t * ll_p) +void * lv_ll_get_head(const lv_ll_t * ll_p) { if(ll_p == NULL) return NULL; return ll_p->head; } -void * _lv_ll_get_tail(const lv_ll_t * ll_p) +void * lv_ll_get_tail(const lv_ll_t * ll_p) { if(ll_p == NULL) return NULL; return ll_p->tail; } -void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act) +void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act) { /*Pointer to the next node is stored in the end of this node. *Go there and return the address found there*/ @@ -233,7 +233,7 @@ void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act) return *((lv_ll_node_t **)n_act_d); } -void * _lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act) +void * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act) { /*Pointer to the prev. node is stored in the end of this node. *Go there and return the address found there*/ @@ -242,32 +242,32 @@ void * _lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act) return *((lv_ll_node_t **)n_act_d); } -uint32_t _lv_ll_get_len(const lv_ll_t * ll_p) +uint32_t lv_ll_get_len(const lv_ll_t * ll_p) { uint32_t len = 0; void * node; - for(node = _lv_ll_get_head(ll_p); node != NULL; node = _lv_ll_get_next(ll_p, node)) { + for(node = lv_ll_get_head(ll_p); node != NULL; node = lv_ll_get_next(ll_p, node)) { len++; } return len; } -void _lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after) +void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after) { if(n_act == n_after) return; /*Can't move before itself*/ void * n_before; if(n_after != NULL) - n_before = _lv_ll_get_prev(ll_p, n_after); + n_before = lv_ll_get_prev(ll_p, n_after); else - n_before = _lv_ll_get_tail(ll_p); /*if `n_after` is NULL `n_act` should be the new tail*/ + n_before = lv_ll_get_tail(ll_p); /*if `n_after` is NULL `n_act` should be the new tail*/ if(n_act == n_before) return; /*Already before `n_after`*/ /*It's much easier to remove from the list and add again*/ - _lv_ll_remove(ll_p, n_act); + lv_ll_remove(ll_p, n_act); /*Add again by setting the prev. and next nodes*/ node_set_next(ll_p, n_before, n_act); @@ -282,7 +282,7 @@ void _lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after) if(n_before == NULL) ll_p->head = n_act; } -bool _lv_ll_is_empty(lv_ll_t * ll_p) +bool lv_ll_is_empty(lv_ll_t * ll_p) { if(ll_p == NULL) return true; @@ -291,6 +291,11 @@ bool _lv_ll_is_empty(lv_ll_t * ll_p) return false; } +void lv_ll_clear(lv_ll_t * ll_p) +{ + lv_ll_clear_custom(ll_p, NULL); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.h index 676e404fd..ee0836ef5 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.h @@ -13,9 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include -#include +#include "../lv_conf_internal.h" +#include "lv_types.h" /********************* * DEFINES @@ -44,14 +43,14 @@ typedef struct { * @param ll_p pointer to lv_ll_t variable * @param node_size the size of 1 node in bytes */ -void _lv_ll_init(lv_ll_t * ll_p, uint32_t node_size); +void lv_ll_init(lv_ll_t * ll_p, uint32_t node_size); /** * Add a new head to a linked list * @param ll_p pointer to linked list * @return pointer to the new head */ -void * _lv_ll_ins_head(lv_ll_t * ll_p); +void * lv_ll_ins_head(lv_ll_t * ll_p); /** * Insert a new node in front of the n_act node @@ -59,14 +58,14 @@ void * _lv_ll_ins_head(lv_ll_t * ll_p); * @param n_act pointer a node * @return pointer to the new node */ -void * _lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act); +void * lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act); /** * Add a new tail to a linked list * @param ll_p pointer to linked list * @return pointer to the new tail */ -void * _lv_ll_ins_tail(lv_ll_t * ll_p); +void * lv_ll_ins_tail(lv_ll_t * ll_p); /** * Remove the node 'node_p' from 'll_p' linked list. @@ -74,18 +73,15 @@ void * _lv_ll_ins_tail(lv_ll_t * ll_p); * @param ll_p pointer to the linked list of 'node_p' * @param node_p pointer to node in 'll_p' linked list */ -void _lv_ll_remove(lv_ll_t * ll_p, void * node_p); +void lv_ll_remove(lv_ll_t * ll_p, void * node_p); -void _lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *)); +void lv_ll_clear_custom(lv_ll_t * ll_p, void(*cleanup)(void *)); /** * Remove and free all elements from a linked list. The list remain valid but become empty. * @param ll_p pointer to linked list */ -static inline void _lv_ll_clear(lv_ll_t * ll_p) -{ - _lv_ll_clear_custom(ll_p, NULL); -} +void lv_ll_clear(lv_ll_t * ll_p); /** * Move a node to a new linked list @@ -95,21 +91,21 @@ static inline void _lv_ll_clear(lv_ll_t * ll_p) * @param head true: be the head in the new list * false be the tail in the new list */ -void _lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head); +void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head); /** * Return with head node of the linked list * @param ll_p pointer to linked list * @return pointer to the head of 'll_p' */ -void * _lv_ll_get_head(const lv_ll_t * ll_p); +void * lv_ll_get_head(const lv_ll_t * ll_p); /** * Return with tail node of the linked list * @param ll_p pointer to linked list * @return pointer to the tail of 'll_p' */ -void * _lv_ll_get_tail(const lv_ll_t * ll_p); +void * lv_ll_get_tail(const lv_ll_t * ll_p); /** * Return with the pointer of the next node after 'n_act' @@ -117,7 +113,7 @@ void * _lv_ll_get_tail(const lv_ll_t * ll_p); * @param n_act pointer a node * @return pointer to the next node */ -void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act); +void * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act); /** * Return with the pointer of the previous node after 'n_act' @@ -125,16 +121,16 @@ void * _lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act); * @param n_act pointer a node * @return pointer to the previous node */ -void * _lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act); +void * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act); /** * Return the length of the linked list. * @param ll_p pointer to linked list * @return length of the linked list */ -uint32_t _lv_ll_get_len(const lv_ll_t * ll_p); +uint32_t lv_ll_get_len(const lv_ll_t * ll_p); -/** +/* * TODO * @param ll_p * @param n1_p @@ -143,27 +139,28 @@ void lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p); */ /** - * Move a node before an other node in the same linked list + * Move a node before another node in the same linked list + * * @param ll_p pointer to a linked list * @param n_act pointer to node to move * @param n_after pointer to a node which should be after `n_act` */ -void _lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after); +void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after); /** * Check if a linked list is empty * @param ll_p pointer to a linked list * @return true: the linked list is empty; false: not empty */ -bool _lv_ll_is_empty(lv_ll_t * ll_p); +bool lv_ll_is_empty(lv_ll_t * ll_p); /********************** * MACROS **********************/ -#define _LV_LL_READ(list, i) for(i = _lv_ll_get_head(list); i != NULL; i = _lv_ll_get_next(list, i)) +#define LV_LL_READ(list, i) for(i = lv_ll_get_head(list); i != NULL; i = lv_ll_get_next(list, i)) -#define _LV_LL_READ_BACK(list, i) for(i = _lv_ll_get_tail(list); i != NULL; i = _lv_ll_get_prev(list, i)) +#define LV_LL_READ_BACK(list, i) for(i = lv_ll_get_tail(list); i != NULL; i = lv_ll_get_prev(list, i)) #ifdef __cplusplus } /*extern "C"*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c index d72c11bd0..3f3caec8d 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c @@ -9,8 +9,7 @@ #include "lv_log.h" #if LV_USE_LOG -#include -#include +#include "../misc/lv_types.h" #include "../stdlib/lv_sprintf.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" @@ -70,9 +69,9 @@ void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb) custom_print_cb = print_cb; } -void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * func, const char * format, ...) +void lv_log_add(lv_log_level_t level, const char * file, int line, const char * func, const char * format, ...) { - if(level >= _LV_LOG_LEVEL_NUM) return; /*Invalid level*/ + if(level >= LV_LOG_LEVEL_NUM) return; /*Invalid level*/ if(level >= LV_LOG_LEVEL) { va_list args; @@ -102,7 +101,8 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * lvl_prefix[level], LOG_TIMESTAMP_EXPR func); vprintf(format, args); printf(LOG_FILE_LINE_FMT "\n" LOG_FILE_LINE_EXPR); -#else + fflush(stdout); +#endif if(custom_print_cb) { char buf[512]; char msg[256]; @@ -111,7 +111,6 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * lvl_prefix[level], LOG_TIMESTAMP_EXPR func, msg LOG_FILE_LINE_EXPR); custom_print_cb(level, buf); } -#endif #if LV_LOG_USE_TIMESTAMP last_log_time = t; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h index 87ca3820a..7774ba6fc 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h @@ -14,7 +14,6 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" -#include #include "lv_types.h" @@ -24,13 +23,13 @@ extern "C" { /*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/ -#define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information*/ -#define LV_LOG_LEVEL_INFO 1 /**< Log important events*/ -#define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem*/ -#define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail*/ -#define LV_LOG_LEVEL_USER 4 /**< Custom logs from the user*/ -#define LV_LOG_LEVEL_NONE 5 /**< Do not log anything*/ -#define _LV_LOG_LEVEL_NUM 6 /**< Number of log levels*/ +#define LV_LOG_LEVEL_TRACE 0 /**< Log detailed information. */ +#define LV_LOG_LEVEL_INFO 1 /**< Log important events. */ +#define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem. */ +#define LV_LOG_LEVEL_ERROR 3 /**< Log only critical issues, when system may fail. */ +#define LV_LOG_LEVEL_USER 4 /**< Log only custom log messages added by the user. */ +#define LV_LOG_LEVEL_NONE 5 /**< Do not log anything. */ +#define LV_LOG_LEVEL_NUM 6 /**< Number of log levels */ LV_EXPORT_CONST_INT(LV_LOG_LEVEL_TRACE); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_INFO); @@ -89,15 +88,15 @@ void lv_log(const char * format, ...) LV_FORMAT_ATTRIBUTE(1, 2); * @param format printf-like format string * @param ... parameters for `format` */ -void _lv_log_add(lv_log_level_t level, const char * file, int line, - const char * func, const char * format, ...) LV_FORMAT_ATTRIBUTE(5, 6); +void lv_log_add(lv_log_level_t level, const char * file, int line, + const char * func, const char * format, ...) LV_FORMAT_ATTRIBUTE(5, 6); /********************** * MACROS **********************/ #ifndef LV_LOG_TRACE # if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE -# define LV_LOG_TRACE(...) _lv_log_add(LV_LOG_LEVEL_TRACE, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# define LV_LOG_TRACE(...) lv_log_add(LV_LOG_LEVEL_TRACE, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) # else # define LV_LOG_TRACE(...) do {}while(0) # endif @@ -105,7 +104,7 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, #ifndef LV_LOG_INFO # if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO -# define LV_LOG_INFO(...) _lv_log_add(LV_LOG_LEVEL_INFO, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# define LV_LOG_INFO(...) lv_log_add(LV_LOG_LEVEL_INFO, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) # else # define LV_LOG_INFO(...) do {}while(0) # endif @@ -113,7 +112,7 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, #ifndef LV_LOG_WARN # if LV_LOG_LEVEL <= LV_LOG_LEVEL_WARN -# define LV_LOG_WARN(...) _lv_log_add(LV_LOG_LEVEL_WARN, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# define LV_LOG_WARN(...) lv_log_add(LV_LOG_LEVEL_WARN, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) # else # define LV_LOG_WARN(...) do {}while(0) # endif @@ -121,7 +120,7 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, #ifndef LV_LOG_ERROR # if LV_LOG_LEVEL <= LV_LOG_LEVEL_ERROR -# define LV_LOG_ERROR(...) _lv_log_add(LV_LOG_LEVEL_ERROR, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# define LV_LOG_ERROR(...) lv_log_add(LV_LOG_LEVEL_ERROR, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) # else # define LV_LOG_ERROR(...) do {}while(0) # endif @@ -129,7 +128,7 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, #ifndef LV_LOG_USER # if LV_LOG_LEVEL <= LV_LOG_LEVEL_USER -# define LV_LOG_USER(...) _lv_log_add(LV_LOG_LEVEL_USER, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) +# define LV_LOG_USER(...) lv_log_add(LV_LOG_LEVEL_USER, LV_LOG_FILE, LV_LOG_LINE, __func__, __VA_ARGS__) # else # define LV_LOG_USER(...) do {}while(0) # endif @@ -146,7 +145,7 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, #else /*LV_USE_LOG*/ /*Do nothing if `LV_USE_LOG 0`*/ -#define _lv_log_add(level, file, line, ...) +#define lv_log_add(level, file, line, ...) #define LV_LOG_TRACE(...) do {}while(0) #define LV_LOG_INFO(...) do {}while(0) #define LV_LOG_WARN(...) do {}while(0) diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c index 5f3618cf4..f8d4c0682 100755 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c @@ -23,13 +23,13 @@ * TYPEDEFS **********************/ -struct _lv_lru_item_t { +struct lv_lru_item_t { void * value; void * key; size_t value_length; size_t key_length; uint64_t access_count; - struct _lv_lru_item_t * next; + struct lv_lru_item_t * next; }; /********************** @@ -164,7 +164,7 @@ lv_lru_res_t lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, v item = lv_lru_pop_or_create_item(cache); item->value = value; item->key = lv_malloc(key_length); - memcpy(item->key, key, key_length); + lv_memcpy(item->key, key, key_length); item->value_length = value_length; item->key_length = key_length; required = (int) value_length; @@ -303,7 +303,7 @@ static int lv_lru_cmp_keys(lv_lru_item_t * item, const void * key, uint32_t key_ return 1; } else { - return memcmp(key, item->key, key_length); + return lv_memcmp(key, item->key, key_length); } } diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h index 02172d202..1bb25861f 100755 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h @@ -18,9 +18,6 @@ extern "C" { #include "lv_types.h" -#include -#include - /********************* * DEFINES *********************/ @@ -40,7 +37,7 @@ typedef enum { typedef void (*lv_lru_free_cb_t)(void * v); -typedef struct _lv_lru_item_t lv_lru_item_t; +typedef struct lv_lru_item_t lv_lru_item_t; typedef struct lv_lru_t { lv_lru_item_t ** items; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_math.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_math.c index 59e946062..bd728fbcf 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_math.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_math.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_math.c * */ @@ -222,6 +222,95 @@ void LV_ATTRIBUTE_FAST_MEM lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask) q->f = (root & 0xf) << 4; } +/* +// Alternative Integer Square Root function +// Contributors include Arne Steinarson for the basic approximation idea, +// Dann Corbit and Mathew Hendry for the first cut at the algorithm, +// Lawrence Kirby for the rearrangement, improvements and range optimization +// and Paul Hsieh for the round-then-adjust idea. +*/ +int32_t LV_ATTRIBUTE_FAST_MEM lv_sqrt32(uint32_t x) +{ + static const unsigned char sqq_table[] = { + 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, + 59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, + 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, + 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145, + 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157, + 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, + 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, + 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, + 189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, + 198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206, + 207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215, + 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223, + 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231, + 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, + 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, + 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, + 253, 254, 254, 255 + }; + + int32_t xn; + + if(x >= 0x10000) + if(x >= 0x1000000) + if(x >= 0x10000000) + if(x >= 0x40000000) { + if(x >= 65535UL * 65535UL) + return 65535; + xn = sqq_table[x >> 24] << 8; + } + else + xn = sqq_table[x >> 22] << 7; + else if(x >= 0x4000000) + xn = sqq_table[x >> 20] << 6; + else + xn = sqq_table[x >> 18] << 5; + else { + if(x >= 0x100000) + if(x >= 0x400000) + xn = sqq_table[x >> 16] << 4; + else + xn = sqq_table[x >> 14] << 3; + else if(x >= 0x40000) + xn = sqq_table[x >> 12] << 2; + else + xn = sqq_table[x >> 10] << 1; + + goto nr1; + } + else if(x >= 0x100) { + if(x >= 0x1000) + if(x >= 0x4000) + xn = (sqq_table[x >> 8] >> 0) + 1; + else + xn = (sqq_table[x >> 6] >> 1) + 1; + else if(x >= 0x400) + xn = (sqq_table[x >> 4] >> 2) + 1; + else + xn = (sqq_table[x >> 2] >> 3) + 1; + + goto adj; + } + else + return sqq_table[x] >> 4; + + /* Run two iterations of the standard convergence formula */ + + xn = (xn + 1 + x / xn) / 2; +nr1: + xn = (xn + 1 + x / xn) / 2; +adj: + + if(xn * xn > (int32_t)x) /* Correct rounding if necessary */ + xn--; + + return xn; +} + uint16_t lv_atan2(int x, int y) { /** @@ -350,6 +439,18 @@ uint32_t lv_rand(uint32_t min, uint32_t max) return (rand_seed % (max - min + 1)) + min; } +int32_t LV_ATTRIBUTE_FAST_MEM lv_trigo_cos(int16_t angle) +{ + return lv_trigo_sin(angle + 90); +} + +int32_t lv_bezier3(int32_t t, int32_t u0, uint32_t u1, int32_t u2, int32_t u3) +{ + LV_UNUSED(u0); + LV_UNUSED(u3); + return lv_cubic_bezier(t, 341, u1, 683, u2); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_math.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_math.h index d1a543d3d..05e159f13 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_math.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_math.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_math.h * */ @@ -14,7 +14,6 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" -#include #include "lv_types.h" /********************* @@ -27,9 +26,12 @@ extern "C" { #define LV_BEZIER_VAL_MAX (1L << LV_BEZIER_VAL_SHIFT) /**< Max time in Bezier functions (not [0..1] to use integers)*/ #define LV_BEZIER_VAL_FLOAT(f) ((int32_t)((f) * LV_BEZIER_VAL_MAX)) /**< Convert const float number cubic-bezier values to fix-point value*/ -/*Align up value x to align, align must be a power of two*/ +/** Align up value x to align, align must be a power of two */ #define LV_ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) +/** Round up value x to round, round can be any integer number */ +#define LV_ROUND_UP(x, round) ((((x) + ((round) - 1)) / (round)) * (round)) + /********************** * TYPEDEFS **********************/ @@ -51,10 +53,7 @@ typedef struct { */ int32_t /* LV_ATTRIBUTE_FAST_MEM */ lv_trigo_sin(int16_t angle); -static inline int32_t LV_ATTRIBUTE_FAST_MEM lv_trigo_cos(int16_t angle) -{ - return lv_trigo_sin(angle + 90); -} +int32_t LV_ATTRIBUTE_FAST_MEM lv_trigo_cos(int16_t angle); //! @endcond @@ -78,12 +77,8 @@ int32_t lv_cubic_bezier(int32_t x, int32_t x1, int32_t y1, int32_t x2, int32_t y * @param u3 must be LV_BEZIER_VAL_MAX * @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX] */ -static inline int32_t lv_bezier3(int32_t t, int32_t u0, uint32_t u1, int32_t u2, int32_t u3) -{ - LV_UNUSED(u0); - LV_UNUSED(u3); - return lv_cubic_bezier(t, 341, u1, 683, u2); -} +int32_t lv_bezier3(int32_t t, int32_t u0, uint32_t u1, int32_t u2, int32_t u3); + /** * Calculate the atan2 of a vector. @@ -109,6 +104,22 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t //! @endcond +/** + * Alternative (fast, approximate) implementation for getting the square root of an integer. + * @param x integer which square root should be calculated + */ +int32_t /* LV_ATTRIBUTE_FAST_MEM */ lv_sqrt32(uint32_t x); + +/** + * Calculate the square of an integer (input range is 0..32767). + * @param x input + * @return square + */ +static inline int32_t lv_sqr(int32_t x) +{ + return x * x; +} + /** * Calculate the integer exponents. * @param base diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c new file mode 100644 index 000000000..4a6bb6374 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c @@ -0,0 +1,225 @@ +/** + * @file lv_matrix.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_matrix.h" + +#if LV_USE_MATRIX + +#include "../stdlib/lv_string.h" +#include "lv_math.h" +#include +/********************* + * DEFINES + *********************/ +#ifndef M_PI + #define M_PI 3.1415926f +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_matrix_identity(lv_matrix_t * matrix) +{ + matrix->m[0][0] = 1.0f; + matrix->m[0][1] = 0.0f; + matrix->m[0][2] = 0.0f; + matrix->m[1][0] = 0.0f; + matrix->m[1][1] = 1.0f; + matrix->m[1][2] = 0.0f; + matrix->m[2][0] = 0.0f; + matrix->m[2][1] = 0.0f; + matrix->m[2][2] = 1.0f; +} + +void lv_matrix_translate(lv_matrix_t * matrix, float dx, float dy) +{ + if(lv_matrix_is_identity_or_translation(matrix)) { + /*optimization for matrix translation.*/ + matrix->m[0][2] += dx; + matrix->m[1][2] += dy; + return; + } + + lv_matrix_t tlm = {{ + {1.0f, 0.0f, dx}, + {0.0f, 1.0f, dy}, + {0.0f, 0.0f, 1.0f}, + } + }; + + lv_matrix_multiply(matrix, &tlm); +} + +void lv_matrix_scale(lv_matrix_t * matrix, float scale_x, float scale_y) +{ + lv_matrix_t scm = {{ + {scale_x, 0.0f, 0.0f}, + {0.0f, scale_y, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + lv_matrix_multiply(matrix, &scm); +} + +void lv_matrix_rotate(lv_matrix_t * matrix, float degree) +{ + float radian = degree / 180.0f * (float)M_PI; + float cos_r = cosf(radian); + float sin_r = sinf(radian); + + lv_matrix_t rtm = {{ + {cos_r, -sin_r, 0.0f}, + {sin_r, cos_r, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + lv_matrix_multiply(matrix, &rtm); +} + +void lv_matrix_skew(lv_matrix_t * matrix, float skew_x, float skew_y) +{ + float rskew_x = skew_x / 180.0f * (float)M_PI; + float rskew_y = skew_y / 180.0f * (float)M_PI; + float tan_x = tanf(rskew_x); + float tan_y = tanf(rskew_y); + + lv_matrix_t skm = {{ + {1.0f, tan_x, 0.0f}, + {tan_y, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + lv_matrix_multiply(matrix, &skm); +} + +void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * mul) +{ + /*TODO: use NEON to optimize this function on ARM architecture.*/ + lv_matrix_t tmp; + + for(int y = 0; y < 3; y++) { + for(int x = 0; x < 3; x++) { + tmp.m[y][x] = (matrix->m[y][0] * mul->m[0][x]) + + (matrix->m[y][1] * mul->m[1][x]) + + (matrix->m[y][2] * mul->m[2][x]); + } + } + + lv_memcpy(matrix, &tmp, sizeof(lv_matrix_t)); +} + +bool lv_matrix_inverse(lv_matrix_t * matrix, const lv_matrix_t * m) +{ + float det00, det01, det02; + float d; + bool is_affine; + + /* Test for identity matrix. */ + if(m == NULL) { + lv_matrix_identity(matrix); + return true; + } + + det00 = (m->m[1][1] * m->m[2][2]) - (m->m[2][1] * m->m[1][2]); + det01 = (m->m[2][0] * m->m[1][2]) - (m->m[1][0] * m->m[2][2]); + det02 = (m->m[1][0] * m->m[2][1]) - (m->m[2][0] * m->m[1][1]); + + /* Compute determinant. */ + d = (m->m[0][0] * det00) + (m->m[0][1] * det01) + (m->m[0][2] * det02); + + /* Return 0 if there is no inverse matrix. */ + if(d == 0.0f) + return false; + + /* Compute reciprocal. */ + d = 1.0f / d; + + /* Determine if the matrix is affine. */ + is_affine = (m->m[2][0] == 0.0f) && (m->m[2][1] == 0.0f) && (m->m[2][2] == 1.0f); + + matrix->m[0][0] = d * det00; + matrix->m[0][1] = d * ((m->m[2][1] * m->m[0][2]) - (m->m[0][1] * m->m[2][2])); + matrix->m[0][2] = d * ((m->m[0][1] * m->m[1][2]) - (m->m[1][1] * m->m[0][2])); + matrix->m[1][0] = d * det01; + matrix->m[1][1] = d * ((m->m[0][0] * m->m[2][2]) - (m->m[2][0] * m->m[0][2])); + matrix->m[1][2] = d * ((m->m[1][0] * m->m[0][2]) - (m->m[0][0] * m->m[1][2])); + matrix->m[2][0] = is_affine ? 0.0f : d * det02; + matrix->m[2][1] = is_affine ? 0.0f : d * ((m->m[2][0] * m->m[0][1]) - (m->m[0][0] * m->m[2][1])); + matrix->m[2][2] = is_affine ? 1.0f : d * ((m->m[0][0] * m->m[1][1]) - (m->m[1][0] * m->m[0][1])); + + /* Success. */ + return true; +} + +lv_point_precise_t lv_matrix_transform_precise_point(const lv_matrix_t * matrix, const lv_point_precise_t * point) +{ + lv_point_precise_t p; + p.x = (lv_value_precise_t)roundf(point->x * matrix->m[0][0] + point->y * matrix->m[0][1] + matrix->m[0][2]); + p.y = (lv_value_precise_t)roundf(point->x * matrix->m[1][0] + point->y * matrix->m[1][1] + matrix->m[1][2]); + return p; +} + +lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * area) +{ + lv_area_t res; + lv_point_precise_t p[4] = { + {area->x1, area->y1}, + {area->x1, area->y2}, + {area->x2, area->y1}, + {area->x2, area->y2}, + }; + p[0] = lv_matrix_transform_precise_point(matrix, &p[0]); + p[1] = lv_matrix_transform_precise_point(matrix, &p[1]); + p[2] = lv_matrix_transform_precise_point(matrix, &p[2]); + p[3] = lv_matrix_transform_precise_point(matrix, &p[3]); + + res.x1 = (int32_t)(LV_MIN4(p[0].x, p[1].x, p[2].x, p[3].x)); + res.x2 = (int32_t)(LV_MAX4(p[0].x, p[1].x, p[2].x, p[3].x)); + res.y1 = (int32_t)(LV_MIN4(p[0].y, p[1].y, p[2].y, p[3].y)); + res.y2 = (int32_t)(LV_MAX4(p[0].y, p[1].y, p[2].y, p[3].y)); + + return res; +} + +bool lv_matrix_is_identity_or_translation(const lv_matrix_t * matrix) +{ + return (matrix->m[0][0] == 1.0f && + matrix->m[0][1] == 0.0f && + matrix->m[1][0] == 0.0f && + matrix->m[1][1] == 1.0f && + matrix->m[2][0] == 0.0f && + matrix->m[2][1] == 0.0f && + matrix->m[2][2] == 1.0f); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_MATRIX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h new file mode 100644 index 000000000..9583fa9af --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h @@ -0,0 +1,129 @@ +/** + * @file lv_matrix.h + * + */ + +#ifndef LV_MATRIX_H +#define LV_MATRIX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_conf_internal.h" + +#if LV_USE_MATRIX + +#include "lv_types.h" +#include "lv_area.h" + +/********************* + * DEFINES + *********************/ + +#if !LV_USE_FLOAT +#error "LV_USE_FLOAT is required for lv_matrix" +#endif + +/********************** + * TYPEDEFS + **********************/ + +struct lv_matrix_t { + float m[3][3]; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Set matrix to identity matrix + * @param matrix pointer to a matrix + */ +void lv_matrix_identity(lv_matrix_t * matrix); + +/** + * Translate the matrix to new position + * @param matrix pointer to a matrix + * @param tx the amount of translate in x direction + * @param tx the amount of translate in y direction + */ +void lv_matrix_translate(lv_matrix_t * matrix, float tx, float ty); + +/** + * Change the scale factor of the matrix + * @param matrix pointer to a matrix + * @param scale_x the scale factor for the X direction + * @param scale_y the scale factor for the Y direction + */ +void lv_matrix_scale(lv_matrix_t * matrix, float scale_x, float scale_y); + +/** + * Rotate the matrix with origin + * @param matrix pointer to a matrix + * @param degree angle to rotate + */ +void lv_matrix_rotate(lv_matrix_t * matrix, float degree); + +/** + * Change the skew factor of the matrix + * @param matrix pointer to a matrix + * @param skew_x the skew factor for x direction + * @param skew_y the skew factor for y direction + */ +void lv_matrix_skew(lv_matrix_t * matrix, float skew_x, float skew_y); + +/** + * Multiply two matrix and store the result to the first one + * @param matrix pointer to a matrix + * @param matrix2 pointer to another matrix + */ +void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * mul); + +/** + * Invert the matrix + * @param matrix pointer to a matrix + * @param m pointer to another matrix (optional) + * @return true: the matrix is invertible, false: the matrix is singular and cannot be inverted + */ +bool lv_matrix_inverse(lv_matrix_t * matrix, const lv_matrix_t * m); + +/** + * Transform a point by a matrix + * @param matrix pointer to a matrix + * @param point pointer to a point + * @return the transformed point + */ +lv_point_precise_t lv_matrix_transform_precise_point(const lv_matrix_t * matrix, const lv_point_precise_t * point); + +/** + * Transform an area by a matrix + * @param matrix pointer to a matrix + * @param area pointer to an area + * @return the transformed area + */ +lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * area); + +/** + * Check if the matrix is identity or translation matrix + * @param matrix pointer to a matrix + * @return true: the matrix is identity or translation matrix, false: the matrix is not identity or translation matrix + */ +bool lv_matrix_is_identity_or_translation(const lv_matrix_t * matrix); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_MATRIX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MATRIX_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.c index 31aa66cf9..cbcdf4e64 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.c @@ -42,7 +42,7 @@ lv_color_t lv_palette_main(lv_palette_t p) LV_COLOR_MAKE(0x79, 0x55, 0x48), LV_COLOR_MAKE(0x60, 0x7D, 0x8B), LV_COLOR_MAKE(0x9E, 0x9E, 0x9E) }; - if(p >= _LV_PALETTE_LAST) { + if(p >= LV_PALETTE_LAST) { LV_LOG_WARN("Invalid palette: %d", p); return lv_color_black(); } @@ -75,7 +75,7 @@ lv_color_t lv_palette_lighten(lv_palette_t p, uint8_t lvl) {LV_COLOR_MAKE(0xBD, 0xBD, 0xBD), LV_COLOR_MAKE(0xE0, 0xE0, 0xE0), LV_COLOR_MAKE(0xEE, 0xEE, 0xEE), LV_COLOR_MAKE(0xF5, 0xF5, 0xF5), LV_COLOR_MAKE(0xFA, 0xFA, 0xFA)}, }; - if(p >= _LV_PALETTE_LAST) { + if(p >= LV_PALETTE_LAST) { LV_LOG_WARN("Invalid palette: %d", p); return lv_color_black(); } @@ -114,7 +114,7 @@ lv_color_t lv_palette_darken(lv_palette_t p, uint8_t lvl) {LV_COLOR_MAKE(0x75, 0x75, 0x75), LV_COLOR_MAKE(0x61, 0x61, 0x61), LV_COLOR_MAKE(0x42, 0x42, 0x42), LV_COLOR_MAKE(0x21, 0x21, 0x21)}, }; - if(p >= _LV_PALETTE_LAST) { + if(p >= LV_PALETTE_LAST) { LV_LOG_WARN("Invalid palette: %d", p); return lv_color_black(); } diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.h index fedac9eee..d2f408ca2 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_palette.h @@ -14,8 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "lv_color.h" -#include -#include +#include "lv_types.h" /********************* * DEFINES @@ -44,7 +43,7 @@ typedef enum { LV_PALETTE_BROWN, LV_PALETTE_BLUE_GREY, LV_PALETTE_GREY, - _LV_PALETTE_LAST, + LV_PALETTE_LAST, LV_PALETTE_NONE = 0xff, } lv_palette_t; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.c index ba278ae94..b6b6fd435 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ -#include "lv_profiler_builtin.h" +#include "lv_profiler_builtin_private.h" #include "../lvgl.h" #include "../core/lv_global.h" @@ -54,7 +54,7 @@ typedef struct { /** * @brief Structure representing a context for the LVGL built-in profiler */ -typedef struct _lv_profiler_builtin_ctx_t { +typedef struct lv_profiler_builtin_ctx_t { lv_profiler_builtin_item_t * item_arr; /**< Pointer to an array of profiler items */ uint32_t item_num; /**< Number of profiler items in the array */ uint32_t cur_index; /**< Index of the current profiler item */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.h index ac79f8e6f..aa0220b20 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.h @@ -18,9 +18,7 @@ extern "C" { #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN -#include -#include -#include +#include "lv_types.h" /********************* * DEFINES @@ -35,18 +33,6 @@ extern "C" { * TYPEDEFS **********************/ -/** - * @brief LVGL profiler built-in configuration structure - */ -typedef struct { - size_t buf_size; /**< The size of the buffer used for profiling data */ - uint32_t tick_per_sec; /**< The number of ticks per second */ - uint32_t (*tick_get_cb)(void); /**< Callback function to get the current tick count */ - void (*flush_cb)(const char * buf); /**< Callback function to flush the profiling data */ - int (*tid_get_cb)(void); /**< Callback function to get the current thread ID */ - int (*cpu_get_cb)(void); /**< Callback function to get the current CPU */ -} lv_profiler_builtin_config_t; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin_private.h new file mode 100644 index 000000000..3fb9938a2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin_private.h @@ -0,0 +1,56 @@ +/** + * @file lv_profiler_builtin_private.h + * + */ + +#ifndef LV_PROFILER_BUILTIN_PRIVATE_H +#define LV_PROFILER_BUILTIN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_profiler_builtin.h" + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * @brief LVGL profiler built-in configuration structure + */ +struct lv_profiler_builtin_config_t { + size_t buf_size; /**< The size of the buffer used for profiling data */ + uint32_t tick_per_sec; /**< The number of ticks per second */ + uint32_t (*tick_get_cb)(void); /**< Callback function to get the current tick count */ + void (*flush_cb)(const char * buf); /**< Callback function to flush the profiling data */ + int (*tid_get_cb)(void); /**< Callback function to get the current thread ID */ + int (*cpu_get_cb)(void); /**< Callback function to get the current CPU */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PROFILER_BUILTIN_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.c index 8a564599b..8a7328caa 100755 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_rb.h" +#include "lv_rb_private.h" #include "../stdlib/lv_string.h" /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.h index 1533cea75..bec0a788f 100755 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb.h @@ -14,8 +14,8 @@ extern "C" { * INCLUDES *********************/ #include "lv_types.h" -#include "stdbool.h" #include "lv_assert.h" +#include "lv_types.h" /********************* * DEFINES @@ -30,24 +30,10 @@ typedef enum { LV_RB_COLOR_BLACK } lv_rb_color_t; -typedef struct lv_rb_node_t { - struct lv_rb_node_t * parent; - struct lv_rb_node_t * left; - struct lv_rb_node_t * right; - lv_rb_color_t color; - void * data; -} lv_rb_node_t; - typedef int8_t lv_rb_compare_res_t; typedef lv_rb_compare_res_t (*lv_rb_compare_t)(const void * a, const void * b); -typedef struct { - lv_rb_node_t * root; - lv_rb_compare_t compare; - size_t size; -} lv_rb_t; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h new file mode 100644 index 000000000..327b7b0be --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h @@ -0,0 +1,54 @@ +/** + * @file lv_rb_private.h + * + */ + +#ifndef LV_RB_PRIVATE_H +#define LV_RB_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_rb.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_rb_node_t { + struct lv_rb_node_t * parent; + struct lv_rb_node_t * left; + struct lv_rb_node_t * right; + lv_rb_color_t color; + void * data; +}; + +struct lv_rb_t { + lv_rb_node_t * root; + lv_rb_compare_t compare; + size_t size; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RB_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c index e7278434e..d137d67eb 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_style.h" +#include "lv_style_private.h" #include "../core/lv_global.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" @@ -16,8 +16,8 @@ /********************* * DEFINES *********************/ -#define _lv_style_custom_prop_flag_lookup_table_size LV_GLOBAL_DEFAULT()->style_custom_table_size -#define _lv_style_custom_prop_flag_lookup_table LV_GLOBAL_DEFAULT()->style_custom_prop_flag_lookup_table +#define lv_style_custom_prop_flag_lookup_table_size LV_GLOBAL_DEFAULT()->style_custom_table_size +#define lv_style_custom_prop_flag_lookup_table LV_GLOBAL_DEFAULT()->style_custom_prop_flag_lookup_table #define last_custom_prop_id LV_GLOBAL_DEFAULT()->style_last_custom_prop_id /********************** @@ -34,7 +34,7 @@ const lv_style_prop_t lv_style_const_prop_id_inv = LV_STYLE_PROP_INV; -const uint8_t _lv_style_builtin_prop_flag_lookup_table[_LV_STYLE_NUM_BUILT_IN_PROPS] = { +const uint8_t lv_style_builtin_prop_flag_lookup_table[LV_STYLE_NUM_BUILT_IN_PROPS] = { [LV_STYLE_WIDTH] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, [LV_STYLE_MIN_WIDTH] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, [LV_STYLE_MAX_WIDTH] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, @@ -200,9 +200,9 @@ void lv_style_reset(lv_style_t * style) lv_style_prop_t lv_style_register_prop(uint8_t flag) { - if(_lv_style_custom_prop_flag_lookup_table == NULL) { - _lv_style_custom_prop_flag_lookup_table_size = 0; - last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP; + if(lv_style_custom_prop_flag_lookup_table == NULL) { + lv_style_custom_prop_flag_lookup_table_size = 0; + last_custom_prop_id = (uint16_t)LV_STYLE_LAST_BUILT_IN_PROP; } // if((last_custom_prop_id + 1) != 0) { @@ -213,30 +213,30 @@ lv_style_prop_t lv_style_register_prop(uint8_t flag) /* * Allocate the lookup table if it's not yet available. */ - size_t required_size = (last_custom_prop_id + 1 - _LV_STYLE_LAST_BUILT_IN_PROP); - if(_lv_style_custom_prop_flag_lookup_table_size < required_size) { + size_t required_size = (last_custom_prop_id + 1 - LV_STYLE_LAST_BUILT_IN_PROP); + if(lv_style_custom_prop_flag_lookup_table_size < required_size) { /* Round required_size up to the nearest 32-byte value */ required_size = (required_size + 31) & ~31; LV_ASSERT_MSG(required_size > 0, "required size has become 0?"); - uint8_t * old_p = _lv_style_custom_prop_flag_lookup_table; + uint8_t * old_p = lv_style_custom_prop_flag_lookup_table; uint8_t * new_p = lv_realloc(old_p, required_size * sizeof(uint8_t)); if(new_p == NULL) { LV_LOG_ERROR("Unable to allocate space for custom property lookup table"); return LV_STYLE_PROP_INV; } - _lv_style_custom_prop_flag_lookup_table = new_p; - _lv_style_custom_prop_flag_lookup_table_size = required_size; + lv_style_custom_prop_flag_lookup_table = new_p; + lv_style_custom_prop_flag_lookup_table_size = required_size; } last_custom_prop_id++; /* This should never happen - we should bail out above */ - LV_ASSERT_NULL(_lv_style_custom_prop_flag_lookup_table); - _lv_style_custom_prop_flag_lookup_table[last_custom_prop_id - _LV_STYLE_NUM_BUILT_IN_PROPS] = flag; + LV_ASSERT_NULL(lv_style_custom_prop_flag_lookup_table); + lv_style_custom_prop_flag_lookup_table[last_custom_prop_id - LV_STYLE_NUM_BUILT_IN_PROPS] = flag; return last_custom_prop_id; } lv_style_prop_t lv_style_get_num_custom_props(void) { - return last_custom_prop_id - _LV_STYLE_LAST_BUILT_IN_PROP; + return last_custom_prop_id - LV_STYLE_LAST_BUILT_IN_PROP; } bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop) @@ -329,7 +329,7 @@ void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_ props[style->prop_cnt - 1] = prop; values[style->prop_cnt - 1] = value; - uint32_t group = _lv_style_get_prop_group(prop); + uint32_t group = lv_style_get_prop_group(prop); style->has_group |= (uint32_t)1 << group; } @@ -424,16 +424,16 @@ bool lv_style_is_empty(const lv_style_t * style) return style->prop_cnt == 0; } -uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop) +uint8_t lv_style_prop_lookup_flags(lv_style_prop_t prop) { if(prop == LV_STYLE_PROP_ANY) return LV_STYLE_PROP_FLAG_ALL; /*Any prop can have any flags*/ if(prop == LV_STYLE_PROP_INV) return 0; - if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS) - return _lv_style_builtin_prop_flag_lookup_table[prop]; - prop -= _LV_STYLE_NUM_BUILT_IN_PROPS; - if(_lv_style_custom_prop_flag_lookup_table != NULL && prop < _lv_style_custom_prop_flag_lookup_table_size) - return _lv_style_custom_prop_flag_lookup_table[prop]; + if(prop < LV_STYLE_NUM_BUILT_IN_PROPS) + return lv_style_builtin_prop_flag_lookup_table[prop]; + prop -= LV_STYLE_NUM_BUILT_IN_PROPS; + if(lv_style_custom_prop_flag_lookup_table != NULL && prop < lv_style_custom_prop_flag_lookup_table_size) + return lv_style_custom_prop_flag_lookup_table[prop]; return 0; } diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.h index 5c69e5989..dcce7dcd6 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_style.h * */ @@ -13,8 +13,6 @@ extern "C" { /********************* * INCLUDES *********************/ -#include -#include #include "../font/lv_font.h" #include "lv_color.h" #include "lv_area.h" @@ -31,24 +29,22 @@ extern "C" { #define LV_STYLE_SENTINEL_VALUE 0xAABBCCDD -/** +/* * Flags for style behavior - * - * The rest of the flags will have _FLAG added to their name in v9. */ -#define LV_STYLE_PROP_FLAG_NONE (0) -#define LV_STYLE_PROP_FLAG_INHERITABLE (1 << 0) /*Inherited*/ -#define LV_STYLE_PROP_FLAG_EXT_DRAW_UPDATE (1 << 1) /*Requires ext. draw size update when changed*/ -#define LV_STYLE_PROP_FLAG_LAYOUT_UPDATE (1 << 2) /*Requires layout update when changed*/ -#define LV_STYLE_PROP_FLAG_PARENT_LAYOUT_UPDATE (1 << 3) /*Requires layout update on parent when changed*/ -#define LV_STYLE_PROP_FLAG_LAYER_UPDATE (1 << 4) /*Affects layer handling*/ -#define LV_STYLE_PROP_FLAG_TRANSFORM (1 << 5) /*Affects the object's transformation*/ -#define LV_STYLE_PROP_FLAG_ALL (0x3F) /*Indicating all flags*/ +#define LV_STYLE_PROP_FLAG_NONE (0) /**< No special behavior */ +#define LV_STYLE_PROP_FLAG_INHERITABLE (1 << 0) /**< Inherited */ +#define LV_STYLE_PROP_FLAG_EXT_DRAW_UPDATE (1 << 1) /**< Requires ext. draw size update when changed */ +#define LV_STYLE_PROP_FLAG_LAYOUT_UPDATE (1 << 2) /**< Requires layout update when changed */ +#define LV_STYLE_PROP_FLAG_PARENT_LAYOUT_UPDATE (1 << 3) /**< Requires layout update on parent when changed */ +#define LV_STYLE_PROP_FLAG_LAYER_UPDATE (1 << 4) /**< Affects layer handling */ +#define LV_STYLE_PROP_FLAG_TRANSFORM (1 << 5) /**< Affects the object's transformation */ +#define LV_STYLE_PROP_FLAG_ALL (0x3F) /**< Indicating all flags */ -/** +/* * Other constants */ -#define LV_SCALE_NONE 256 /*Value for not zooming the image*/ +#define LV_SCALE_NONE 256 /**< Value for not zooming the image */ LV_EXPORT_CONST_INT(LV_SCALE_NONE); // *INDENT-OFF* @@ -56,63 +52,51 @@ LV_EXPORT_CONST_INT(LV_SCALE_NONE); #define LV_STYLE_CONST_INIT(var_name, prop_array) \ const lv_style_t var_name = { \ .sentinel = LV_STYLE_SENTINEL_VALUE, \ - .values_and_props = (void*)prop_array, \ + .values_and_props = (void*)prop_array, \ .has_group = 0xFFFFFFFF, \ - .prop_cnt = 255 \ + .prop_cnt = 255 \ } #else #define LV_STYLE_CONST_INIT(var_name, prop_array) \ const lv_style_t var_name = { \ - .values_and_props = prop_array, \ + .values_and_props = prop_array, \ .has_group = 0xFFFFFFFF, \ - .prop_cnt = 255, \ + .prop_cnt = 255, \ } #endif // *INDENT-ON* -#define LV_STYLE_CONST_PROPS_END { .prop_ptr = NULL, .value = { .num = 0 } } +#define LV_STYLE_CONST_PROPS_END { .prop = LV_STYLE_PROP_INV, .value = { .num = 0 } } /********************** * TYPEDEFS **********************/ /** - * Possible options how to blend opaque drawings + * Possible options for blending opaque drawings */ -enum _lv_blend_mode_t { +typedef enum { LV_BLEND_MODE_NORMAL, /**< Simply mix according to the opacity value*/ LV_BLEND_MODE_ADDITIVE, /**< Add the respective color channels*/ LV_BLEND_MODE_SUBTRACTIVE,/**< Subtract the foreground from the background*/ LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/ -}; - -#ifdef DOXYGEN -typedef _lv_blend_mode_t lv_blend_mode_t; -#else -typedef uint8_t lv_blend_mode_t; -#endif /*DOXYGEN*/ +} lv_blend_mode_t; /** * Some options to apply decorations on texts. * 'OR'ed values can be used. */ -enum _lv_text_decor_t { +typedef enum { LV_TEXT_DECOR_NONE = 0x00, LV_TEXT_DECOR_UNDERLINE = 0x01, LV_TEXT_DECOR_STRIKETHROUGH = 0x02, -}; - -#ifdef DOXYGEN -typedef _lv_text_decor_t lv_text_decor_t; -#else -typedef uint8_t lv_text_decor_t; -#endif /*DOXYGEN*/ +} lv_text_decor_t; /** * Selects on which sides border should be drawn * 'OR'ed values can be used. */ -enum _lv_border_side_t { +typedef enum { LV_BORDER_SIDE_NONE = 0x00, LV_BORDER_SIDE_BOTTOM = 0x01, LV_BORDER_SIDE_TOP = 0x02, @@ -120,28 +104,28 @@ enum _lv_border_side_t { LV_BORDER_SIDE_RIGHT = 0x08, LV_BORDER_SIDE_FULL = 0x0F, LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/ -}; - -#ifdef DOXYGEN -typedef _lv_border_side_t lv_border_side_t; -#else -typedef uint8_t lv_border_side_t; -#endif /*DOXYGEN*/ +} lv_border_side_t; /** * The direction of the gradient. */ -enum _lv_grad_dir_t { - LV_GRAD_DIR_NONE, /**< No gradient (the `grad_color` property is ignored)*/ - LV_GRAD_DIR_VER, /**< Vertical (top to bottom) gradient*/ - LV_GRAD_DIR_HOR, /**< Horizontal (left to right) gradient*/ -}; +typedef enum { + LV_GRAD_DIR_NONE, /**< No gradient (the `grad_color` property is ignored)*/ + LV_GRAD_DIR_VER, /**< Simple vertical (top to bottom) gradient*/ + LV_GRAD_DIR_HOR, /**< Simple horizontal (left to right) gradient*/ + LV_GRAD_DIR_LINEAR, /**< Linear gradient defined by start and end points. Can be at any angle.*/ + LV_GRAD_DIR_RADIAL, /**< Radial gradient defined by start and end circles*/ + LV_GRAD_DIR_CONICAL, /**< Conical gradient defined by center point, start and end angles*/ +} lv_grad_dir_t; -#ifdef DOXYGEN -typedef _lv_grad_dir_t lv_grad_dir_t; -#else -typedef uint8_t lv_grad_dir_t; -#endif /*DOXYGEN*/ +/** + * Gradient behavior outside the defined range. +*/ +typedef enum { + LV_GRAD_EXTEND_PAD, /**< Repeat the same color*/ + LV_GRAD_EXTEND_REPEAT, /**< Repeat the pattern*/ + LV_GRAD_EXTEND_REFLECT, /**< Repeat the pattern mirrored*/ +} lv_grad_extend_t; /** A gradient stop definition. * This matches a color and a position in a virtual 0-255 scale. @@ -154,10 +138,37 @@ typedef struct { /** A descriptor of a gradient. */ typedef struct { - lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ - uint8_t stops_count; /**< The number of used stops in the array */ - lv_grad_dir_t dir : 3; /**< The gradient direction. - * Any of LV_GRAD_DIR_HOR, LV_GRAD_DIR_VER, LV_GRAD_DIR_NONE */ + lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ + uint8_t stops_count; /**< The number of used stops in the array */ + lv_grad_dir_t dir : 3; /**< The gradient direction. + * Any of LV_GRAD_DIR_NONE, LV_GRAD_DIR_VER, LV_GRAD_DIR_HOR, + * LV_GRAD_TYPE_LINEAR, LV_GRAD_TYPE_RADIAL, LV_GRAD_TYPE_CONICAL */ + lv_grad_extend_t extend : 2; /**< Behaviour outside the defined range. + * LV_GRAD_EXTEND_NONE, LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT, LV_GRAD_EXTEND_REFLECT */ +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + union { + /*Linear gradient parameters*/ + struct { + lv_point_t start; /**< Linear gradient vector start point */ + lv_point_t end; /**< Linear gradient vector end point */ + } linear; + /*Radial gradient parameters*/ + struct { + lv_point_t focal; /**< Center of the focal (starting) circle in local coordinates */ + /* (can be the same as the ending circle to create concentric circles) */ + lv_point_t focal_extent; /**< Point on the circle (can be the same as the center) */ + lv_point_t end; /**< Center of the ending circle in local coordinates */ + lv_point_t end_extent; /**< Point on the circle determining the radius of the gradient */ + } radial; + /*Conical gradient parameters*/ + struct { + lv_point_t center; /**< Conical gradient center point */ + int16_t start_angle; /**< Start angle 0..3600 */ + int16_t end_angle; /**< End angle 0..3600 */ + } conical; + } params; + void * state; +#endif } lv_grad_dsc_t; /** @@ -174,7 +185,7 @@ typedef union { * * Props are split into groups of 16. When adding a new prop to a group, ensure it does not overflow into the next one. */ -enum _lv_style_prop_t { +enum { LV_STYLE_PROP_INV = 0, /*Group 0*/ @@ -301,15 +312,12 @@ enum _lv_style_prop_t { LV_STYLE_BITMAP_MASK_SRC = 115, LV_STYLE_ROTARY_SENSITIVITY = 116, -#if LV_USE_FLEX LV_STYLE_FLEX_FLOW = 125, LV_STYLE_FLEX_MAIN_PLACE = 126, LV_STYLE_FLEX_CROSS_PLACE = 127, LV_STYLE_FLEX_TRACK_PLACE = 128, LV_STYLE_FLEX_GROW = 129, -#endif -#if LV_USE_GRID LV_STYLE_GRID_COLUMN_ALIGN = 130, LV_STYLE_GRID_ROW_ALIGN = 131, LV_STYLE_GRID_ROW_DSC_ARRAY = 132, @@ -320,32 +328,19 @@ enum _lv_style_prop_t { LV_STYLE_GRID_CELL_ROW_POS = 137, LV_STYLE_GRID_CELL_ROW_SPAN = 138, LV_STYLE_GRID_CELL_Y_ALIGN = 139, -#endif - _LV_STYLE_LAST_BUILT_IN_PROP = 140, + LV_STYLE_LAST_BUILT_IN_PROP = 140, - _LV_STYLE_NUM_BUILT_IN_PROPS = _LV_STYLE_LAST_BUILT_IN_PROP + 1, + LV_STYLE_NUM_BUILT_IN_PROPS = LV_STYLE_LAST_BUILT_IN_PROP + 1, LV_STYLE_PROP_ANY = 0xFF, - _LV_STYLE_PROP_CONST = 0xFF /* magic value for const styles */ + LV_STYLE_PROP_CONST = 0xFF /* magic value for const styles */ }; -#ifdef DOXYGEN -typedef _lv_style_prop_t lv_style_prop_t; -#else -typedef uint8_t lv_style_prop_t; -#endif /*DOXYGEN*/ - -enum _lv_style_res_t { +typedef enum { LV_STYLE_RES_NOT_FOUND, LV_STYLE_RES_FOUND, -}; - -#ifdef DOXYGEN -typedef _lv_style_res_t lv_style_res_t; -#else -typedef uint8_t lv_style_res_t; -#endif /*DOXYGEN*/ +} lv_style_res_t; /** * Descriptor for style transitions @@ -353,7 +348,7 @@ typedef uint8_t lv_style_res_t; typedef struct { const lv_style_prop_t * props; /**< An array with the properties to animate.*/ void * user_data; /**< A custom user data that will be passed to the animation's user_data */ - lv_anim_path_cb_t path_xcb; /**< A path for the animation.*/ + lv_anim_path_cb_t path_xcb; /**< A path for the animation.*/ uint32_t time; /**< Duration of the transition in [ms]*/ uint32_t delay; /**< Delay before the transition in [ms]*/ } lv_style_transition_dsc_t; @@ -362,7 +357,7 @@ typedef struct { * Descriptor of a constant style property. */ typedef struct { - const lv_style_prop_t * prop_ptr; + lv_style_prop_t prop; lv_style_value_t value; } lv_style_const_prop_t; @@ -414,7 +409,9 @@ static inline bool lv_style_is_const(const lv_style_t * style) /** * Register a new style property for custom usage * @return a new property ID, or LV_STYLE_PROP_INV if there are no more available. - * @example + * + * Example: + * @code * lv_style_prop_t MY_PROP; * static inline void lv_style_set_my_prop(lv_style_t * style, lv_color_t value) { * lv_style_value_t v = {.color = value}; lv_style_set_prop(style, MY_PROP, v); } @@ -423,6 +420,7 @@ static inline bool lv_style_is_const(const lv_style_t * style) * MY_PROP = lv_style_register_prop(); * ... * lv_style_set_my_prop(&style1, lv_palette_main(LV_PALETTE_RED)); + * @endcode */ lv_style_prop_t lv_style_register_prop(uint8_t flag); @@ -468,10 +466,13 @@ lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, * @param time duration of the transition in [ms] * @param delay delay before the transition in [ms] * @param user_data any custom data that will be saved in the transition animation and will be available when `path_cb` is called - * @example + * + * Example: + * @code * const static lv_style_prop_t trans_props[] = { LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, 0 }; - * static lv_style_transition_dsc_t trans1; - * lv_style_transition_dsc_init(&trans1, trans_props, NULL, 300, 0, NULL); + * static lv_style_transition_dsc_t trans1; + * lv_style_transition_dsc_init(&trans1, trans_props, NULL, 300, 0, NULL); + * @endcode */ void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style_prop_t props[], lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void * user_data); @@ -499,8 +500,8 @@ static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, if(lv_style_is_const(style)) { lv_style_const_prop_t * props = (lv_style_const_prop_t *)style->values_and_props; uint32_t i; - for(i = 0; props[i].prop_ptr; i++) { - if(*props[i].prop_ptr == prop) { + for(i = 0; props[i].prop != LV_STYLE_PROP_INV; i++) { + if(props[i].prop == prop) { *value = props[i].value; return LV_STYLE_RES_FOUND; } @@ -533,7 +534,7 @@ bool lv_style_is_empty(const lv_style_t * style); * @param prop a style property * @return the group [0..30] 30 means all the custom properties with index > 120 */ -static inline uint32_t _lv_style_get_prop_group(lv_style_prop_t prop) +static inline uint32_t lv_style_get_prop_group(lv_style_prop_t prop) { uint32_t group = prop >> 2; if(group > 30) group = 31; /*The MSB marks all the custom properties*/ @@ -547,7 +548,7 @@ static inline uint32_t _lv_style_get_prop_group(lv_style_prop_t prop) * @param prop a style property * @return the flags of the property */ -uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop); +uint8_t lv_style_prop_lookup_flags(lv_style_prop_t prop); #include "lv_style_gen.h" @@ -601,7 +602,7 @@ static inline void lv_style_set_transform_scale(lv_style_t * style, int32_t valu */ static inline bool lv_style_prop_has_flag(lv_style_prop_t prop, uint8_t flag) { - return _lv_style_prop_lookup_flags(prop) & flag; + return lv_style_prop_lookup_flags(prop) & flag; } /************************* diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.c index 297087534..233cf7b94 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.c @@ -18,8 +18,6 @@ void lv_style_set_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_WIDTH = LV_STYLE_WIDTH; - void lv_style_set_min_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -28,8 +26,6 @@ void lv_style_set_min_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MIN_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_MIN_WIDTH = LV_STYLE_MIN_WIDTH; - void lv_style_set_max_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -38,8 +34,6 @@ void lv_style_set_max_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MAX_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_MAX_WIDTH = LV_STYLE_MAX_WIDTH; - void lv_style_set_height(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -48,8 +42,6 @@ void lv_style_set_height(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_HEIGHT, v); } -const lv_style_prop_t _lv_style_const_prop_id_HEIGHT = LV_STYLE_HEIGHT; - void lv_style_set_min_height(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -58,8 +50,6 @@ void lv_style_set_min_height(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MIN_HEIGHT, v); } -const lv_style_prop_t _lv_style_const_prop_id_MIN_HEIGHT = LV_STYLE_MIN_HEIGHT; - void lv_style_set_max_height(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -68,8 +58,6 @@ void lv_style_set_max_height(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MAX_HEIGHT, v); } -const lv_style_prop_t _lv_style_const_prop_id_MAX_HEIGHT = LV_STYLE_MAX_HEIGHT; - void lv_style_set_length(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -78,8 +66,6 @@ void lv_style_set_length(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_LENGTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_LENGTH = LV_STYLE_LENGTH; - void lv_style_set_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -88,8 +74,6 @@ void lv_style_set_x(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_X, v); } -const lv_style_prop_t _lv_style_const_prop_id_X = LV_STYLE_X; - void lv_style_set_y(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -98,8 +82,6 @@ void lv_style_set_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_Y, v); } -const lv_style_prop_t _lv_style_const_prop_id_Y = LV_STYLE_Y; - void lv_style_set_align(lv_style_t * style, lv_align_t value) { lv_style_value_t v = { @@ -108,8 +90,6 @@ void lv_style_set_align(lv_style_t * style, lv_align_t value) lv_style_set_prop(style, LV_STYLE_ALIGN, v); } -const lv_style_prop_t _lv_style_const_prop_id_ALIGN = LV_STYLE_ALIGN; - void lv_style_set_transform_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -118,8 +98,6 @@ void lv_style_set_transform_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_WIDTH = LV_STYLE_TRANSFORM_WIDTH; - void lv_style_set_transform_height(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -128,8 +106,6 @@ void lv_style_set_transform_height(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_HEIGHT, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_HEIGHT = LV_STYLE_TRANSFORM_HEIGHT; - void lv_style_set_translate_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -138,8 +114,6 @@ void lv_style_set_translate_x(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSLATE_X, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSLATE_X = LV_STYLE_TRANSLATE_X; - void lv_style_set_translate_y(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -148,8 +122,6 @@ void lv_style_set_translate_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSLATE_Y, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSLATE_Y = LV_STYLE_TRANSLATE_Y; - void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -158,8 +130,6 @@ void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_SCALE_X, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SCALE_X = LV_STYLE_TRANSFORM_SCALE_X; - void lv_style_set_transform_scale_y(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -168,8 +138,6 @@ void lv_style_set_transform_scale_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_SCALE_Y, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SCALE_Y = LV_STYLE_TRANSFORM_SCALE_Y; - void lv_style_set_transform_rotation(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -178,8 +146,6 @@ void lv_style_set_transform_rotation(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_ROTATION, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_ROTATION = LV_STYLE_TRANSFORM_ROTATION; - void lv_style_set_transform_pivot_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -188,8 +154,6 @@ void lv_style_set_transform_pivot_x(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_PIVOT_X, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_PIVOT_X = LV_STYLE_TRANSFORM_PIVOT_X; - void lv_style_set_transform_pivot_y(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -198,8 +162,6 @@ void lv_style_set_transform_pivot_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_PIVOT_Y, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_PIVOT_Y = LV_STYLE_TRANSFORM_PIVOT_Y; - void lv_style_set_transform_skew_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -208,8 +170,6 @@ void lv_style_set_transform_skew_x(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_SKEW_X, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SKEW_X = LV_STYLE_TRANSFORM_SKEW_X; - void lv_style_set_transform_skew_y(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -218,8 +178,6 @@ void lv_style_set_transform_skew_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSFORM_SKEW_Y, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SKEW_Y = LV_STYLE_TRANSFORM_SKEW_Y; - void lv_style_set_pad_top(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -228,8 +186,6 @@ void lv_style_set_pad_top(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_TOP, v); } -const lv_style_prop_t _lv_style_const_prop_id_PAD_TOP = LV_STYLE_PAD_TOP; - void lv_style_set_pad_bottom(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -238,8 +194,6 @@ void lv_style_set_pad_bottom(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_BOTTOM, v); } -const lv_style_prop_t _lv_style_const_prop_id_PAD_BOTTOM = LV_STYLE_PAD_BOTTOM; - void lv_style_set_pad_left(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -248,8 +202,6 @@ void lv_style_set_pad_left(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_LEFT, v); } -const lv_style_prop_t _lv_style_const_prop_id_PAD_LEFT = LV_STYLE_PAD_LEFT; - void lv_style_set_pad_right(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -258,8 +210,6 @@ void lv_style_set_pad_right(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_RIGHT, v); } -const lv_style_prop_t _lv_style_const_prop_id_PAD_RIGHT = LV_STYLE_PAD_RIGHT; - void lv_style_set_pad_row(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -268,8 +218,6 @@ void lv_style_set_pad_row(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_ROW, v); } -const lv_style_prop_t _lv_style_const_prop_id_PAD_ROW = LV_STYLE_PAD_ROW; - void lv_style_set_pad_column(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -278,8 +226,6 @@ void lv_style_set_pad_column(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_COLUMN, v); } -const lv_style_prop_t _lv_style_const_prop_id_PAD_COLUMN = LV_STYLE_PAD_COLUMN; - void lv_style_set_margin_top(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -288,8 +234,6 @@ void lv_style_set_margin_top(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MARGIN_TOP, v); } -const lv_style_prop_t _lv_style_const_prop_id_MARGIN_TOP = LV_STYLE_MARGIN_TOP; - void lv_style_set_margin_bottom(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -298,8 +242,6 @@ void lv_style_set_margin_bottom(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MARGIN_BOTTOM, v); } -const lv_style_prop_t _lv_style_const_prop_id_MARGIN_BOTTOM = LV_STYLE_MARGIN_BOTTOM; - void lv_style_set_margin_left(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -308,8 +250,6 @@ void lv_style_set_margin_left(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MARGIN_LEFT, v); } -const lv_style_prop_t _lv_style_const_prop_id_MARGIN_LEFT = LV_STYLE_MARGIN_LEFT; - void lv_style_set_margin_right(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -318,8 +258,6 @@ void lv_style_set_margin_right(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_MARGIN_RIGHT, v); } -const lv_style_prop_t _lv_style_const_prop_id_MARGIN_RIGHT = LV_STYLE_MARGIN_RIGHT; - void lv_style_set_bg_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -328,8 +266,6 @@ void lv_style_set_bg_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_BG_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_COLOR = LV_STYLE_BG_COLOR; - void lv_style_set_bg_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -338,8 +274,6 @@ void lv_style_set_bg_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_BG_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_OPA = LV_STYLE_BG_OPA; - void lv_style_set_bg_grad_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -348,8 +282,6 @@ void lv_style_set_bg_grad_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_BG_GRAD_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_COLOR = LV_STYLE_BG_GRAD_COLOR; - void lv_style_set_bg_grad_dir(lv_style_t * style, lv_grad_dir_t value) { lv_style_value_t v = { @@ -358,8 +290,6 @@ void lv_style_set_bg_grad_dir(lv_style_t * style, lv_grad_dir_t value) lv_style_set_prop(style, LV_STYLE_BG_GRAD_DIR, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_DIR = LV_STYLE_BG_GRAD_DIR; - void lv_style_set_bg_main_stop(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -368,8 +298,6 @@ void lv_style_set_bg_main_stop(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_BG_MAIN_STOP, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_MAIN_STOP = LV_STYLE_BG_MAIN_STOP; - void lv_style_set_bg_grad_stop(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -378,8 +306,6 @@ void lv_style_set_bg_grad_stop(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_BG_GRAD_STOP, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_STOP = LV_STYLE_BG_GRAD_STOP; - void lv_style_set_bg_main_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -388,8 +314,6 @@ void lv_style_set_bg_main_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_BG_MAIN_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_MAIN_OPA = LV_STYLE_BG_MAIN_OPA; - void lv_style_set_bg_grad_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -398,8 +322,6 @@ void lv_style_set_bg_grad_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_BG_GRAD_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_OPA = LV_STYLE_BG_GRAD_OPA; - void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value) { lv_style_value_t v = { @@ -408,8 +330,6 @@ void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value) lv_style_set_prop(style, LV_STYLE_BG_GRAD, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD = LV_STYLE_BG_GRAD; - void lv_style_set_bg_image_src(lv_style_t * style, const void * value) { lv_style_value_t v = { @@ -418,8 +338,6 @@ void lv_style_set_bg_image_src(lv_style_t * style, const void * value) lv_style_set_prop(style, LV_STYLE_BG_IMAGE_SRC, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_SRC = LV_STYLE_BG_IMAGE_SRC; - void lv_style_set_bg_image_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -428,8 +346,6 @@ void lv_style_set_bg_image_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_BG_IMAGE_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_OPA = LV_STYLE_BG_IMAGE_OPA; - void lv_style_set_bg_image_recolor(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -438,8 +354,6 @@ void lv_style_set_bg_image_recolor(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_BG_IMAGE_RECOLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_RECOLOR = LV_STYLE_BG_IMAGE_RECOLOR; - void lv_style_set_bg_image_recolor_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -448,8 +362,6 @@ void lv_style_set_bg_image_recolor_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_BG_IMAGE_RECOLOR_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_RECOLOR_OPA = LV_STYLE_BG_IMAGE_RECOLOR_OPA; - void lv_style_set_bg_image_tiled(lv_style_t * style, bool value) { lv_style_value_t v = { @@ -458,8 +370,6 @@ void lv_style_set_bg_image_tiled(lv_style_t * style, bool value) lv_style_set_prop(style, LV_STYLE_BG_IMAGE_TILED, v); } -const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_TILED = LV_STYLE_BG_IMAGE_TILED; - void lv_style_set_border_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -468,8 +378,6 @@ void lv_style_set_border_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_BORDER_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_BORDER_COLOR = LV_STYLE_BORDER_COLOR; - void lv_style_set_border_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -478,8 +386,6 @@ void lv_style_set_border_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_BORDER_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_BORDER_OPA = LV_STYLE_BORDER_OPA; - void lv_style_set_border_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -488,8 +394,6 @@ void lv_style_set_border_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_BORDER_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_BORDER_WIDTH = LV_STYLE_BORDER_WIDTH; - void lv_style_set_border_side(lv_style_t * style, lv_border_side_t value) { lv_style_value_t v = { @@ -498,8 +402,6 @@ void lv_style_set_border_side(lv_style_t * style, lv_border_side_t value) lv_style_set_prop(style, LV_STYLE_BORDER_SIDE, v); } -const lv_style_prop_t _lv_style_const_prop_id_BORDER_SIDE = LV_STYLE_BORDER_SIDE; - void lv_style_set_border_post(lv_style_t * style, bool value) { lv_style_value_t v = { @@ -508,8 +410,6 @@ void lv_style_set_border_post(lv_style_t * style, bool value) lv_style_set_prop(style, LV_STYLE_BORDER_POST, v); } -const lv_style_prop_t _lv_style_const_prop_id_BORDER_POST = LV_STYLE_BORDER_POST; - void lv_style_set_outline_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -518,8 +418,6 @@ void lv_style_set_outline_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_OUTLINE_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_WIDTH = LV_STYLE_OUTLINE_WIDTH; - void lv_style_set_outline_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -528,8 +426,6 @@ void lv_style_set_outline_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_OUTLINE_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_COLOR = LV_STYLE_OUTLINE_COLOR; - void lv_style_set_outline_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -538,8 +434,6 @@ void lv_style_set_outline_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_OUTLINE_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_OPA = LV_STYLE_OUTLINE_OPA; - void lv_style_set_outline_pad(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -548,8 +442,6 @@ void lv_style_set_outline_pad(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_OUTLINE_PAD, v); } -const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_PAD = LV_STYLE_OUTLINE_PAD; - void lv_style_set_shadow_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -558,8 +450,6 @@ void lv_style_set_shadow_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_SHADOW_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_SHADOW_WIDTH = LV_STYLE_SHADOW_WIDTH; - void lv_style_set_shadow_offset_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -568,8 +458,6 @@ void lv_style_set_shadow_offset_x(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_SHADOW_OFFSET_X, v); } -const lv_style_prop_t _lv_style_const_prop_id_SHADOW_OFFSET_X = LV_STYLE_SHADOW_OFFSET_X; - void lv_style_set_shadow_offset_y(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -578,8 +466,6 @@ void lv_style_set_shadow_offset_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_SHADOW_OFFSET_Y, v); } -const lv_style_prop_t _lv_style_const_prop_id_SHADOW_OFFSET_Y = LV_STYLE_SHADOW_OFFSET_Y; - void lv_style_set_shadow_spread(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -588,8 +474,6 @@ void lv_style_set_shadow_spread(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_SHADOW_SPREAD, v); } -const lv_style_prop_t _lv_style_const_prop_id_SHADOW_SPREAD = LV_STYLE_SHADOW_SPREAD; - void lv_style_set_shadow_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -598,8 +482,6 @@ void lv_style_set_shadow_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_SHADOW_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_SHADOW_COLOR = LV_STYLE_SHADOW_COLOR; - void lv_style_set_shadow_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -608,8 +490,6 @@ void lv_style_set_shadow_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_SHADOW_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_SHADOW_OPA = LV_STYLE_SHADOW_OPA; - void lv_style_set_image_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -618,8 +498,6 @@ void lv_style_set_image_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_IMAGE_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_IMAGE_OPA = LV_STYLE_IMAGE_OPA; - void lv_style_set_image_recolor(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -628,8 +506,6 @@ void lv_style_set_image_recolor(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_IMAGE_RECOLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_IMAGE_RECOLOR = LV_STYLE_IMAGE_RECOLOR; - void lv_style_set_image_recolor_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -638,8 +514,6 @@ void lv_style_set_image_recolor_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_IMAGE_RECOLOR_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_IMAGE_RECOLOR_OPA = LV_STYLE_IMAGE_RECOLOR_OPA; - void lv_style_set_line_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -648,8 +522,6 @@ void lv_style_set_line_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_LINE_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_LINE_WIDTH = LV_STYLE_LINE_WIDTH; - void lv_style_set_line_dash_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -658,8 +530,6 @@ void lv_style_set_line_dash_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_LINE_DASH_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_LINE_DASH_WIDTH = LV_STYLE_LINE_DASH_WIDTH; - void lv_style_set_line_dash_gap(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -668,8 +538,6 @@ void lv_style_set_line_dash_gap(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_LINE_DASH_GAP, v); } -const lv_style_prop_t _lv_style_const_prop_id_LINE_DASH_GAP = LV_STYLE_LINE_DASH_GAP; - void lv_style_set_line_rounded(lv_style_t * style, bool value) { lv_style_value_t v = { @@ -678,8 +546,6 @@ void lv_style_set_line_rounded(lv_style_t * style, bool value) lv_style_set_prop(style, LV_STYLE_LINE_ROUNDED, v); } -const lv_style_prop_t _lv_style_const_prop_id_LINE_ROUNDED = LV_STYLE_LINE_ROUNDED; - void lv_style_set_line_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -688,8 +554,6 @@ void lv_style_set_line_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_LINE_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_LINE_COLOR = LV_STYLE_LINE_COLOR; - void lv_style_set_line_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -698,8 +562,6 @@ void lv_style_set_line_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_LINE_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_LINE_OPA = LV_STYLE_LINE_OPA; - void lv_style_set_arc_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -708,8 +570,6 @@ void lv_style_set_arc_width(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_ARC_WIDTH, v); } -const lv_style_prop_t _lv_style_const_prop_id_ARC_WIDTH = LV_STYLE_ARC_WIDTH; - void lv_style_set_arc_rounded(lv_style_t * style, bool value) { lv_style_value_t v = { @@ -718,8 +578,6 @@ void lv_style_set_arc_rounded(lv_style_t * style, bool value) lv_style_set_prop(style, LV_STYLE_ARC_ROUNDED, v); } -const lv_style_prop_t _lv_style_const_prop_id_ARC_ROUNDED = LV_STYLE_ARC_ROUNDED; - void lv_style_set_arc_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -728,8 +586,6 @@ void lv_style_set_arc_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_ARC_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_ARC_COLOR = LV_STYLE_ARC_COLOR; - void lv_style_set_arc_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -738,8 +594,6 @@ void lv_style_set_arc_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_ARC_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_ARC_OPA = LV_STYLE_ARC_OPA; - void lv_style_set_arc_image_src(lv_style_t * style, const void * value) { lv_style_value_t v = { @@ -748,8 +602,6 @@ void lv_style_set_arc_image_src(lv_style_t * style, const void * value) lv_style_set_prop(style, LV_STYLE_ARC_IMAGE_SRC, v); } -const lv_style_prop_t _lv_style_const_prop_id_ARC_IMAGE_SRC = LV_STYLE_ARC_IMAGE_SRC; - void lv_style_set_text_color(lv_style_t * style, lv_color_t value) { lv_style_value_t v = { @@ -758,8 +610,6 @@ void lv_style_set_text_color(lv_style_t * style, lv_color_t value) lv_style_set_prop(style, LV_STYLE_TEXT_COLOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_COLOR = LV_STYLE_TEXT_COLOR; - void lv_style_set_text_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -768,8 +618,6 @@ void lv_style_set_text_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_TEXT_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_OPA = LV_STYLE_TEXT_OPA; - void lv_style_set_text_font(lv_style_t * style, const lv_font_t * value) { lv_style_value_t v = { @@ -778,8 +626,6 @@ void lv_style_set_text_font(lv_style_t * style, const lv_font_t * value) lv_style_set_prop(style, LV_STYLE_TEXT_FONT, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_FONT = LV_STYLE_TEXT_FONT; - void lv_style_set_text_letter_space(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -788,8 +634,6 @@ void lv_style_set_text_letter_space(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TEXT_LETTER_SPACE, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_LETTER_SPACE = LV_STYLE_TEXT_LETTER_SPACE; - void lv_style_set_text_line_space(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -798,8 +642,6 @@ void lv_style_set_text_line_space(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TEXT_LINE_SPACE, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_LINE_SPACE = LV_STYLE_TEXT_LINE_SPACE; - void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value) { lv_style_value_t v = { @@ -808,8 +650,6 @@ void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value) lv_style_set_prop(style, LV_STYLE_TEXT_DECOR, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_DECOR = LV_STYLE_TEXT_DECOR; - void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value) { lv_style_value_t v = { @@ -818,8 +658,6 @@ void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value) lv_style_set_prop(style, LV_STYLE_TEXT_ALIGN, v); } -const lv_style_prop_t _lv_style_const_prop_id_TEXT_ALIGN = LV_STYLE_TEXT_ALIGN; - void lv_style_set_radius(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -828,8 +666,6 @@ void lv_style_set_radius(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_RADIUS, v); } -const lv_style_prop_t _lv_style_const_prop_id_RADIUS = LV_STYLE_RADIUS; - void lv_style_set_clip_corner(lv_style_t * style, bool value) { lv_style_value_t v = { @@ -838,8 +674,6 @@ void lv_style_set_clip_corner(lv_style_t * style, bool value) lv_style_set_prop(style, LV_STYLE_CLIP_CORNER, v); } -const lv_style_prop_t _lv_style_const_prop_id_CLIP_CORNER = LV_STYLE_CLIP_CORNER; - void lv_style_set_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -848,8 +682,6 @@ void lv_style_set_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_OPA = LV_STYLE_OPA; - void lv_style_set_opa_layered(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -858,8 +690,6 @@ void lv_style_set_opa_layered(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_OPA_LAYERED, v); } -const lv_style_prop_t _lv_style_const_prop_id_OPA_LAYERED = LV_STYLE_OPA_LAYERED; - void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value) { lv_style_value_t v = { @@ -868,8 +698,6 @@ void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc lv_style_set_prop(style, LV_STYLE_COLOR_FILTER_DSC, v); } -const lv_style_prop_t _lv_style_const_prop_id_COLOR_FILTER_DSC = LV_STYLE_COLOR_FILTER_DSC; - void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value) { lv_style_value_t v = { @@ -878,8 +706,6 @@ void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_COLOR_FILTER_OPA, v); } -const lv_style_prop_t _lv_style_const_prop_id_COLOR_FILTER_OPA = LV_STYLE_COLOR_FILTER_OPA; - void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value) { lv_style_value_t v = { @@ -888,8 +714,6 @@ void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value) lv_style_set_prop(style, LV_STYLE_ANIM, v); } -const lv_style_prop_t _lv_style_const_prop_id_ANIM = LV_STYLE_ANIM; - void lv_style_set_anim_duration(lv_style_t * style, uint32_t value) { lv_style_value_t v = { @@ -898,8 +722,6 @@ void lv_style_set_anim_duration(lv_style_t * style, uint32_t value) lv_style_set_prop(style, LV_STYLE_ANIM_DURATION, v); } -const lv_style_prop_t _lv_style_const_prop_id_ANIM_DURATION = LV_STYLE_ANIM_DURATION; - void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value) { lv_style_value_t v = { @@ -908,8 +730,6 @@ void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t lv_style_set_prop(style, LV_STYLE_TRANSITION, v); } -const lv_style_prop_t _lv_style_const_prop_id_TRANSITION = LV_STYLE_TRANSITION; - void lv_style_set_blend_mode(lv_style_t * style, lv_blend_mode_t value) { lv_style_value_t v = { @@ -918,8 +738,6 @@ void lv_style_set_blend_mode(lv_style_t * style, lv_blend_mode_t value) lv_style_set_prop(style, LV_STYLE_BLEND_MODE, v); } -const lv_style_prop_t _lv_style_const_prop_id_BLEND_MODE = LV_STYLE_BLEND_MODE; - void lv_style_set_layout(lv_style_t * style, uint16_t value) { lv_style_value_t v = { @@ -928,8 +746,6 @@ void lv_style_set_layout(lv_style_t * style, uint16_t value) lv_style_set_prop(style, LV_STYLE_LAYOUT, v); } -const lv_style_prop_t _lv_style_const_prop_id_LAYOUT = LV_STYLE_LAYOUT; - void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value) { lv_style_value_t v = { @@ -938,9 +754,7 @@ void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value) lv_style_set_prop(style, LV_STYLE_BASE_DIR, v); } -const lv_style_prop_t _lv_style_const_prop_id_BASE_DIR = LV_STYLE_BASE_DIR; - -void lv_style_set_bitmap_mask_src(lv_style_t * style, const lv_image_dsc_t * value) +void lv_style_set_bitmap_mask_src(lv_style_t * style, const void * value) { lv_style_value_t v = { .ptr = value @@ -948,8 +762,6 @@ void lv_style_set_bitmap_mask_src(lv_style_t * style, const lv_image_dsc_t * val lv_style_set_prop(style, LV_STYLE_BITMAP_MASK_SRC, v); } -const lv_style_prop_t _lv_style_const_prop_id_BITMAP_MASK_SRC = LV_STYLE_BITMAP_MASK_SRC; - void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value) { lv_style_value_t v = { @@ -957,8 +769,6 @@ void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value) }; lv_style_set_prop(style, LV_STYLE_ROTARY_SENSITIVITY, v); } - -const lv_style_prop_t _lv_style_const_prop_id_ROTARY_SENSITIVITY = LV_STYLE_ROTARY_SENSITIVITY; #if LV_USE_FLEX void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value) @@ -969,8 +779,6 @@ void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value) lv_style_set_prop(style, LV_STYLE_FLEX_FLOW, v); } -const lv_style_prop_t _lv_style_const_prop_id_FLEX_FLOW = LV_STYLE_FLEX_FLOW; - void lv_style_set_flex_main_place(lv_style_t * style, lv_flex_align_t value) { lv_style_value_t v = { @@ -979,8 +787,6 @@ void lv_style_set_flex_main_place(lv_style_t * style, lv_flex_align_t value) lv_style_set_prop(style, LV_STYLE_FLEX_MAIN_PLACE, v); } -const lv_style_prop_t _lv_style_const_prop_id_FLEX_MAIN_PLACE = LV_STYLE_FLEX_MAIN_PLACE; - void lv_style_set_flex_cross_place(lv_style_t * style, lv_flex_align_t value) { lv_style_value_t v = { @@ -989,8 +795,6 @@ void lv_style_set_flex_cross_place(lv_style_t * style, lv_flex_align_t value) lv_style_set_prop(style, LV_STYLE_FLEX_CROSS_PLACE, v); } -const lv_style_prop_t _lv_style_const_prop_id_FLEX_CROSS_PLACE = LV_STYLE_FLEX_CROSS_PLACE; - void lv_style_set_flex_track_place(lv_style_t * style, lv_flex_align_t value) { lv_style_value_t v = { @@ -999,8 +803,6 @@ void lv_style_set_flex_track_place(lv_style_t * style, lv_flex_align_t value) lv_style_set_prop(style, LV_STYLE_FLEX_TRACK_PLACE, v); } -const lv_style_prop_t _lv_style_const_prop_id_FLEX_TRACK_PLACE = LV_STYLE_FLEX_TRACK_PLACE; - void lv_style_set_flex_grow(lv_style_t * style, uint8_t value) { lv_style_value_t v = { @@ -1008,8 +810,6 @@ void lv_style_set_flex_grow(lv_style_t * style, uint8_t value) }; lv_style_set_prop(style, LV_STYLE_FLEX_GROW, v); } - -const lv_style_prop_t _lv_style_const_prop_id_FLEX_GROW = LV_STYLE_FLEX_GROW; #endif /*LV_USE_FLEX*/ #if LV_USE_GRID @@ -1022,8 +822,6 @@ void lv_style_set_grid_column_dsc_array(lv_style_t * style, const int32_t * valu lv_style_set_prop(style, LV_STYLE_GRID_COLUMN_DSC_ARRAY, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_COLUMN_DSC_ARRAY = LV_STYLE_GRID_COLUMN_DSC_ARRAY; - void lv_style_set_grid_column_align(lv_style_t * style, lv_grid_align_t value) { lv_style_value_t v = { @@ -1032,8 +830,6 @@ void lv_style_set_grid_column_align(lv_style_t * style, lv_grid_align_t value) lv_style_set_prop(style, LV_STYLE_GRID_COLUMN_ALIGN, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_COLUMN_ALIGN = LV_STYLE_GRID_COLUMN_ALIGN; - void lv_style_set_grid_row_dsc_array(lv_style_t * style, const int32_t * value) { lv_style_value_t v = { @@ -1042,8 +838,6 @@ void lv_style_set_grid_row_dsc_array(lv_style_t * style, const int32_t * value) lv_style_set_prop(style, LV_STYLE_GRID_ROW_DSC_ARRAY, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_ROW_DSC_ARRAY = LV_STYLE_GRID_ROW_DSC_ARRAY; - void lv_style_set_grid_row_align(lv_style_t * style, lv_grid_align_t value) { lv_style_value_t v = { @@ -1052,8 +846,6 @@ void lv_style_set_grid_row_align(lv_style_t * style, lv_grid_align_t value) lv_style_set_prop(style, LV_STYLE_GRID_ROW_ALIGN, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_ROW_ALIGN = LV_STYLE_GRID_ROW_ALIGN; - void lv_style_set_grid_cell_column_pos(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -1062,8 +854,6 @@ void lv_style_set_grid_cell_column_pos(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_GRID_CELL_COLUMN_POS, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_COLUMN_POS = LV_STYLE_GRID_CELL_COLUMN_POS; - void lv_style_set_grid_cell_x_align(lv_style_t * style, lv_grid_align_t value) { lv_style_value_t v = { @@ -1072,8 +862,6 @@ void lv_style_set_grid_cell_x_align(lv_style_t * style, lv_grid_align_t value) lv_style_set_prop(style, LV_STYLE_GRID_CELL_X_ALIGN, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_X_ALIGN = LV_STYLE_GRID_CELL_X_ALIGN; - void lv_style_set_grid_cell_column_span(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -1082,8 +870,6 @@ void lv_style_set_grid_cell_column_span(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_GRID_CELL_COLUMN_SPAN, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_COLUMN_SPAN = LV_STYLE_GRID_CELL_COLUMN_SPAN; - void lv_style_set_grid_cell_row_pos(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -1092,8 +878,6 @@ void lv_style_set_grid_cell_row_pos(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_GRID_CELL_ROW_POS, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_ROW_POS = LV_STYLE_GRID_CELL_ROW_POS; - void lv_style_set_grid_cell_y_align(lv_style_t * style, lv_grid_align_t value) { lv_style_value_t v = { @@ -1102,8 +886,6 @@ void lv_style_set_grid_cell_y_align(lv_style_t * style, lv_grid_align_t value) lv_style_set_prop(style, LV_STYLE_GRID_CELL_Y_ALIGN, v); } -const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_Y_ALIGN = LV_STYLE_GRID_CELL_Y_ALIGN; - void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -1111,7 +893,5 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value) }; lv_style_set_prop(style, LV_STYLE_GRID_CELL_ROW_SPAN, v); } - -const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_ROW_SPAN = LV_STYLE_GRID_CELL_ROW_SPAN; #endif /*LV_USE_GRID*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.h index 7aed6b7e9..5714e74d9 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.h @@ -15,731 +15,621 @@ extern "C" { #endif void lv_style_set_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_WIDTH; void lv_style_set_min_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MIN_WIDTH; void lv_style_set_max_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MAX_WIDTH; void lv_style_set_height(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_HEIGHT; void lv_style_set_min_height(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MIN_HEIGHT; void lv_style_set_max_height(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MAX_HEIGHT; void lv_style_set_length(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LENGTH; void lv_style_set_x(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_X; void lv_style_set_y(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_Y; void lv_style_set_align(lv_style_t * style, lv_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ALIGN; void lv_style_set_transform_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_WIDTH; void lv_style_set_transform_height(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_HEIGHT; void lv_style_set_translate_x(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSLATE_X; void lv_style_set_translate_y(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSLATE_Y; void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SCALE_X; void lv_style_set_transform_scale_y(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SCALE_Y; void lv_style_set_transform_rotation(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_ROTATION; void lv_style_set_transform_pivot_x(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_PIVOT_X; void lv_style_set_transform_pivot_y(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_PIVOT_Y; void lv_style_set_transform_skew_x(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SKEW_X; void lv_style_set_transform_skew_y(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSFORM_SKEW_Y; void lv_style_set_pad_top(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_PAD_TOP; void lv_style_set_pad_bottom(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_PAD_BOTTOM; void lv_style_set_pad_left(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_PAD_LEFT; void lv_style_set_pad_right(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_PAD_RIGHT; void lv_style_set_pad_row(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_PAD_ROW; void lv_style_set_pad_column(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_PAD_COLUMN; void lv_style_set_margin_top(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MARGIN_TOP; void lv_style_set_margin_bottom(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MARGIN_BOTTOM; void lv_style_set_margin_left(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MARGIN_LEFT; void lv_style_set_margin_right(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_MARGIN_RIGHT; void lv_style_set_bg_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_COLOR; void lv_style_set_bg_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_OPA; void lv_style_set_bg_grad_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_COLOR; void lv_style_set_bg_grad_dir(lv_style_t * style, lv_grad_dir_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_DIR; void lv_style_set_bg_main_stop(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_MAIN_STOP; void lv_style_set_bg_grad_stop(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_STOP; void lv_style_set_bg_main_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_MAIN_OPA; void lv_style_set_bg_grad_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD_OPA; void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_GRAD; void lv_style_set_bg_image_src(lv_style_t * style, const void * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_SRC; void lv_style_set_bg_image_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_OPA; void lv_style_set_bg_image_recolor(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_RECOLOR; void lv_style_set_bg_image_recolor_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_RECOLOR_OPA; void lv_style_set_bg_image_tiled(lv_style_t * style, bool value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BG_IMAGE_TILED; void lv_style_set_border_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BORDER_COLOR; void lv_style_set_border_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BORDER_OPA; void lv_style_set_border_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BORDER_WIDTH; void lv_style_set_border_side(lv_style_t * style, lv_border_side_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BORDER_SIDE; void lv_style_set_border_post(lv_style_t * style, bool value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BORDER_POST; void lv_style_set_outline_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_WIDTH; void lv_style_set_outline_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_COLOR; void lv_style_set_outline_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_OPA; void lv_style_set_outline_pad(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_OUTLINE_PAD; void lv_style_set_shadow_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_SHADOW_WIDTH; void lv_style_set_shadow_offset_x(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_SHADOW_OFFSET_X; void lv_style_set_shadow_offset_y(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_SHADOW_OFFSET_Y; void lv_style_set_shadow_spread(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_SHADOW_SPREAD; void lv_style_set_shadow_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_SHADOW_COLOR; void lv_style_set_shadow_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_SHADOW_OPA; void lv_style_set_image_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_IMAGE_OPA; void lv_style_set_image_recolor(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_IMAGE_RECOLOR; void lv_style_set_image_recolor_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_IMAGE_RECOLOR_OPA; void lv_style_set_line_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LINE_WIDTH; void lv_style_set_line_dash_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LINE_DASH_WIDTH; void lv_style_set_line_dash_gap(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LINE_DASH_GAP; void lv_style_set_line_rounded(lv_style_t * style, bool value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LINE_ROUNDED; void lv_style_set_line_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LINE_COLOR; void lv_style_set_line_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LINE_OPA; void lv_style_set_arc_width(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ARC_WIDTH; void lv_style_set_arc_rounded(lv_style_t * style, bool value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ARC_ROUNDED; void lv_style_set_arc_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ARC_COLOR; void lv_style_set_arc_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ARC_OPA; void lv_style_set_arc_image_src(lv_style_t * style, const void * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ARC_IMAGE_SRC; void lv_style_set_text_color(lv_style_t * style, lv_color_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_COLOR; void lv_style_set_text_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_OPA; void lv_style_set_text_font(lv_style_t * style, const lv_font_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_FONT; void lv_style_set_text_letter_space(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_LETTER_SPACE; void lv_style_set_text_line_space(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_LINE_SPACE; void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_DECOR; void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TEXT_ALIGN; void lv_style_set_radius(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_RADIUS; void lv_style_set_clip_corner(lv_style_t * style, bool value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_CLIP_CORNER; void lv_style_set_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_OPA; void lv_style_set_opa_layered(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_OPA_LAYERED; void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_COLOR_FILTER_DSC; void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_COLOR_FILTER_OPA; void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ANIM; void lv_style_set_anim_duration(lv_style_t * style, uint32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ANIM_DURATION; void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_TRANSITION; void lv_style_set_blend_mode(lv_style_t * style, lv_blend_mode_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BLEND_MODE; void lv_style_set_layout(lv_style_t * style, uint16_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_LAYOUT; void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BASE_DIR; -void lv_style_set_bitmap_mask_src(lv_style_t * style, const lv_image_dsc_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_BITMAP_MASK_SRC; +void lv_style_set_bitmap_mask_src(lv_style_t * style, const void * value); void lv_style_set_rotary_sensitivity(lv_style_t * style, uint32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_ROTARY_SENSITIVITY; #if LV_USE_FLEX void lv_style_set_flex_flow(lv_style_t * style, lv_flex_flow_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_FLEX_FLOW; void lv_style_set_flex_main_place(lv_style_t * style, lv_flex_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_FLEX_MAIN_PLACE; void lv_style_set_flex_cross_place(lv_style_t * style, lv_flex_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_FLEX_CROSS_PLACE; void lv_style_set_flex_track_place(lv_style_t * style, lv_flex_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_FLEX_TRACK_PLACE; void lv_style_set_flex_grow(lv_style_t * style, uint8_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_FLEX_GROW; #endif /*LV_USE_FLEX*/ #if LV_USE_GRID void lv_style_set_grid_column_dsc_array(lv_style_t * style, const int32_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_COLUMN_DSC_ARRAY; void lv_style_set_grid_column_align(lv_style_t * style, lv_grid_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_COLUMN_ALIGN; void lv_style_set_grid_row_dsc_array(lv_style_t * style, const int32_t * value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_ROW_DSC_ARRAY; void lv_style_set_grid_row_align(lv_style_t * style, lv_grid_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_ROW_ALIGN; void lv_style_set_grid_cell_column_pos(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_COLUMN_POS; void lv_style_set_grid_cell_x_align(lv_style_t * style, lv_grid_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_X_ALIGN; void lv_style_set_grid_cell_column_span(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_COLUMN_SPAN; void lv_style_set_grid_cell_row_pos(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_ROW_POS; void lv_style_set_grid_cell_y_align(lv_style_t * style, lv_grid_align_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_Y_ALIGN; void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); -LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GRID_CELL_ROW_SPAN; #endif /*LV_USE_GRID*/ #define LV_STYLE_CONST_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MIN_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MIN_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MIN_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MAX_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MAX_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MAX_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_HEIGHT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_HEIGHT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_HEIGHT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MIN_HEIGHT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MIN_HEIGHT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MIN_HEIGHT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MAX_HEIGHT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MAX_HEIGHT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MAX_HEIGHT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LENGTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LENGTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LENGTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_X(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_X, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_X, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_Y(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_Y, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_Y, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_ALIGN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ALIGN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_ALIGN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_HEIGHT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_HEIGHT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_HEIGHT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSLATE_X(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSLATE_X, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSLATE_X, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSLATE_Y(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSLATE_Y, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSLATE_Y, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_SCALE_X(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_SCALE_X, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_SCALE_X, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_SCALE_Y(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_SCALE_Y, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_SCALE_Y, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_ROTATION(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_ROTATION, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_ROTATION, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_PIVOT_X(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_PIVOT_X, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_PIVOT_X, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_PIVOT_Y(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_PIVOT_Y, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_PIVOT_Y, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_SKEW_X(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_SKEW_X, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_SKEW_X, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSFORM_SKEW_Y(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSFORM_SKEW_Y, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TRANSFORM_SKEW_Y, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_PAD_TOP(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_PAD_TOP, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_PAD_TOP, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_PAD_BOTTOM(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_PAD_BOTTOM, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_PAD_BOTTOM, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_PAD_LEFT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_PAD_LEFT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_PAD_LEFT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_PAD_RIGHT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_PAD_RIGHT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_PAD_RIGHT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_PAD_ROW(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_PAD_ROW, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_PAD_ROW, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_PAD_COLUMN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_PAD_COLUMN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_PAD_COLUMN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MARGIN_TOP(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MARGIN_TOP, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MARGIN_TOP, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MARGIN_BOTTOM(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MARGIN_BOTTOM, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MARGIN_BOTTOM, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MARGIN_LEFT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MARGIN_LEFT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MARGIN_LEFT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_MARGIN_RIGHT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_MARGIN_RIGHT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_MARGIN_RIGHT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_BG_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_BG_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_GRAD_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_GRAD_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_BG_GRAD_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_BG_GRAD_DIR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_GRAD_DIR, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_GRAD_DIR, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_MAIN_STOP(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_MAIN_STOP, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_MAIN_STOP, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_GRAD_STOP(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_GRAD_STOP, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_GRAD_STOP, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_MAIN_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_MAIN_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_MAIN_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_GRAD_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_GRAD_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_GRAD_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_GRAD(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_GRAD, .value = { .ptr = val } \ + .prop = LV_STYLE_BG_GRAD, .value = { .ptr = val } \ } #define LV_STYLE_CONST_BG_IMAGE_SRC(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_IMAGE_SRC, .value = { .ptr = val } \ + .prop = LV_STYLE_BG_IMAGE_SRC, .value = { .ptr = val } \ } #define LV_STYLE_CONST_BG_IMAGE_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_IMAGE_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_IMAGE_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_IMAGE_RECOLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_IMAGE_RECOLOR, .value = { .color = val } \ + .prop = LV_STYLE_BG_IMAGE_RECOLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_BG_IMAGE_RECOLOR_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BG_IMAGE_TILED(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BG_IMAGE_TILED, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BG_IMAGE_TILED, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BORDER_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BORDER_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_BORDER_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_BORDER_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BORDER_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BORDER_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BORDER_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BORDER_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BORDER_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BORDER_SIDE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BORDER_SIDE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BORDER_SIDE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BORDER_POST(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BORDER_POST, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BORDER_POST, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_OUTLINE_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_OUTLINE_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_OUTLINE_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_OUTLINE_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_OUTLINE_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_OUTLINE_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_OUTLINE_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_OUTLINE_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_OUTLINE_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_OUTLINE_PAD(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_OUTLINE_PAD, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_OUTLINE_PAD, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_SHADOW_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_SHADOW_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_SHADOW_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_SHADOW_OFFSET_X(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_SHADOW_OFFSET_X, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_SHADOW_OFFSET_X, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_SHADOW_OFFSET_Y(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_SHADOW_OFFSET_Y, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_SHADOW_OFFSET_Y, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_SHADOW_SPREAD(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_SHADOW_SPREAD, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_SHADOW_SPREAD, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_SHADOW_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_SHADOW_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_SHADOW_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_SHADOW_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_SHADOW_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_SHADOW_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_IMAGE_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_IMAGE_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_IMAGE_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_IMAGE_RECOLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_IMAGE_RECOLOR, .value = { .color = val } \ + .prop = LV_STYLE_IMAGE_RECOLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_IMAGE_RECOLOR_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LINE_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LINE_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LINE_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LINE_DASH_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LINE_DASH_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LINE_DASH_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LINE_DASH_GAP(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LINE_DASH_GAP, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LINE_DASH_GAP, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LINE_ROUNDED(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LINE_ROUNDED, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LINE_ROUNDED, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LINE_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LINE_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_LINE_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_LINE_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LINE_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LINE_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_ARC_WIDTH(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ARC_WIDTH, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_ARC_WIDTH, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_ARC_ROUNDED(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ARC_ROUNDED, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_ARC_ROUNDED, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_ARC_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ARC_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_ARC_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_ARC_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ARC_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_ARC_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_ARC_IMAGE_SRC(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ARC_IMAGE_SRC, .value = { .ptr = val } \ + .prop = LV_STYLE_ARC_IMAGE_SRC, .value = { .ptr = val } \ } #define LV_STYLE_CONST_TEXT_COLOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_COLOR, .value = { .color = val } \ + .prop = LV_STYLE_TEXT_COLOR, .value = { .color = val } \ } #define LV_STYLE_CONST_TEXT_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TEXT_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TEXT_FONT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_FONT, .value = { .ptr = val } \ + .prop = LV_STYLE_TEXT_FONT, .value = { .ptr = val } \ } #define LV_STYLE_CONST_TEXT_LETTER_SPACE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_LETTER_SPACE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TEXT_LETTER_SPACE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TEXT_LINE_SPACE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_LINE_SPACE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TEXT_LINE_SPACE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TEXT_DECOR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_DECOR, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TEXT_DECOR, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TEXT_ALIGN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TEXT_ALIGN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_TEXT_ALIGN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_RADIUS(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_RADIUS, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_RADIUS, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_CLIP_CORNER(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_CLIP_CORNER, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_CLIP_CORNER, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_OPA_LAYERED(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_OPA_LAYERED, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_OPA_LAYERED, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_COLOR_FILTER_DSC(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_COLOR_FILTER_DSC, .value = { .ptr = val } \ + .prop = LV_STYLE_COLOR_FILTER_DSC, .value = { .ptr = val } \ } #define LV_STYLE_CONST_COLOR_FILTER_OPA(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_COLOR_FILTER_OPA, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_COLOR_FILTER_OPA, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_ANIM(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ANIM, .value = { .ptr = val } \ + .prop = LV_STYLE_ANIM, .value = { .ptr = val } \ } #define LV_STYLE_CONST_ANIM_DURATION(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ANIM_DURATION, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_ANIM_DURATION, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_TRANSITION(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_TRANSITION, .value = { .ptr = val } \ + .prop = LV_STYLE_TRANSITION, .value = { .ptr = val } \ } #define LV_STYLE_CONST_BLEND_MODE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BLEND_MODE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BLEND_MODE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_LAYOUT(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_LAYOUT, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_LAYOUT, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BASE_DIR(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BASE_DIR, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_BASE_DIR, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_BITMAP_MASK_SRC(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_BITMAP_MASK_SRC, .value = { .ptr = val } \ + .prop = LV_STYLE_BITMAP_MASK_SRC, .value = { .ptr = val } \ } #define LV_STYLE_CONST_ROTARY_SENSITIVITY(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_ROTARY_SENSITIVITY, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_ROTARY_SENSITIVITY, .value = { .num = (int32_t)val } \ } #if LV_USE_FLEX #define LV_STYLE_CONST_FLEX_FLOW(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_FLEX_FLOW, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_FLEX_FLOW, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_FLEX_MAIN_PLACE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_FLEX_MAIN_PLACE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_FLEX_MAIN_PLACE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_FLEX_CROSS_PLACE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_FLEX_CROSS_PLACE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_FLEX_CROSS_PLACE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_FLEX_TRACK_PLACE(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_FLEX_TRACK_PLACE, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_FLEX_TRACK_PLACE, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_FLEX_GROW(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_FLEX_GROW, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_FLEX_GROW, .value = { .num = (int32_t)val } \ } #endif /*LV_USE_FLEX*/ @@ -747,52 +637,52 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_style_prop_t _lv_style_const_prop_id_GR #define LV_STYLE_CONST_GRID_COLUMN_DSC_ARRAY(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_COLUMN_DSC_ARRAY, .value = { .ptr = val } \ + .prop = LV_STYLE_GRID_COLUMN_DSC_ARRAY, .value = { .ptr = val } \ } #define LV_STYLE_CONST_GRID_COLUMN_ALIGN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_COLUMN_ALIGN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_COLUMN_ALIGN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_ROW_DSC_ARRAY(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_ROW_DSC_ARRAY, .value = { .ptr = val } \ + .prop = LV_STYLE_GRID_ROW_DSC_ARRAY, .value = { .ptr = val } \ } #define LV_STYLE_CONST_GRID_ROW_ALIGN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_ROW_ALIGN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_ROW_ALIGN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_CELL_COLUMN_POS(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_CELL_COLUMN_POS, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_CELL_COLUMN_POS, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_CELL_X_ALIGN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_CELL_X_ALIGN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_CELL_X_ALIGN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_CELL_COLUMN_SPAN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_CELL_COLUMN_SPAN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_CELL_COLUMN_SPAN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_CELL_ROW_POS(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_CELL_ROW_POS, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_CELL_ROW_POS, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_CELL_Y_ALIGN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_CELL_Y_ALIGN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_CELL_Y_ALIGN, .value = { .num = (int32_t)val } \ } #define LV_STYLE_CONST_GRID_CELL_ROW_SPAN(val) \ { \ - .prop_ptr = &_lv_style_const_prop_id_GRID_CELL_ROW_SPAN, .value = { .num = (int32_t)val } \ + .prop = LV_STYLE_GRID_CELL_ROW_SPAN, .value = { .num = (int32_t)val } \ } #endif /*LV_USE_GRID*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_private.h new file mode 100644 index 000000000..8a88185d6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_style_private.h + * + */ + +#ifndef LV_STYLE_PRIVATE_H +#define LV_STYLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_STYLE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c index b9e96de6e..11081f959 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c @@ -6,14 +6,14 @@ /********************* * INCLUDES *********************/ -#include -#include "lv_text.h" +#include "lv_text_private.h" #include "lv_text_ap.h" #include "lv_math.h" #include "lv_log.h" #include "lv_assert.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" +#include "../misc/lv_types.h" /********************* * DEFINES @@ -55,23 +55,23 @@ * GLOBAL VARIABLES **********************/ #if LV_TXT_ENC == LV_TXT_ENC_UTF8 - uint8_t (*_lv_text_encoded_size)(const char *) = lv_text_utf8_size; - uint32_t (*_lv_text_unicode_to_encoded)(uint32_t) = lv_text_unicode_to_utf8; - uint32_t (*_lv_text_encoded_conv_wc)(uint32_t) = lv_text_utf8_conv_wc; - uint32_t (*_lv_text_encoded_next)(const char *, uint32_t *) = lv_text_utf8_next; - uint32_t (*_lv_text_encoded_prev)(const char *, uint32_t *) = lv_text_utf8_prev; - uint32_t (*_lv_text_encoded_get_byte_id)(const char *, uint32_t) = lv_text_utf8_get_byte_id; - uint32_t (*_lv_text_encoded_get_char_id)(const char *, uint32_t) = lv_text_utf8_get_char_id; - uint32_t (*_lv_text_get_encoded_length)(const char *) = lv_text_utf8_get_length; + uint8_t (*const lv_text_encoded_size)(const char *) = lv_text_utf8_size; + uint32_t (*const lv_text_unicode_to_encoded)(uint32_t) = lv_text_unicode_to_utf8; + uint32_t (*const lv_text_encoded_conv_wc)(uint32_t) = lv_text_utf8_conv_wc; + uint32_t (*const lv_text_encoded_next)(const char *, uint32_t *) = lv_text_utf8_next; + uint32_t (*const lv_text_encoded_prev)(const char *, uint32_t *) = lv_text_utf8_prev; + uint32_t (*const lv_text_encoded_get_byte_id)(const char *, uint32_t) = lv_text_utf8_get_byte_id; + uint32_t (*const lv_text_encoded_get_char_id)(const char *, uint32_t) = lv_text_utf8_get_char_id; + uint32_t (*const lv_text_get_encoded_length)(const char *) = lv_text_utf8_get_length; #elif LV_TXT_ENC == LV_TXT_ENC_ASCII - uint8_t (*_lv_text_encoded_size)(const char *) = lv_text_iso8859_1_size; - uint32_t (*_lv_text_unicode_to_encoded)(uint32_t) = lv_text_unicode_to_iso8859_1; - uint32_t (*_lv_text_encoded_conv_wc)(uint32_t) = lv_text_iso8859_1_conv_wc; - uint32_t (*_lv_text_encoded_next)(const char *, uint32_t *) = lv_text_iso8859_1_next; - uint32_t (*_lv_text_encoded_prev)(const char *, uint32_t *) = lv_text_iso8859_1_prev; - uint32_t (*_lv_text_encoded_get_byte_id)(const char *, uint32_t) = lv_text_iso8859_1_get_byte_id; - uint32_t (*_lv_text_encoded_get_char_id)(const char *, uint32_t) = lv_text_iso8859_1_get_char_id; - uint32_t (*_lv_text_get_encoded_length)(const char *) = lv_text_iso8859_1_get_length; + uint8_t (*const lv_text_encoded_size)(const char *) = lv_text_iso8859_1_size; + uint32_t (*const lv_text_unicode_to_encoded)(uint32_t) = lv_text_unicode_to_iso8859_1; + uint32_t (*const lv_text_encoded_conv_wc)(uint32_t) = lv_text_iso8859_1_conv_wc; + uint32_t (*const lv_text_encoded_next)(const char *, uint32_t *) = lv_text_iso8859_1_next; + uint32_t (*const lv_text_encoded_prev)(const char *, uint32_t *) = lv_text_iso8859_1_prev; + uint32_t (*const lv_text_encoded_get_byte_id)(const char *, uint32_t) = lv_text_iso8859_1_get_byte_id; + uint32_t (*const lv_text_encoded_get_char_id)(const char *, uint32_t) = lv_text_iso8859_1_get_char_id; + uint32_t (*const lv_text_get_encoded_length)(const char *) = lv_text_iso8859_1_get_length; #endif @@ -106,7 +106,7 @@ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t /*Calc. the height and longest line*/ while(text[line_start] != '\0') { - new_line_start += _lv_text_get_next_line(&text[line_start], font, letter_space, max_width, NULL, flag); + new_line_start += lv_text_get_next_line(&text[line_start], font, letter_space, max_width, NULL, flag); if((unsigned long)size_res->y + (unsigned long)letter_height + (unsigned long)line_space > LV_MAX_OF(int32_t)) { LV_LOG_WARN("integer overflow while calculating text height"); @@ -164,12 +164,11 @@ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid line breaks * @param flags settings for the text from 'txt_flag_type' enum * @param[out] word_w_ptr width (in pixels) of the parsed word. May be NULL. - * @param force Force return the fraction of the word that can fit in the provided space. * @return the index of the first char of the next word (in byte index not letter index. With UTF-8 they are different) */ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, int32_t letter_space, int32_t max_width, - lv_text_flag_t flag, uint32_t * word_w_ptr, bool force) + lv_text_flag_t flag, uint32_t * word_w_ptr) { if(txt == NULL || txt[0] == '\0') return 0; if(font == NULL) return 0; @@ -180,17 +179,17 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, uint32_t letter = 0; /*Letter at i*/ uint32_t letter_next = 0; /*Letter at i_next*/ int32_t letter_w; - int32_t cur_w = 0; /*Pixel Width of transversed string*/ - uint32_t word_len = 0; /*Number of characters in the transversed word*/ + int32_t cur_w = 0; /*Pixel Width of traversed string*/ + uint32_t word_len = 0; /*Number of characters in the traversed word*/ uint32_t break_index = NO_BREAK_FOUND; /*only used for "long" words*/ uint32_t break_letter_count = 0; /*Number of characters up to the long word break point*/ - letter = _lv_text_encoded_next(txt, &i_next); + letter = lv_text_encoded_next(txt, &i_next); i_next_next = i_next; /*Obtain the full word, regardless if it fits or not in max_width*/ while(txt[i] != '\0') { - letter_next = _lv_text_encoded_next(txt, &i_next_next); + letter_next = lv_text_encoded_next(txt, &i_next_next); word_len++; letter_w = lv_font_get_glyph_width(font, letter, letter_next); @@ -208,14 +207,14 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, } /*Check for new line chars and breakchars*/ - if(letter == '\n' || letter == '\r' || _lv_text_is_break_char(letter)) { + if(letter == '\n' || letter == '\r' || lv_text_is_break_char(letter)) { /*Update the output width on the first character if it fits. *Must do this here in case first letter is a break character.*/ if(i == 0 && break_index == NO_BREAK_FOUND && word_w_ptr != NULL) *word_w_ptr = cur_w; word_len--; break; } - else if(_lv_text_is_a_word(letter_next) || _lv_text_is_a_word(letter)) { + else if(lv_text_is_a_word(letter_next) || lv_text_is_a_word(letter)) { /*Found a word for single letter, usually true for CJK*/ *word_w_ptr = cur_w; i = i_next; @@ -239,14 +238,14 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, #if LV_TXT_LINE_BREAK_LONG_LEN > 0 /*Word doesn't fit in provided space, but isn't "long"*/ if(word_len < LV_TXT_LINE_BREAK_LONG_LEN) { - if(force) return break_index; + if(flag & LV_TEXT_FLAG_BREAK_ALL) return break_index; if(word_w_ptr != NULL) *word_w_ptr = 0; /*Return no word*/ return 0; } /*Word is "long," but insufficient amounts can fit in provided space*/ if(break_letter_count < LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN) { - if(force) return break_index; + if(flag & LV_TEXT_FLAG_BREAK_ALL) return break_index; if(word_w_ptr != NULL) *word_w_ptr = 0; return 0; } @@ -257,7 +256,7 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, int32_t n_move = LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN - (word_len - break_letter_count); /*Move pointer "i" backwards*/ for(; n_move > 0; n_move--) { - _lv_text_encoded_prev(txt, &i); + lv_text_encoded_prev(txt, &i); /** * TODO: it would be appropriate to update the returned * word width hereHowever, in current usage, this doesn't impact anything. @@ -266,16 +265,16 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, } return i; #else - if(force) return break_index; + if(flag & LV_TEXT_FLAG_BREAK_ALL) return break_index; if(word_w_ptr != NULL) *word_w_ptr = 0; /*Return no word*/ (void) break_letter_count; return 0; #endif } -uint32_t _lv_text_get_next_line(const char * txt, const lv_font_t * font, - int32_t letter_space, int32_t max_width, - int32_t * used_width, lv_text_flag_t flag) +uint32_t lv_text_get_next_line(const char * txt, const lv_font_t * font, + int32_t letter_space, int32_t max_width, + int32_t * used_width, lv_text_flag_t flag) { if(used_width) *used_width = 0; @@ -301,8 +300,11 @@ uint32_t _lv_text_get_next_line(const char * txt, const lv_font_t * font, uint32_t i = 0; /*Iterating index into txt*/ while(txt[i] != '\0' && max_width > 0) { + lv_text_flag_t word_flag = flag; + if(i == 0) word_flag |= LV_TEXT_FLAG_BREAK_ALL; + uint32_t word_w = 0; - uint32_t advance = lv_text_get_next_word(&txt[i], font, letter_space, max_width, flag, &word_w, i == 0); + uint32_t advance = lv_text_get_next_word(&txt[i], font, letter_space, max_width, word_flag, &word_w); max_width -= word_w; line_w += word_w; @@ -323,7 +325,7 @@ uint32_t _lv_text_get_next_line(const char * txt, const lv_font_t * font, /*Always step at least one to avoid infinite loops*/ if(i == 0) { - uint32_t letter = _lv_text_encoded_next(txt, &i); + uint32_t letter = lv_text_encoded_next(txt, &i); if(used_width != NULL) { line_w = lv_font_get_glyph_width(font, letter, '\0'); } @@ -349,7 +351,7 @@ int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * f while(i < length) { uint32_t letter; uint32_t letter_next; - _lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); + lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); int32_t char_width = lv_font_get_glyph_width(font, letter, letter_next); if(char_width > 0) { @@ -367,7 +369,7 @@ int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * f return width; } -void _lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt) +void lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt) { if(txt_buf == NULL || ins_txt == NULL) return; @@ -376,7 +378,7 @@ void _lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt) if(ins_len == 0) return; size_t new_len = ins_len + old_len; - pos = _lv_text_encoded_get_byte_id(txt_buf, pos); /*Convert to byte index instead of letter index*/ + pos = lv_text_encoded_get_byte_id(txt_buf, pos); /*Convert to byte index instead of letter index*/ /*Copy the second part into the end to make place to text to insert*/ size_t i; @@ -388,14 +390,14 @@ void _lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt) lv_memcpy(txt_buf + pos, ins_txt, ins_len); } -void _lv_text_cut(char * txt, uint32_t pos, uint32_t len) +void lv_text_cut(char * txt, uint32_t pos, uint32_t len) { if(txt == NULL) return; size_t old_len = lv_strlen(txt); - pos = _lv_text_encoded_get_byte_id(txt, pos); /*Convert to byte index instead of letter index*/ - len = _lv_text_encoded_get_byte_id(&txt[pos], len); + pos = lv_text_encoded_get_byte_id(txt, pos); /*Convert to byte index instead of letter index*/ + len = lv_text_encoded_get_byte_id(&txt[pos], len); /*Copy the second part into the end to make place to text to insert*/ uint32_t i; @@ -404,7 +406,7 @@ void _lv_text_cut(char * txt, uint32_t pos, uint32_t len) } } -char * _lv_text_set_text_vfmt(const char * fmt, va_list ap) +char * lv_text_set_text_vfmt(const char * fmt, va_list ap) { /*Allocate space for the new text by using trick from C99 standard section 7.19.6.12*/ va_list ap_copy; @@ -424,13 +426,13 @@ char * _lv_text_set_text_vfmt(const char * fmt, va_list ap) lv_vsnprintf(raw_txt, len + 1, fmt, ap); /*Get the size of the Arabic text and process it*/ - size_t len_ap = _lv_text_ap_calc_bytes_count(raw_txt); + size_t len_ap = lv_text_ap_calc_bytes_count(raw_txt); text = lv_malloc(len_ap + 1); LV_ASSERT_MALLOC(text); if(text == NULL) { return NULL; } - _lv_text_ap_proc(raw_txt, text); + lv_text_ap_proc(raw_txt, text); lv_free(raw_txt); #else @@ -446,10 +448,10 @@ char * _lv_text_set_text_vfmt(const char * fmt, va_list ap) return text; } -void _lv_text_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t * ofs) +void lv_text_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t * ofs) { - *letter = _lv_text_encoded_next(txt, ofs); - *letter_next = *letter != '\0' ? _lv_text_encoded_next(&txt[*ofs], NULL) : 0; + *letter = lv_text_encoded_next(txt, ofs); + *letter_next = *letter != '\0' ? lv_text_encoded_next(&txt[*ofs], NULL) : 0; } #if LV_TXT_ENC == LV_TXT_ENC_UTF8 @@ -629,7 +631,7 @@ static uint32_t lv_text_utf8_prev(const char * txt, uint32_t * i) do { if(cnt >= 4) return 0; /*No UTF-8 char found before the initial*/ - c_size = _lv_text_encoded_size(&txt[*i]); + c_size = lv_text_encoded_size(&txt[*i]); if(c_size == 0) { if(*i != 0) (*i)--; @@ -640,7 +642,7 @@ static uint32_t lv_text_utf8_prev(const char * txt, uint32_t * i) } while(c_size == 0); uint32_t i_tmp = *i; - uint32_t letter = _lv_text_encoded_next(txt, &i_tmp); /*Character found, get it*/ + uint32_t letter = lv_text_encoded_next(txt, &i_tmp); /*Character found, get it*/ return letter; } @@ -657,7 +659,7 @@ static uint32_t lv_text_utf8_get_byte_id(const char * txt, uint32_t utf8_id) uint32_t i; uint32_t byte_cnt = 0; for(i = 0; i < utf8_id && txt[byte_cnt] != '\0'; i++) { - uint8_t c_size = _lv_text_encoded_size(&txt[byte_cnt]); + uint8_t c_size = lv_text_encoded_size(&txt[byte_cnt]); /* If the char was invalid tell it's 1 byte long*/ byte_cnt += c_size ? c_size : 1; } @@ -678,7 +680,7 @@ static uint32_t lv_text_utf8_get_char_id(const char * txt, uint32_t byte_id) uint32_t char_cnt = 0; while(i < byte_id) { - _lv_text_encoded_next(txt, &i); /*'i' points to the next letter so use the prev. value*/ + lv_text_encoded_next(txt, &i); /*'i' points to the next letter so use the prev. value*/ char_cnt++; } @@ -697,7 +699,7 @@ static uint32_t lv_text_utf8_get_length(const char * txt) uint32_t i = 0; while(txt[i] != '\0') { - _lv_text_encoded_next(txt, &i); + lv_text_encoded_next(txt, &i); len++; } @@ -712,7 +714,7 @@ static uint32_t lv_text_utf8_get_length(const char * txt) /** * Give the size of an ISO8859-1 coded character * @param str pointer to a character in a string - * @return length of the UTF-8 character (1,2,3 or 4). O on invalid code + * @return length of the ISO8859-1 coded character, will be always 1. */ static uint8_t lv_text_iso8859_1_size(const char * str) { @@ -748,9 +750,9 @@ static uint32_t lv_text_iso8859_1_conv_wc(uint32_t c) * Decode an ISO8859-1 character from a string. * @param txt pointer to '\0' terminated string * @param i start byte index in 'txt' where to start. - * After call it will point to the next UTF-8 char in 'txt'. + * After call it will point to the next ISO8859-1 coded char in 'txt'. * NULL to use txt[0] as index - * @return the decoded Unicode character or 0 on invalid UTF-8 code + * @return the decoded ISO8859-1 character. */ static uint32_t lv_text_iso8859_1_next(const char * txt, uint32_t * i) { @@ -764,8 +766,8 @@ static uint32_t lv_text_iso8859_1_next(const char * txt, uint32_t * i) /** * Get previous ISO8859-1 character form a string. * @param txt pointer to '\0' terminated string - * @param i start byte index in 'txt' where to start. After the call it will point to the previous UTF-8 char in 'txt'. - * @return the decoded Unicode character or 0 on invalid UTF-8 code + * @param i start byte index in 'txt' where to start. After the call it will point to the previous ISO8859-1 coded char in 'txt'. + * @return the decoded ISO8859-1 character. */ static uint32_t lv_text_iso8859_1_prev(const char * txt, uint32_t * i) { @@ -779,8 +781,8 @@ static uint32_t lv_text_iso8859_1_prev(const char * txt, uint32_t * i) /** * Convert a character index (in an ISO8859-1 text) to byte index. - * E.g. in "AÁRT" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long - * @param txt a '\0' terminated UTF-8 string + * The ISO8859-1 encoding is compatible with ASCII so the indices of characters is the same as the indices of bytes. + * @param txt a '\0' terminated char string * @param utf8_id character index * @return byte index of the 'utf8_id'th letter */ @@ -792,8 +794,8 @@ static uint32_t lv_text_iso8859_1_get_byte_id(const char * txt, uint32_t utf8_id /** * Convert a byte index (in an ISO8859-1 text) to character index. - * E.g. in "AÁRT" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long - * @param txt a '\0' terminated UTF-8 string + * The ISO8859-1 encoding is compatible with ASCII so the indices of characters is the same as the indices of bytes. + * @param txt a '\0' terminated char string * @param byte_id byte index * @return character index of the letter at 'byte_id'th position */ @@ -804,8 +806,8 @@ static uint32_t lv_text_iso8859_1_get_char_id(const char * txt, uint32_t byte_id } /** - * Get the number of characters (and NOT bytes) in a string. Decode it with UTF-8 if enabled. - * E.g.: "ÁBC" is 3 characters (but 4 bytes) + * Get the number of characters (and NOT bytes) in a string. + * The ISO8859-1 encoding is compatible with ASCII so the number of characters is the same as the number of bytes. * @param txt a '\0' terminated char string * @return number of characters */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h index b2eddab4e..f2407dd8e 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h @@ -15,12 +15,10 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" -#include -#include +#include "lv_types.h" #include "lv_area.h" #include "../font/lv_font.h" #include "../stdlib/lv_sprintf.h" -#include "lv_types.h" /********************* * DEFINES @@ -37,31 +35,23 @@ extern "C" { * Options for text rendering. */ -enum _lv_text_flag_t { - LV_TEXT_FLAG_NONE = 0x00, - LV_TEXT_FLAG_EXPAND = 0x01, /**< Ignore max-width to avoid automatic word wrapping*/ - LV_TEXT_FLAG_FIT = 0x02, /**< Max-width is already equal to the longest line. (Used to skip some calculation)*/ -}; - -#ifdef DOXYGEN -typedef _lv_text_flag_t lv_text_flag_t; -#else -typedef uint8_t lv_text_flag_t; -#endif /*DOXYGEN*/ +typedef enum { + LV_TEXT_FLAG_NONE = 0x00, + LV_TEXT_FLAG_EXPAND = 0x01, /**< Ignore max-width to avoid automatic word wrapping*/ + LV_TEXT_FLAG_FIT = 0x02, /**< Max-width is already equal to the longest line. (Used to skip some calculation)*/ + LV_TEXT_FLAG_BREAK_ALL = 0x04, /**< To prevent overflow, insert breaks between any two characters. + Otherwise breaks are inserted at word boundaries, as configured via LV_TXT_BREAK_CHARS + or according to LV_TXT_LINE_BREAK_LONG_LEN, LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN, + and LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN.*/ +} lv_text_flag_t; /** Label align policy*/ -enum _lv_text_align_t { +typedef enum { LV_TEXT_ALIGN_AUTO, /**< Align text auto*/ LV_TEXT_ALIGN_LEFT, /**< Align text to left*/ LV_TEXT_ALIGN_CENTER, /**< Align text to center*/ LV_TEXT_ALIGN_RIGHT, /**< Align text to right*/ -}; - -#ifdef DOXYGEN -typedef _lv_text_align_t lv_text_align_t; -#else -typedef uint8_t lv_text_align_t; -#endif /*DOXYGEN*/ +} lv_text_align_t; /********************** * GLOBAL PROTOTYPES @@ -82,22 +72,6 @@ typedef uint8_t lv_text_align_t; void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, int32_t letter_space, int32_t line_space, int32_t max_width, lv_text_flag_t flag); -/** - * Get the next line of text. Check line length and break chars too. - * @param txt a '\0' terminated string - * @param font pointer to a font - * @param letter_space letter space - * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid - * line breaks - * @param used_width When used_width != NULL, save the width of this line if - * flag == LV_TEXT_FLAG_NONE, otherwise save -1. - * @param flag settings for the text from 'txt_flag_type' enum - * @return the index of the first char of the new line (in byte index not letter index. With UTF-8 - * they are different) - */ -uint32_t _lv_text_get_next_line(const char * txt, const lv_font_t * font, int32_t letter_space, - int32_t max_width, int32_t * used_width, lv_text_flag_t flag); - /** * Give the length of a text with a given font * @param txt a '\0' terminate string @@ -109,222 +83,6 @@ uint32_t _lv_text_get_next_line(const char * txt, const lv_font_t * font, int32_ */ int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space); -/** - * Insert a string into an other - * @param txt_buf the original text (must be big enough for the result text and NULL terminated) - * @param pos position to insert (0: before the original text, 1: after the first char etc.) - * @param ins_txt text to insert, must be '\0' terminated - */ -void _lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt); - -/** - * Delete a part of a string - * @param txt string to modify, must be '\0' terminated and should point to a heap or stack frame, not read-only memory. - * @param pos position where to start the deleting (0: before the first char, 1: after the first - * char etc.) - * @param len number of characters to delete - */ -void _lv_text_cut(char * txt, uint32_t pos, uint32_t len); - -/** - * return a new formatted text. Memory will be allocated to store the text. - * @param fmt `printf`-like format - * @param ap items to print - - * @return pointer to the allocated text string. - */ -char * _lv_text_set_text_vfmt(const char * fmt, va_list ap) LV_FORMAT_ATTRIBUTE(1, 0); - -/** - * Decode two encoded character from a string. - * @param txt pointer to '\0' terminated string - * @param letter the first decoded Unicode character or 0 on invalid data code - * @param letter_next the second decoded Unicode character or 0 on invalid data code - * @param ofs start index in 'txt' where to start. - * After the call it will point to the next encoded char in 'txt'. - * NULL to use txt[0] as index - */ -void _lv_text_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t * ofs); - -/** - * Test if char is break char or not (a text can broken here or not) - * @param letter a letter - * @return false: 'letter' is not break char - */ -static inline bool _lv_text_is_break_char(uint32_t letter) -{ - uint8_t i; - bool ret = false; - - /*Compare the letter to TXT_BREAK_CHARS*/ - for(i = 0; LV_TXT_BREAK_CHARS[i] != '\0'; i++) { - if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) { - ret = true; /*If match then it is break char*/ - break; - } - } - - return ret; -} - -/** - * Test if char is break char or not (a text can broken here or not) - * @param letter a letter - * @return false: 'letter' is not break char - */ -static inline bool _lv_text_is_a_word(uint32_t letter) -{ - /*Cheap check on invalid letter*/ - if(letter == 0) return false; - - /*CJK Unified Ideographs*/ - if(letter >= 0x4E00 && letter <= 0x9FFF) { - return true; - } - - /*Fullwidth ASCII variants*/ - if(letter >= 0xFF01 && letter <= 0xFF5E) { - return true; - } - - /*CJK symbols and punctuation*/ - if(letter >= 0x3000 && letter <= 0x303F) { - return true; - } - - /*CJK Radicals Supplement*/ - if(letter >= 0x2E80 && letter <= 0x2EFF) { - return true; - } - - /*CJK Strokes*/ - if(letter >= 0x31C0 && letter <= 0x31EF) { - return true; - } - - /*Hiragana and Katakana*/ - if(letter >= 0x3040 && letter <= 0x30FF) { - return true; - } - - /*Chinese Vertical Forms*/ - if(letter >= 0xFE10 && letter <= 0xFE1F) { - return true; - } - - /*CJK Compatibility Forms*/ - if(letter >= 0xFE30 && letter <= 0xFE4F) { - return true; - } - - return false; -} - -/** - * Test if character can be treated as marker, and don't need to be rendered. - * Note, this is not a full list. Add your findings to the list. - * - * @param letter a letter - * @return true if so - */ -static inline bool _lv_text_is_marker(uint32_t letter) -{ - if(letter < 0x20) return true; - - /*U+061C ARABIC LETTER MARK, see https://www.compart.com/en/unicode/block/U+0600*/ - if(letter == 0x061C) return true; - - /*U+115F HANGUL CHOSEONG FILLER, See https://www.compart.com/en/unicode/block/U+1100*/ - if(letter == 0x115F) return true; - /*U+1160 HANGUL JUNGSEONG FILLER*/ - if(letter == 0x1160) return true; - - /*See https://www.compart.com/en/unicode/block/U+1800*/ - if(letter >= 0x180B && letter <= 0x180E) return true; - - /*See https://www.compart.com/en/unicode/block/U+2000*/ - if(letter >= 0x200B && letter <= 0x200F) return true; - if(letter >= 0x2028 && letter <= 0x202F) return true; - if(letter >= 0x205F && letter <= 0x206F) return true; - - /*U+FEFF ZERO WIDTH NO-BREAK SPACE, see https://www.compart.com/en/unicode/block/U+FE70*/ - if(letter == 0xFEFF) return true; - - if(letter == 0xF8FF) return true; /*LV_SYMBOL_DUMMY*/ - - return false; -} - -/*************************************************************** - * GLOBAL FUNCTION POINTERS FOR CHARACTER ENCODING INTERFACE - ***************************************************************/ - -/** - * Give the size of an encoded character - * @param str pointer to a character in a string - * @return length of the encoded character (1,2,3 ...). O in invalid - */ -extern uint8_t (*_lv_text_encoded_size)(const char *); - -/** - * Convert a Unicode letter to encoded - * @param letter_uni a Unicode letter - * @return Encoded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ü') - */ -extern uint32_t (*_lv_text_unicode_to_encoded)(uint32_t); - -/** - * Convert a wide character, e.g. 'Á' little endian to be compatible with the encoded format. - * @param c a wide character - * @return `c` in the encoded format - */ -extern uint32_t (*_lv_text_encoded_conv_wc)(uint32_t c); - -/** - * Decode the next encoded character from a string. - * @param txt pointer to '\0' terminated string - * @param i start index in 'txt' where to start. - * After the call it will point to the next encoded char in 'txt'. - * NULL to use txt[0] as index - * @return the decoded Unicode character or 0 on invalid data code - */ -extern uint32_t (*_lv_text_encoded_next)(const char *, uint32_t *); - -/** - * Get the previous encoded character form a string. - * @param txt pointer to '\0' terminated string - * @param i_start index in 'txt' where to start. After the call it will point to the previous - * encoded char in 'txt'. - * @return the decoded Unicode character or 0 on invalid data - */ -extern uint32_t (*_lv_text_encoded_prev)(const char *, uint32_t *); - -/** - * Convert a letter index (in the encoded text) to byte index. - * E.g. in UTF-8 "AÁRT" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long - * @param txt a '\0' terminated UTF-8 string - * @param enc_id letter index - * @return byte index of the 'enc_id'th letter - */ -extern uint32_t (*_lv_text_encoded_get_byte_id)(const char *, uint32_t); - -/** - * Convert a byte index (in an encoded text) to character index. - * E.g. in UTF-8 "AÁRT" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long - * @param txt a '\0' terminated UTF-8 string - * @param byte_id byte index - * @return character index of the letter at 'byte_id'th position - */ -extern uint32_t (*_lv_text_encoded_get_char_id)(const char *, uint32_t); - -/** - * Get the number of characters (and NOT bytes) in a string. - * E.g. in UTF-8 "ÁBC" is 3 characters (but 4 bytes) - * @param txt a '\0' terminated char string - * @return number of characters - */ -extern uint32_t (*_lv_text_get_encoded_length)(const char *); - /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c index 95e0dd772..320debd0f 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c @@ -6,10 +6,10 @@ /********************* * INCLUDES *********************/ -#include #include "lv_bidi.h" -#include "lv_text.h" +#include "lv_text_private.h" #include "lv_text_ap.h" +#include "lv_types.h" #include "../stdlib/lv_mem.h" #include "../draw/lv_draw.h" @@ -49,7 +49,7 @@ const ap_chars_map_t ap_chars_map[] = { {1, 0xFE84, -1, 0, -1, {1, 0}}, // أ {2, 0xFE86, -1, 0, -1, {1, 0}}, // ؤ {3, 0xFE88, -1, 0, -1, {1, 0}}, // ﺇ - {4, 0xFE8A, 1, 2, -1, {1, 0}}, // ئ + {4, 0xFE8A, 1, 2, -1, {1, 1}}, // ئ {5, 0xFE8E, -1, 0, -1, {1, 0}}, // آ {6, 0xFE90, 1, 2, -1, {1, 1}}, // ب {92, 0xFB57, 1, 2, -1, {1, 1}}, // پ @@ -86,8 +86,8 @@ const ap_chars_map_t ap_chars_map[] = { {39, 0xFEF0, 0, 0, -1, {1, 0}}, // ى {40, 0xFEF2, 1, 2, -1, {1, 1}}, // ي {170, 0xFBFD, 1, 2, -1, {1, 1}}, // ی - {7, 0xFE94, 1, 2, -1, {1, 0}}, // ة - {206, 0x06F0, 1, 2, -1, {0, 0}}, // ۰ + {7, 0xFE94, -1, 2, -1, {1, 0}}, // ة + {206, 0x06F0, -1, 2, 0, {0, 0}}, // ۰ {207, 0x06F1, 0, 0, 0, {0, 0}}, // ۱ {208, 0x06F2, 0, 0, 0, {0, 0}}, // ۲ {209, 0x06F3, 0, 0, 0, {0, 0}}, // ۳ @@ -106,7 +106,7 @@ const ap_chars_map_t ap_chars_map[] = { /********************** * GLOBAL FUNCTIONS **********************/ -uint32_t _lv_text_ap_calc_bytes_count(const char * txt) +uint32_t lv_text_ap_calc_bytes_count(const char * txt) { uint32_t txt_length = 0; uint32_t chars_cnt = 0; @@ -114,12 +114,12 @@ uint32_t _lv_text_ap_calc_bytes_count(const char * txt) uint32_t i, j; uint32_t ch_enc; - txt_length = _lv_text_get_encoded_length(txt); + txt_length = lv_text_get_encoded_length(txt); i = 0; j = 0; while(i < txt_length) { - ch_enc = _lv_text_encoded_next(txt, &j); + ch_enc = lv_text_encoded_next(txt, &j); current_ap_idx = lv_ap_get_char_index(ch_enc); if(current_ap_idx != LV_UNDEF_ARABIC_PERSIAN_CHARS) @@ -140,7 +140,7 @@ uint32_t _lv_text_ap_calc_bytes_count(const char * txt) return chars_cnt + 1; } -void _lv_text_ap_proc(const char * txt, char * txt_out) +void lv_text_ap_proc(const char * txt, char * txt_out) { uint32_t txt_length = 0; uint32_t index_current, idx_next, idx_previous, i, j; @@ -148,7 +148,7 @@ void _lv_text_ap_proc(const char * txt, char * txt_out) uint32_t * ch_fin; char * txt_out_temp; - txt_length = _lv_text_get_encoded_length(txt); + txt_length = lv_text_get_encoded_length(txt); ch_enc = (uint32_t *)lv_malloc(sizeof(uint32_t) * (txt_length + 1)); ch_fin = (uint32_t *)lv_malloc(sizeof(uint32_t) * (txt_length + 1)); @@ -156,7 +156,7 @@ void _lv_text_ap_proc(const char * txt, char * txt_out) i = 0; j = 0; while(j < txt_length) - ch_enc[j++] = _lv_text_encoded_next(txt, &i); + ch_enc[j++] = lv_text_encoded_next(txt, &i); ch_enc[j] = 0; @@ -185,14 +185,14 @@ void _lv_text_ap_proc(const char * txt, char * txt_out) continue; } - uint8_t conjunction_to_previuse = (i == 0 || + uint8_t conjunction_to_previous = (i == 0 || idx_previous == LV_UNDEF_ARABIC_PERSIAN_CHARS) ? 0 : ap_chars_map[idx_previous].ap_chars_conjunction.conj_to_next; uint8_t conjunction_to_next = ((i == txt_length - 1) || idx_next == LV_UNDEF_ARABIC_PERSIAN_CHARS) ? 0 : ap_chars_map[idx_next].ap_chars_conjunction.conj_to_previous; uint32_t lam_alef = lv_text_lam_alef(index_current, idx_next); if(lam_alef) { - if(conjunction_to_previuse) { + if(conjunction_to_previous) { lam_alef ++; } ch_fin[j] = lam_alef; @@ -202,11 +202,11 @@ void _lv_text_ap_proc(const char * txt, char * txt_out) continue; } - if(conjunction_to_previuse && conjunction_to_next) + if(conjunction_to_previous && conjunction_to_next) ch_fin[j] = ap_chars_map[index_current].char_end_form + ap_chars_map[index_current].char_middle_form_offset; - else if(!conjunction_to_previuse && conjunction_to_next) + else if(!conjunction_to_previous && conjunction_to_next) ch_fin[j] = ap_chars_map[index_current].char_end_form + ap_chars_map[index_current].char_beginning_form_offset; - else if(conjunction_to_previuse && !conjunction_to_next) + else if(conjunction_to_previous && !conjunction_to_next) ch_fin[j] = ap_chars_map[index_current].char_end_form; else ch_fin[j] = ap_chars_map[index_current].char_end_form + ap_chars_map[index_current].char_isolated_form_offset; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.h index df6357fc9..cac7c7121 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include #include "lv_text.h" +#include "lv_types.h" #include "../draw/lv_draw.h" #if LV_USE_ARABIC_PERSIAN_CHARS == 1 @@ -33,8 +33,8 @@ extern "C" { /********************** * GLOBAL PROTOTYPES **********************/ -uint32_t _lv_text_ap_calc_bytes_count(const char * txt); -void _lv_text_ap_proc(const char * txt, char * txt_out); +uint32_t lv_text_ap_calc_bytes_count(const char * txt); +void lv_text_ap_proc(const char * txt, char * txt_out); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h new file mode 100644 index 000000000..858f59383 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h @@ -0,0 +1,273 @@ +/** + * @file lv_text_private.h + * + */ + +#ifndef LV_TEXT_PRIVATE_H +#define LV_TEXT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_text.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the next line of text. Check line length and break chars too. + * @param txt a '\0' terminated string + * @param font pointer to a font + * @param letter_space letter space + * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid + * line breaks + * @param used_width When used_width != NULL, save the width of this line if + * flag == LV_TEXT_FLAG_NONE, otherwise save -1. + * @param flag settings for the text from 'txt_flag_type' enum + * @return the index of the first char of the new line (in byte index not letter index. With UTF-8 + * they are different) + */ +uint32_t lv_text_get_next_line(const char * txt, const lv_font_t * font, int32_t letter_space, + int32_t max_width, int32_t * used_width, lv_text_flag_t flag); + +/** + * Insert a string into another + * @param txt_buf the original text (must be big enough for the result text and NULL terminated) + * @param pos position to insert (0: before the original text, 1: after the first char etc.) + * @param ins_txt text to insert, must be '\0' terminated + */ +void lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt); + +/** + * Delete a part of a string + * @param txt string to modify, must be '\0' terminated and should point to a heap or stack frame, not read-only memory. + * @param pos position where to start the deleting (0: before the first char, 1: after the first + * char etc.) + * @param len number of characters to delete + */ +void lv_text_cut(char * txt, uint32_t pos, uint32_t len); + +/** + * return a new formatted text. Memory will be allocated to store the text. + * @param fmt `printf`-like format + * @param ap items to print + + * @return pointer to the allocated text string. + */ +char * lv_text_set_text_vfmt(const char * fmt, va_list ap) LV_FORMAT_ATTRIBUTE(1, 0); + +/** + * Decode two encoded character from a string. + * @param txt pointer to '\0' terminated string + * @param letter the first decoded Unicode character or 0 on invalid data code + * @param letter_next the second decoded Unicode character or 0 on invalid data code + * @param ofs start index in 'txt' where to start. + * After the call it will point to the next encoded char in 'txt'. + * NULL to use txt[0] as index + */ +void lv_text_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t * ofs); + +/** + * Test if char is break char or not (a text can broken here or not) + * @param letter a letter + * @return false: 'letter' is not break char + */ +static inline bool lv_text_is_break_char(uint32_t letter) +{ + uint8_t i; + bool ret = false; + + /*Compare the letter to TXT_BREAK_CHARS*/ + for(i = 0; LV_TXT_BREAK_CHARS[i] != '\0'; i++) { + if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) { + ret = true; /*If match then it is break char*/ + break; + } + } + + return ret; +} + +/** + * Test if char is break char or not (a text can broken here or not) + * @param letter a letter + * @return false: 'letter' is not break char + */ +static inline bool lv_text_is_a_word(uint32_t letter) +{ + /*Cheap check on invalid letter*/ + if(letter == 0) return false; + + /*CJK Unified Ideographs*/ + if(letter >= 0x4E00 && letter <= 0x9FFF) { + return true; + } + + /*Fullwidth ASCII variants*/ + if(letter >= 0xFF01 && letter <= 0xFF5E) { + return true; + } + + /*CJK symbols and punctuation*/ + if(letter >= 0x3000 && letter <= 0x303F) { + return true; + } + + /*CJK Radicals Supplement*/ + if(letter >= 0x2E80 && letter <= 0x2EFF) { + return true; + } + + /*CJK Strokes*/ + if(letter >= 0x31C0 && letter <= 0x31EF) { + return true; + } + + /*Hiragana and Katakana*/ + if(letter >= 0x3040 && letter <= 0x30FF) { + return true; + } + + /*Chinese Vertical Forms*/ + if(letter >= 0xFE10 && letter <= 0xFE1F) { + return true; + } + + /*CJK Compatibility Forms*/ + if(letter >= 0xFE30 && letter <= 0xFE4F) { + return true; + } + + return false; +} + +/** + * Test if character can be treated as marker, and don't need to be rendered. + * Note, this is not a full list. Add your findings to the list. + * + * @param letter a letter + * @return true if so + */ +static inline bool lv_text_is_marker(uint32_t letter) +{ + if(letter < 0x20) return true; + + /*U+061C ARABIC LETTER MARK, see https://www.compart.com/en/unicode/block/U+0600*/ + if(letter == 0x061C) return true; + + /*U+115F HANGUL CHOSEONG FILLER, See https://www.compart.com/en/unicode/block/U+1100*/ + if(letter == 0x115F) return true; + /*U+1160 HANGUL JUNGSEONG FILLER*/ + if(letter == 0x1160) return true; + + /*See https://www.compart.com/en/unicode/block/U+1800*/ + if(letter >= 0x180B && letter <= 0x180E) return true; + + /*See https://www.compart.com/en/unicode/block/U+2000*/ + if(letter >= 0x200B && letter <= 0x200F) return true; + if(letter >= 0x2028 && letter <= 0x202F) return true; + if(letter >= 0x205F && letter <= 0x206F) return true; + + /*U+FEFF ZERO WIDTH NO-BREAK SPACE, see https://www.compart.com/en/unicode/block/U+FE70*/ + if(letter == 0xFEFF) return true; + + if(letter == 0xF8FF) return true; /*LV_SYMBOL_DUMMY*/ + + return false; +} + +/*************************************************************** + * GLOBAL FUNCTION POINTERS FOR CHARACTER ENCODING INTERFACE + ***************************************************************/ + +/** + * Give the size of an encoded character + * @param txt pointer to a character in a string + * @return length of the encoded character (1,2,3 ...). O in invalid + */ +extern uint8_t (*const lv_text_encoded_size)(const char * txt); + +/** + * Convert a Unicode letter to encoded + * @param letter_uni a Unicode letter + * @return Encoded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ü') + */ +extern uint32_t (*const lv_text_unicode_to_encoded)(uint32_t letter_uni); + +/** + * Convert a wide character, e.g. 'Á' little endian to be compatible with the encoded format. + * @param c a wide character + * @return `c` in the encoded format + */ +extern uint32_t (*const lv_text_encoded_conv_wc)(uint32_t c); + +/** + * Decode the next encoded character from a string. + * @param txt pointer to '\0' terminated string + * @param i_start start index in 'txt' where to start. + * After the call it will point to the next encoded char in 'txt'. + * NULL to use txt[0] as index + * @return the decoded Unicode character or 0 on invalid data code + */ +extern uint32_t (*const lv_text_encoded_next)(const char * txt, uint32_t * i_start); + +/** + * Get the previous encoded character form a string. + * + * @param txt pointer to '\0' terminated string + * @param i_start index in 'txt' where to start. After the call it will point to the previous + * encoded char in 'txt'. + * + * @return the decoded Unicode character or 0 on invalid data + */ +extern uint32_t (*const lv_text_encoded_prev)(const char * txt, uint32_t * i_start); + +/** + * Convert a letter index (in the encoded text) to byte index. + * E.g. in UTF-8 "AÁRT" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long + * @param txt a '\0' terminated UTF-8 string + * @param utf8_id character index + * @return byte index of the 'enc_id'th letter + */ +extern uint32_t (*const lv_text_encoded_get_byte_id)(const char * txt, uint32_t utf8_id); + +/** + * Convert a byte index (in an encoded text) to character index. + * E.g. in UTF-8 "AÁRT" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long + * @param txt a '\0' terminated UTF-8 string + * @param byte_id byte index + * @return character index of the letter at 'byte_id'th position + */ +extern uint32_t (*const lv_text_encoded_get_char_id)(const char * txt, uint32_t byte_id); + +/** + * Get the number of characters (and NOT bytes) in a string. + * E.g. in UTF-8 "ÁBC" is 3 characters (but 4 bytes) + * @param txt a '\0' terminated char string + * @return number of characters + */ +extern uint32_t (*const lv_text_get_encoded_length)(const char * txt); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c index 5537e5910..959ce53b9 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c @@ -5,7 +5,7 @@ /********************* * INCLUDES *********************/ -#include "lv_timer.h" +#include "lv_timer_private.h" #include "../core/lv_global.h" #include "../tick/lv_tick.h" #include "../stdlib/lv_mem.h" @@ -52,9 +52,9 @@ static void lv_timer_handler_resume(void); * GLOBAL FUNCTIONS **********************/ -void _lv_timer_core_init(void) +void lv_timer_core_init(void) { - _lv_ll_init(timer_ll_p, sizeof(lv_timer_t)); + lv_ll_init(timer_ll_p, sizeof(lv_timer_t)); /*Initially enable the lv_timer handling*/ lv_timer_enable(true); @@ -78,6 +78,8 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) } LV_PROFILER_BEGIN; + lv_lock(); + uint32_t handler_start = lv_tick_get(); if(handler_start == 0) { @@ -96,11 +98,11 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) state_p->timer_deleted = false; state_p->timer_created = false; - timer_active = _lv_ll_get_head(timer_head); + timer_active = lv_ll_get_head(timer_head); while(timer_active) { /*The timer might be deleted if it runs only once ('repeat_count = 1') *So get next element until the current is surely valid*/ - next = _lv_ll_get_next(timer_head, timer_active); + next = lv_ll_get_next(timer_head, timer_active); if(lv_timer_exec(timer_active)) { /*If a timer was created or deleted then this or the next item might be corrupted*/ @@ -115,7 +117,7 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) } while(timer_active); uint32_t time_until_next = LV_NO_TIMER_READY; - next = _lv_ll_get_head(timer_head); + next = lv_ll_get_head(timer_head); while(next) { if(!next->paused) { uint32_t delay = lv_timer_time_remaining(next); @@ -123,7 +125,7 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) time_until_next = delay; } - next = _lv_ll_get_next(timer_head, next); /*Find the next timer*/ + next = lv_ll_get_next(timer_head, next); /*Find the next timer*/ } state_p->busy_time += lv_tick_elaps(handler_start); @@ -139,7 +141,10 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) state_p->already_running = false; /*Release the mutex*/ LV_TRACE_TIMER("finished (%" LV_PRIu32 " ms until the next timer call)", time_until_next); + lv_unlock(); + LV_PROFILER_END; + return time_until_next; } @@ -162,7 +167,7 @@ lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * us { lv_timer_t * new_timer = NULL; - new_timer = _lv_ll_ins_head(timer_ll_p); + new_timer = lv_ll_ins_head(timer_ll_p); LV_ASSERT_MALLOC(new_timer); if(new_timer == NULL) return NULL; @@ -189,7 +194,7 @@ void lv_timer_set_cb(lv_timer_t * timer, lv_timer_cb_t timer_cb) void lv_timer_delete(lv_timer_t * timer) { - _lv_ll_remove(timer_ll_p, timer); + lv_ll_remove(timer_ll_p, timer); state.timer_deleted = true; lv_free(timer); @@ -251,11 +256,11 @@ void lv_timer_enable(bool en) if(en) lv_timer_handler_resume(); } -void _lv_timer_core_deinit(void) +void lv_timer_core_deinit(void) { lv_timer_enable(false); - _lv_ll_clear(timer_ll_p); + lv_ll_clear(timer_ll_p); } uint32_t lv_timer_get_idle(void) @@ -270,8 +275,29 @@ uint32_t lv_timer_get_time_until_next(void) lv_timer_t * lv_timer_get_next(lv_timer_t * timer) { - if(timer == NULL) return _lv_ll_get_head(timer_ll_p); - else return _lv_ll_get_next(timer_ll_p, timer); + if(timer == NULL) return lv_ll_get_head(timer_ll_p); + else return lv_ll_get_next(timer_ll_p, timer); +} + +LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler_run_in_period(uint32_t period) +{ + static uint32_t last_tick = 0; + + if(lv_tick_elaps(last_tick) >= period) { + last_tick = lv_tick_get(); + return lv_timer_handler(); + } + return 1; +} + +void * lv_timer_get_user_data(lv_timer_t * timer) +{ + return timer->user_data; +} + +bool lv_timer_get_paused(lv_timer_t * timer) +{ + return timer->paused; } /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h index 06576a853..be2500333 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h @@ -17,9 +17,6 @@ extern "C" { #include "lv_types.h" #include "lv_ll.h" -#include -#include - /********************* * DEFINES *********************/ @@ -43,52 +40,10 @@ typedef void (*lv_timer_cb_t)(lv_timer_t *); */ typedef void (*lv_timer_handler_resume_cb_t)(void * data); -/** - * Descriptor of a lv_timer - */ -struct _lv_timer_t { - uint32_t period; /**< How often the timer should run*/ - uint32_t last_run; /**< Last time the timer ran*/ - lv_timer_cb_t timer_cb; /**< Timer function*/ - void * user_data; /**< Custom user data*/ - int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times*/ - uint32_t paused : 1; - uint32_t auto_delete : 1; -}; - -typedef struct { - lv_ll_t timer_ll; /*Linked list to store the lv_timers*/ - - bool lv_timer_run; - uint8_t idle_last; - bool timer_deleted; - bool timer_created; - uint32_t timer_time_until_next; - - bool already_running; - uint32_t periodic_last_tick; - uint32_t busy_time; - uint32_t idle_period_start; - uint32_t run_cnt; - - lv_timer_handler_resume_cb_t resume_cb; - void * resume_data; -} lv_timer_state_t; - /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Init the lv_timer module - */ -void _lv_timer_core_init(void); - -/** - * Deinit the lv_timer module - */ -void _lv_timer_core_deinit(void); - //! @cond Doxygen_Suppress /** @@ -106,16 +61,7 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void); * @param period the period for running lv_timer_handler() * @return the time after which it must be called again */ -static inline LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler_run_in_period(uint32_t period) -{ - static uint32_t last_tick = 0; - - if(lv_tick_elaps(last_tick) >= period) { - last_tick = lv_tick_get(); - return lv_timer_handler(); - } - return 1; -} +LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler_run_in_period(uint32_t period); /** * Call it in the super-loop of main() or threads. It will automatically call lv_timer_handler() at the right time. @@ -244,20 +190,14 @@ lv_timer_t * lv_timer_get_next(lv_timer_t * timer); * @param timer pointer to the lv_timer * @return pointer to the user_data */ -static inline void * lv_timer_get_user_data(lv_timer_t * timer) -{ - return timer->user_data; -} +void * lv_timer_get_user_data(lv_timer_t * timer); /** * Get the pause state of a timer * @param timer pointer to a lv_timer * @return true: timer is paused; false: timer is running */ -static inline bool lv_timer_get_paused(lv_timer_t * timer) -{ - return timer->paused; -} +bool lv_timer_get_paused(lv_timer_t * timer); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h new file mode 100644 index 000000000..b7f42b0a1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h @@ -0,0 +1,81 @@ +/** + * @file lv_timer_private.h + * + */ + +#ifndef LV_TIMER_PRIVATE_H +#define LV_TIMER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_timer.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Descriptor of a lv_timer + */ +struct lv_timer_t { + uint32_t period; /**< How often the timer should run */ + uint32_t last_run; /**< Last time the timer ran */ + lv_timer_cb_t timer_cb; /**< Timer function */ + void * user_data; /**< Custom user data */ + int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */ + uint32_t paused : 1; + uint32_t auto_delete : 1; +}; + +typedef struct { + lv_ll_t timer_ll; /**< Linked list to store the lv_timers */ + + bool lv_timer_run; + uint8_t idle_last; + bool timer_deleted; + bool timer_created; + uint32_t timer_time_until_next; + + bool already_running; + uint32_t periodic_last_tick; + uint32_t busy_time; + uint32_t idle_period_start; + uint32_t run_cnt; + + lv_timer_handler_resume_cb_t resume_cb; + void * resume_data; +} lv_timer_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Init the lv_timer module + */ +void lv_timer_core_init(void); + +/** + * Deinit the lv_timer module + */ +void lv_timer_core_deinit(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TIMER_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h index 1b992c150..4e02c1366 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h @@ -16,7 +16,12 @@ extern "C" { #include "../lv_conf_internal.h" #ifndef __ASSEMBLY__ -#include +#include LV_STDINT_INCLUDE +#include LV_STDDEF_INCLUDE +#include LV_STDBOOL_INCLUDE +#include LV_INTTYPES_INCLUDE +#include LV_LIMITS_INCLUDE +#include LV_STDARG_INCLUDE #endif /********************* @@ -46,17 +51,11 @@ extern "C" { /** * LVGL error codes. */ -enum _lv_result_t { +typedef enum { LV_RESULT_INVALID = 0, /*Typically indicates that the object is deleted (become invalid) in the action function or an operation was failed*/ LV_RESULT_OK, /*The object is valid (no deleted) after the action*/ -}; - -#ifdef DOXYGEN -typedef _lv_result_t lv_result_t; -#else -typedef uint8_t lv_result_t; -#endif /*DOXYGEN*/ +} lv_result_t; #if defined(__cplusplus) || __STDC_VERSION__ >= 199901L /*If c99 or newer, use the definition of uintptr_t directly from */ @@ -87,61 +86,261 @@ typedef int32_t lv_value_precise_t; * They are defined here to avoid circular dependencies. */ -struct _lv_obj_t; -typedef struct _lv_obj_t lv_obj_t; +typedef struct lv_obj_t lv_obj_t; -#ifdef DOXYGEN -typedef _lv_state_t lv_state_t; -typedef _lv_part_t lv_part_t; -typedef _lv_obj_flag_t lv_obj_flag_t; -#else typedef uint16_t lv_state_t; typedef uint32_t lv_part_t; -typedef uint32_t lv_obj_flag_t; -#endif /*DOXYGEN*/ -struct _lv_obj_class_t; -typedef struct _lv_obj_class_t lv_obj_class_t; +typedef uint8_t lv_opa_t; -struct _lv_group_t; -typedef struct _lv_group_t lv_group_t; +typedef uint8_t lv_style_prop_t; -#ifdef DOXYGEN -typedef _lv_key_t lv_key_t; -#else -typedef uint8_t lv_key_t; -#endif /*DOXYGEN*/ +typedef struct lv_obj_class_t lv_obj_class_t; -struct _lv_display_t; -typedef struct _lv_display_t lv_display_t; +typedef struct lv_group_t lv_group_t; -struct _lv_layer_t; -typedef struct _lv_layer_t lv_layer_t; -struct _lv_draw_unit_t; -typedef struct _lv_draw_unit_t lv_draw_unit_t; -struct _lv_draw_task_t; -typedef struct _lv_draw_task_t lv_draw_task_t; +typedef struct lv_display_t lv_display_t; -struct _lv_indev_t; -typedef struct _lv_indev_t lv_indev_t; +typedef struct lv_layer_t lv_layer_t; +typedef struct lv_draw_unit_t lv_draw_unit_t; +typedef struct lv_draw_task_t lv_draw_task_t; -struct _lv_event_t; -typedef struct _lv_event_t lv_event_t; +typedef struct lv_indev_t lv_indev_t; -struct _lv_timer_t; -typedef struct _lv_timer_t lv_timer_t; +typedef struct lv_event_t lv_event_t; -struct _lv_theme_t; -typedef struct _lv_theme_t lv_theme_t; +typedef struct lv_timer_t lv_timer_t; -struct _lv_anim_t; -typedef struct _lv_anim_t lv_anim_t; +typedef struct lv_theme_t lv_theme_t; -struct _lv_font_t; -typedef struct _lv_font_t lv_font_t; +typedef struct lv_anim_t lv_anim_t; -struct _lv_image_decoder_t; -typedef struct _lv_image_decoder_t lv_image_decoder_t; +typedef struct lv_font_t lv_font_t; + +typedef struct lv_image_decoder_t lv_image_decoder_t; + +typedef struct lv_image_decoder_dsc_t lv_image_decoder_dsc_t; + +typedef struct lv_fragment_t lv_fragment_t; +typedef struct lv_fragment_class_t lv_fragment_class_t; +typedef struct lv_fragment_managed_states_t lv_fragment_managed_states_t; + +typedef struct lv_profiler_builtin_config_t lv_profiler_builtin_config_t; + +typedef struct lv_rb_node_t lv_rb_node_t; + +typedef struct lv_rb_t lv_rb_t; + +typedef struct lv_color_filter_dsc_t lv_color_filter_dsc_t; + +typedef struct lv_event_dsc_t lv_event_dsc_t; + +typedef struct lv_fs_file_cache_t lv_fs_file_cache_t; + +typedef struct lv_fs_path_ex_t lv_fs_path_ex_t; + +typedef struct lv_fs_dir_t lv_fs_dir_t; + +typedef struct lv_image_decoder_args_t lv_image_decoder_args_t; + +typedef struct lv_image_cache_data_t lv_image_cache_data_t; + +typedef struct lv_image_header_cache_data_t lv_image_header_cache_data_t; + +typedef struct lv_draw_mask_t lv_draw_mask_t; + +typedef struct lv_grad_t lv_grad_t; + +typedef struct lv_draw_label_hint_t lv_draw_label_hint_t; + +typedef struct lv_draw_glyph_dsc_t lv_draw_glyph_dsc_t; + +typedef struct lv_draw_image_sup_t lv_draw_image_sup_t; + +typedef struct lv_draw_mask_rect_dsc_t lv_draw_mask_rect_dsc_t; + +typedef struct lv_obj_style_t lv_obj_style_t; + +typedef struct lv_obj_style_transition_dsc_t lv_obj_style_transition_dsc_t; + +typedef struct lv_hit_test_info_t lv_hit_test_info_t; + +typedef struct lv_cover_check_info_t lv_cover_check_info_t; + +typedef struct lv_obj_spec_attr_t lv_obj_spec_attr_t; + +typedef struct lv_image_t lv_image_t; + +typedef struct lv_animimg_t lv_animimg_t; + +typedef struct lv_arc_t lv_arc_t; + +typedef struct lv_label_t lv_label_t; + +typedef struct lv_bar_anim_t lv_bar_anim_t; + +typedef struct lv_bar_t lv_bar_t; + +typedef struct lv_button_t lv_button_t; + +typedef struct lv_buttonmatrix_t lv_buttonmatrix_t; + +typedef struct lv_calendar_t lv_calendar_t; + +typedef struct lv_calendar_chinese_t lv_calendar_chinese_t; + +typedef struct lv_canvas_t lv_canvas_t; + +typedef struct lv_chart_series_t lv_chart_series_t; + +typedef struct lv_chart_cursor_t lv_chart_cursor_t; + +typedef struct lv_chart_t lv_chart_t; + +typedef struct lv_checkbox_t lv_checkbox_t; + +typedef struct lv_dropdown_t lv_dropdown_t; + +typedef struct lv_dropdown_list_t lv_dropdown_list_t; + +typedef struct lv_imagebutton_src_info_t lv_imagebutton_src_info_t; + +typedef struct lv_imagebutton_t lv_imagebutton_t; + +typedef struct lv_keyboard_t lv_keyboard_t; + +typedef struct lv_led_t lv_led_t; + +typedef struct lv_line_t lv_line_t; + +typedef struct lv_menu_load_page_event_data_t lv_menu_load_page_event_data_t; + +typedef struct lv_menu_history_t lv_menu_history_t; + +typedef struct lv_menu_t lv_menu_t; + +typedef struct lv_menu_page_t lv_menu_page_t; + +typedef struct lv_msgbox_t lv_msgbox_t; + +typedef struct lv_roller_t lv_roller_t; + +typedef struct lv_scale_section_t lv_scale_section_t; + +typedef struct lv_scale_t lv_scale_t; + +typedef struct lv_slider_t lv_slider_t; + +typedef struct lv_span_t lv_span_t; + +typedef struct lv_spangroup_t lv_spangroup_t; + +typedef struct lv_textarea_t lv_textarea_t; + +typedef struct lv_spinbox_t lv_spinbox_t; + +typedef struct lv_switch_t lv_switch_t; + +typedef struct lv_table_cell_t lv_table_cell_t; + +typedef struct lv_table_t lv_table_t; + +typedef struct lv_tabview_t lv_tabview_t; + +typedef struct lv_tileview_t lv_tileview_t; + +typedef struct lv_tileview_tile_t lv_tileview_tile_t; + +typedef struct lv_win_t lv_win_t; + +typedef struct lv_observer_t lv_observer_t; + +typedef struct lv_monkey_config_t lv_monkey_config_t; + +typedef struct lv_ime_pinyin_t lv_ime_pinyin_t; + +typedef struct lv_file_explorer_t lv_file_explorer_t; + +typedef struct lv_barcode_t lv_barcode_t; + +typedef struct lv_gif_t lv_gif_t; + +typedef struct lv_qrcode_t lv_qrcode_t; + +typedef struct lv_freetype_outline_vector_t lv_freetype_outline_vector_t; + +typedef struct lv_freetype_outline_event_param_t lv_freetype_outline_event_param_t; + +typedef struct lv_fpoint_t lv_fpoint_t; + +typedef struct lv_matrix_t lv_matrix_t; + +typedef struct lv_vector_path_t lv_vector_path_t; + +typedef struct lv_vector_gradient_t lv_vector_gradient_t; + +typedef struct lv_vector_fill_dsc_t lv_vector_fill_dsc_t; + +typedef struct lv_vector_stroke_dsc_t lv_vector_stroke_dsc_t; + +typedef struct lv_vector_draw_dsc_t lv_vector_draw_dsc_t; + +typedef struct lv_draw_vector_task_dsc_t lv_draw_vector_task_dsc_t; + +typedef struct lv_vector_dsc_t lv_vector_dsc_t; + +typedef struct lv_xkb_t lv_xkb_t; + +typedef struct lv_libinput_event_t lv_libinput_event_t; + +typedef struct lv_libinput_t lv_libinput_t; + +typedef struct lv_draw_sw_unit_t lv_draw_sw_unit_t; + +typedef struct lv_draw_sw_mask_common_dsc_t lv_draw_sw_mask_common_dsc_t; + +typedef struct lv_draw_sw_mask_line_param_t lv_draw_sw_mask_line_param_t; + +typedef struct lv_draw_sw_mask_angle_param_t lv_draw_sw_mask_angle_param_t; + +typedef struct lv_draw_sw_mask_radius_param_t lv_draw_sw_mask_radius_param_t; + +typedef struct lv_draw_sw_mask_fade_param_t lv_draw_sw_mask_fade_param_t; + +typedef struct lv_draw_sw_mask_map_param_t lv_draw_sw_mask_map_param_t; + +typedef struct lv_draw_sw_blend_dsc_t lv_draw_sw_blend_dsc_t; + +typedef struct lv_draw_sw_blend_fill_dsc_t lv_draw_sw_blend_fill_dsc_t; + +typedef struct lv_draw_sw_blend_image_dsc_t lv_draw_sw_blend_image_dsc_t; + +typedef struct lv_draw_buf_handlers_t lv_draw_buf_handlers_t; + +typedef struct lv_rlottie_t lv_rlottie_t; + +typedef struct lv_ffmpeg_player_t lv_ffmpeg_player_t; + +typedef struct lv_glfw_window_t lv_glfw_window_t; +typedef struct lv_glfw_texture_t lv_glfw_texture_t; + +typedef uint32_t lv_prop_id_t; + +typedef struct lv_draw_buf_t lv_draw_buf_t; + +#if LV_USE_OBJ_PROPERTY +typedef struct lv_property_name_t lv_property_name_t; +#endif + +#if LV_USE_SYSMON + +typedef struct lv_sysmon_backend_data_t lv_sysmon_backend_data_t; + +#if LV_USE_PERF_MONITOR +typedef struct lv_sysmon_perf_info_t lv_sysmon_perf_info_t; +#endif /*LV_USE_PERF_MONITOR*/ + +#endif /*LV_USE_SYSMON*/ #endif /*__ASSEMBLY__*/ @@ -157,15 +356,17 @@ typedef struct _lv_image_decoder_t lv_image_decoder_t; #define _LV_CONCAT(x, y) x ## y #define LV_CONCAT(x, y) _LV_CONCAT(x, y) +#undef _LV_CONCAT #define _LV_CONCAT3(x, y, z) x ## y ## z #define LV_CONCAT3(x, y, z) _LV_CONCAT3(x, y, z) +#undef _LV_CONCAT3 #if defined(PYCPARSER) || defined(__CC_ARM) #define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) #elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4) #define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) __attribute__((format(gnu_printf, fmtstr, vararg))) -#elif (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)) +#elif (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || defined(__IAR_SYSTEMS_ICC__)) #define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) __attribute__((format(printf, fmtstr, vararg))) #else #define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c index 2eb02afc7..868692170 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c @@ -6,10 +6,9 @@ /********************* * INCLUDES *********************/ -#include - #include "lv_utils.h" #include "lv_fs.h" +#include "lv_types.h" #include "cache/lv_image_cache.h" /********************* @@ -36,8 +35,8 @@ * GLOBAL FUNCTIONS **********************/ -void * _lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size, - int32_t (*cmp)(const void * pRef, const void * pElement)) +void * lv_utils_bsearch(const void * key, const void * base, size_t n, size_t size, + int (*cmp)(const void * pRef, const void * pElement)) { const char * middle; int32_t c; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h index 8422cf8d7..7a8d61014 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h @@ -17,8 +17,6 @@ extern "C" { #include "lv_types.h" #include "../draw/lv_draw_buf.h" -#include - /********************* * DEFINES *********************/ @@ -37,25 +35,25 @@ extern "C" { * argument (the search key) is less that it's second (a table entry), * zero if equal, and positive if greater. * - * @note Items in the array must be in ascending order. + * @note Items in the array must be in ascending order. * * @param key Pointer to item being searched for * @param base Pointer to first element to search * @param n Number of elements * @param size Size of each element - * @param cmp Pointer to comparison function (see #unicode_list_compare as a comparison function - * example) + * @param cmp Pointer to comparison function (see unicode_list_compare() + * as a comparison function example) * * @return a pointer to a matching item, or NULL if none exists. */ -void * _lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size, - int32_t (*cmp)(const void * pRef, const void * pElement)); +void * lv_utils_bsearch(const void * key, const void * base, size_t n, size_t size, + int (*cmp)(const void * pRef, const void * pElement)); /** * Save a draw buf to a file * @param draw_buf pointer to a draw buffer * @param path path to the file to save - * @return LV_RES_OK: success; LV_RES_INV: error + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: error */ lv_result_t lv_draw_buf_save_to_file(const lv_draw_buf_t * draw_buf, const char * path); diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_cmsis_rtos2.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_cmsis_rtos2.c index 028520f18..ed414c8da 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_cmsis_rtos2.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_cmsis_rtos2.c @@ -172,6 +172,11 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + return lv_thread_sync_signal(sync); +} + lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) { osStatus_t status = osEventFlagsDelete(*sync); diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c index 0f7f678bc..1c81a8e05 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c @@ -13,7 +13,6 @@ * INCLUDES *********************/ #include "lv_os.h" - #if LV_USE_OS == LV_OS_FREERTOS #if (ESP_PLATFORM) @@ -22,7 +21,10 @@ #include "atomic.h" #endif +#include "../tick/lv_tick.h" #include "../misc/lv_log.h" +#include "../core/lv_global.h" + /********************* * DEFINES *********************/ @@ -32,6 +34,8 @@ #define pcTASK_NAME "lvglDraw" #endif +#define globals LV_GLOBAL_DEFAULT() + /********************** * TYPEDEFS **********************/ @@ -46,11 +50,11 @@ static void prvMutexInit(lv_mutex_t * pxMutex); static void prvCheckMutexInit(lv_mutex_t * pxMutex); -#if !USE_FREERTOS_TASK_NOTIFY static void prvCondInit(lv_thread_sync_t * pxCond); static void prvCheckCondInit(lv_thread_sync_t * pxCond); +#if !USE_FREERTOS_TASK_NOTIFY static void prvTestAndDecrement(lv_thread_sync_t * pxCond, uint32_t ulLocalWaitingThreads); #endif @@ -83,7 +87,7 @@ lv_result_t lv_thread_init(lv_thread_t * pxThread, lv_thread_prio_t xSchedPriori void (*pvStartRoutine)(void *), size_t usStackSize, void * xAttr) { - pxThread->xTaskArg = xAttr; + pxThread->pTaskArg = xAttr; pxThread->pvStartRoutine = pvStartRoutine; BaseType_t xTaskCreateStatus = xTaskCreate( @@ -178,13 +182,8 @@ lv_result_t lv_mutex_delete(lv_mutex_t * pxMutex) lv_result_t lv_thread_sync_init(lv_thread_sync_t * pxCond) { -#if USE_FREERTOS_TASK_NOTIFY - /* Store the handle of the calling task. */ - pxCond->xTaskToNotify = xTaskGetCurrentTaskHandle(); -#else /* If the cond is uninitialized, perform initialization. */ prvCheckCondInit(pxCond); -#endif return LV_RESULT_OK; } @@ -193,17 +192,30 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * pxCond) { lv_result_t lvRes = LV_RESULT_OK; -#if USE_FREERTOS_TASK_NOTIFY - LV_UNUSED(pxCond); - - /* Wait for other task to notify this task. */ - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); -#else - uint32_t ulLocalWaitingThreads; - /* If the cond is uninitialized, perform initialization. */ prvCheckCondInit(pxCond); +#if USE_FREERTOS_TASK_NOTIFY + TaskHandle_t current_task_handle = xTaskGetCurrentTaskHandle(); + + _enter_critical(); + BaseType_t signal_sent = pxCond->xSyncSignal; + pxCond->xSyncSignal = pdFALSE; + if(signal_sent == pdFALSE) { + /* The signal hasn't been sent yet. Tell the sender to notify this task */ + pxCond->xTaskToNotify = current_task_handle; + } + /* If we have a signal from the other task, we should not ask to be notified */ + _exit_critical(); + + if(signal_sent == pdFALSE) { + /* Wait for other task to notify this task. */ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + } + /* If the signal was received, no wait needs to be done */ +#else + uint32_t ulLocalWaitingThreads; + /* Acquire the mutex. */ xSemaphoreTake(pxCond->xSyncMutex, portMAX_DELAY); @@ -260,13 +272,26 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * pxCond) lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond) { -#if USE_FREERTOS_TASK_NOTIFY - /* Send a notification to the task waiting. */ - xTaskNotifyGive(pxCond->xTaskToNotify); -#else /* If the cond is uninitialized, perform initialization. */ prvCheckCondInit(pxCond); +#if USE_FREERTOS_TASK_NOTIFY + _enter_critical(); + TaskHandle_t task_to_notify = pxCond->xTaskToNotify; + pxCond->xTaskToNotify = NULL; + if(task_to_notify == NULL) { + /* No task waiting to be notified. Send this signal for later */ + pxCond->xSyncSignal = pdTRUE; + } + /* If a task is already waiting, there is no need to set the sync signal */ + _exit_critical(); + + if(task_to_notify != NULL) { + /* There is a task waiting. Send a notification to it */ + xTaskNotifyGive(task_to_notify); + } + /* If there was no task waiting to be notified, we sent a signal for it to see later. */ +#else /* Acquire the mutex. */ xSemaphoreTake(pxCond->xSyncMutex, portMAX_DELAY); @@ -304,20 +329,94 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond) lv_result_t lv_thread_sync_delete(lv_thread_sync_t * pxCond) { -#if USE_FREERTOS_TASK_NOTIFY - LV_UNUSED(pxCond); -#else +#if !USE_FREERTOS_TASK_NOTIFY /* Cleanup all resources used by the cond. */ vSemaphoreDelete(pxCond->xCondWaitSemaphore); vSemaphoreDelete(pxCond->xSyncMutex); pxCond->ulWaitingThreads = 0; pxCond->xSyncSignal = pdFALSE; +#endif pxCond->xIsInitialized = pdFALSE; + + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + /* If the cond is uninitialized, perform initialization. */ + prvCheckCondInit(pxCond); + +#if USE_FREERTOS_TASK_NOTIFY + _enter_critical(); + TaskHandle_t task_to_notify = pxCond->xTaskToNotify; + pxCond->xTaskToNotify = NULL; + if(task_to_notify == NULL) { + /* No task waiting to be notified. Send this signal for later */ + pxCond->xSyncSignal = pdTRUE; + } + /* If a task is already waiting, there is no need to set the sync signal */ + _exit_critical(); + + if(task_to_notify != NULL) { + /* There is a task waiting. Send a notification to it */ + vTaskNotifyGiveFromISR(task_to_notify, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + /* If there was no task waiting to be notified, we sent a signal for it to see later. */ +#else + /* Enter critical section to prevent preemption. */ + _enter_critical(); + + pxCond->xSyncSignal = pdTRUE; + BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE; + + /* Unblock all. */ + for(uint32_t i = 0; i < pxCond->ulWaitingThreads; i++) { + xSemaphoreGiveFromISR(pxCond->xCondWaitSemaphore, &xAnyHigherPriorityTaskWoken); + xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken; + } + + _exit_critical(); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); #endif return LV_RESULT_OK; } + +void lv_freertos_task_switch_in(const char * name) +{ + if(lv_strcmp(name, "IDLE")) globals->freertos_idle_task_running = false; + else globals->freertos_idle_task_running = true; + + globals->freertos_task_switch_timestamp = lv_tick_get(); +} + +void lv_freertos_task_switch_out(void) +{ + uint32_t elaps = lv_tick_elaps(globals->freertos_task_switch_timestamp); + if(globals->freertos_idle_task_running) globals->freertos_idle_time_sum += elaps; + else globals->freertos_non_idle_time_sum += elaps; +} + +uint32_t lv_os_get_idle_percent(void) +{ + if(globals->freertos_non_idle_time_sum + globals->freertos_idle_time_sum == 0) { + LV_LOG_WARN("Not enough time elapsed to provide idle percentage"); + return 0; + } + + uint32_t pct = (globals->freertos_idle_time_sum * 100) / (globals->freertos_idle_time_sum + + globals->freertos_non_idle_time_sum); + + globals->freertos_non_idle_time_sum = 0; + globals->freertos_idle_time_sum = 0; + + return pct; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -327,14 +426,14 @@ static void prvRunThread(void * pxArg) lv_thread_t * pxThread = (lv_thread_t *)pxArg; /* Run the thread routine. */ - pxThread->pvStartRoutine((void *)pxThread->xTaskArg); + pxThread->pvStartRoutine((void *)pxThread->pTaskArg); vTaskDelete(NULL); } static void prvMutexInit(lv_mutex_t * pxMutex) { - pxMutex->xMutex = xSemaphoreCreateMutex(); + pxMutex->xMutex = xSemaphoreCreateRecursiveMutex(); /* Ensure that the FreeRTOS mutex was successfully created. */ if(pxMutex->xMutex == NULL) { @@ -366,9 +465,14 @@ static void prvCheckMutexInit(lv_mutex_t * pxMutex) } } -#if !USE_FREERTOS_TASK_NOTIFY static void prvCondInit(lv_thread_sync_t * pxCond) { + pxCond->xIsInitialized = pdTRUE; + pxCond->xSyncSignal = pdFALSE; + +#if USE_FREERTOS_TASK_NOTIFY + pxCond->xTaskToNotify = NULL; +#else pxCond->xCondWaitSemaphore = xSemaphoreCreateCounting(ulMAX_COUNT, 0U); /* Ensure that the FreeRTOS semaphore was successfully created. */ @@ -389,14 +493,11 @@ static void prvCondInit(lv_thread_sync_t * pxCond) /* Condition variable successfully created. */ pxCond->ulWaitingThreads = 0; - pxCond->xSyncSignal = pdFALSE; - pxCond->xIsInitialized = pdTRUE; +#endif } static void prvCheckCondInit(lv_thread_sync_t * pxCond) { - BaseType_t xSemCreateStatus = pdTRUE; - /* Check if the condition variable needs to be initialized. */ if(pxCond->xIsInitialized == pdFALSE) { /* Cond initialization must be in a critical section to prevent two @@ -415,6 +516,7 @@ static void prvCheckCondInit(lv_thread_sync_t * pxCond) } } +#if !USE_FREERTOS_TASK_NOTIFY static void prvTestAndDecrement(lv_thread_sync_t * pxCond, uint32_t ulLocalWaitingThreads) { diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h index 093500611..2e2384d37 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h @@ -51,7 +51,7 @@ extern "C" { typedef struct { void (*pvStartRoutine)(void *); /**< Application thread function. */ - void * xTaskArg; /**< Arguments for application thread function. */ + void * pTaskArg; /**< Arguments for application thread function. */ TaskHandle_t xTaskHandle; /**< FreeRTOS task handle. */ } lv_thread_t; @@ -61,15 +61,15 @@ typedef struct { } lv_mutex_t; typedef struct { -#if USE_FREERTOS_TASK_NOTIFY - TaskHandle_t xTaskToNotify; -#else BaseType_t xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */ + BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */ +#if USE_FREERTOS_TASK_NOTIFY + TaskHandle_t xTaskToNotify; /**< The task waiting to be signalled. NULL if nothing is waiting. */ +#else SemaphoreHandle_t xCondWaitSemaphore; /**< Threads block on this semaphore in lv_thread_sync_wait. */ uint32_t ulWaitingThreads; /**< The number of threads currently waiting on this condition variable. */ SemaphoreHandle_t xSyncMutex; /**< Threads take this mutex before accessing the condition variable. */ - BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */ #endif } lv_thread_sync_t; @@ -77,6 +77,29 @@ typedef struct { * GLOBAL PROTOTYPES **********************/ +/** + * Set it for `traceTASK_SWITCHED_IN()` as + * `lv_freertos_task_switch_in(pxCurrentTCB->pcTaskName)` + * to save the start time stamp of a task + * @param name the name of the which is switched in + */ +void lv_freertos_task_switch_in(const char * name); + +/** + * Set it for `traceTASK_SWITCHED_OUT()` as + * `lv_freertos_task_switch_out()` + * to save finish time stamp of a task + */ +void lv_freertos_task_switch_out(void); + +/** + * Set it for `LV_SYSMON_GET_IDLE` to show the CPU usage + * as reported based the usage of FreeRTOS's idle task + * If it's important when a GPU is used. + * @return the idle percentage since the last call + */ +uint32_t lv_os_get_idle_percent(void); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c new file mode 100644 index 000000000..fed82f428 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c @@ -0,0 +1,169 @@ +/** + * @file lv_mqx.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" + +#if LV_USE_OS == LV_OS_MQX + +#include "../misc/lv_log.h" +#include "../stdlib/lv_string.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, + void * user_data) +{ + TASK_TEMPLATE_STRUCT task_template; + + lv_memzero(&task_template, sizeof(task_template)); + + task_template.TASK_ADDRESS = (TASK_FPTR)callback; + task_template.TASK_STACKSIZE = stack_size; + task_template.TASK_PRIORITY = _sched_get_min_priority(0) - prio; + task_template.TASK_NAME = "lvglDraw"; + task_template.CREATION_PARAMETER = (uint32_t)user_data; + + *thread = _task_create(0, 0, (uint32_t)&task_template); + if(*thread == MQX_NULL_TASK_ID) { + LV_LOG_WARN("_task_create failed!"); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_delete(lv_thread_t * thread) +{ + _mqx_uint ret = _task_destroy(*thread); + if(ret != MQX_OK) { + LV_LOG_WARN("_task_destroy failed!"); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_init(lv_mutex_t * mutex) +{ + if(MQX_OK != _mutex_init(mutex, NULL)) { + LV_LOG_WARN("create mutex failed"); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_lock(lv_mutex_t * mutex) +{ + _mqx_uint ret = _mutex_lock(mutex); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) +{ + _mqx_uint ret = _mutex_lock(mutex); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) +{ + _mqx_uint ret = _mutex_unlock(mutex); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_delete(lv_mutex_t * mutex) +{ + _mqx_uint ret = _mutex_destroy(mutex); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) +{ + if(MQX_OK != _lwsem_create(sync, 0)) { + LV_LOG_WARN("create semaphore failed"); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) +{ + _mqx_uint ret = _lwsem_wait(sync); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) +{ + _mqx_uint ret = _lwsem_post(sync); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) +{ + _mqx_uint ret = _lwsem_destroy(sync); + if(ret != MQX_OK) { + LV_LOG_WARN("Error: %x", ret); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_OS == LV_OS_MQX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.h new file mode 100644 index 000000000..601f596a4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.h @@ -0,0 +1,51 @@ +/** + * @file lv_mqx.h + * + */ + +#ifndef LV_MQX_H +#define LV_MQX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" + +#if LV_USE_OS == LV_OS_MQX + +#include "mqx.h" +#include "mutex.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef _task_id lv_thread_t; + +typedef MUTEX_STRUCT lv_mutex_t; + +typedef LWSEM_STRUCT lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_MQX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MQX_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c new file mode 100644 index 000000000..7b775f034 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c @@ -0,0 +1,71 @@ +/** + * @file lv_os.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" +#include "lv_os_private.h" +#include "../core/lv_global.h" + +/********************* + * DEFINES + *********************/ +#define lv_general_mutex LV_GLOBAL_DEFAULT()->lv_general_mutex + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_os_init(void) +{ +#if LV_USE_OS != LV_OS_NONE + lv_mutex_init(&lv_general_mutex); +#endif /*LV_USE_OS != LV_OS_NONE*/ +} + +void lv_lock(void) +{ +#if LV_USE_OS != LV_OS_NONE + lv_mutex_lock(&lv_general_mutex); +#endif /*LV_USE_OS != LV_OS_NONE*/ +} + +lv_result_t lv_lock_isr(void) +{ +#if LV_USE_OS != LV_OS_NONE + return lv_mutex_lock_isr(&lv_general_mutex); +#else /*LV_USE_OS != LV_OS_NONE*/ + return LV_RESULT_OK; +#endif /*LV_USE_OS != LV_OS_NONE*/ +} + +void lv_unlock(void) +{ +#if LV_USE_OS != LV_OS_NONE + lv_mutex_unlock(&lv_general_mutex); +#endif /*LV_USE_OS != LV_OS_NONE*/ +} + +/********************** + * STATIC FUNCTIONS + **********************/ + diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h index 9b3254fc2..d0a4e02f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h @@ -20,7 +20,6 @@ extern "C" { #include "../lv_conf_internal.h" #include "../misc/lv_types.h" -#include #if LV_USE_OS == LV_OS_NONE #include "lv_os_none.h" @@ -34,6 +33,8 @@ extern "C" { #include "lv_rtthread.h" #elif LV_USE_OS == LV_OS_WINDOWS #include "lv_windows.h" +#elif LV_USE_OS == LV_OS_MQX +#include "lv_mqx.h" #elif LV_USE_OS == LV_OS_CUSTOM #include LV_OS_CUSTOM_INCLUDE #endif @@ -137,6 +138,13 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync); */ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync); +/** + * Send a wake-up signal to a sync object from interrupt + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync); + /** * Delete a sync object * @param sync a sync object to delete @@ -144,6 +152,29 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync); */ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync); +/** + * Lock LVGL's general mutex. + * LVGL is not thread safe, so a mutex is used to avoid executing multiple LVGL functions at the same time + * from different threads. It shall be called when calling LVGL functions from threads + * different than lv_timer_handler's thread. It doesn't need to be called in LVGL events because + * they are called from lv_timer_handler(). + * It is called internally in lv_timer_handler(). + */ +void lv_lock(void); + +/** + * Same as `lv_lock()` but can be called from an interrupt. + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_lock_isr(void); + +/** + * The pair of `lv_lock()` and `lv_lock_isr()`. + * It unlocks LVGL general mutex. + * It is called internally in lv_timer_handler(). + */ +void lv_unlock(void); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c index 4e044d057..547810db7 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c @@ -106,6 +106,13 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) return LV_RESULT_INVALID; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + LV_ASSERT(0); + return LV_RESULT_INVALID; +} + lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) { LV_UNUSED(sync); diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_os_private.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_os_private.h new file mode 100644 index 000000000..4fe08cd2f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os_private.h @@ -0,0 +1,47 @@ +/** + * @file lv_os_private.h + * + */ + +#ifndef LV_OS_PRIVATE_H +#define LV_OS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * OS OPTIONS + *********************/ + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the OS layer + */ +void lv_os_init(void); + + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OS_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c index 68676c946..268f055c2 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c @@ -42,10 +42,12 @@ lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*c void * user_data) { LV_UNUSED(prio); - LV_UNUSED(stack_size); + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, stack_size); thread->callback = callback; thread->user_data = user_data; - pthread_create(&thread->thread, NULL, generic_callback, thread); + pthread_create(&thread->thread, &attr, generic_callback, thread); return LV_RESULT_OK; } @@ -62,7 +64,13 @@ lv_result_t lv_thread_delete(lv_thread_t * thread) lv_result_t lv_mutex_init(lv_mutex_t * mutex) { - int ret = pthread_mutex_init(mutex, NULL); + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + int ret = pthread_mutex_init(mutex, &attr); + pthread_mutexattr_destroy(&attr); + if(ret) { LV_LOG_WARN("Error: %d", ret); return LV_RESULT_INVALID; @@ -150,6 +158,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c index 39f78d784..e781634e1 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c @@ -177,6 +177,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) } } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c index 0d6a33d66..78ac29353 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c @@ -152,6 +152,7 @@ lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) InitializeCriticalSection(&sync->cs); InitializeConditionVariable(&sync->cv); + sync->v = false; return LV_RESULT_OK; } @@ -197,6 +198,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.c b/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.c index 40a7a383c..bb0220c89 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.c +++ b/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_file_explorer.h" +#include "lv_file_explorer_private.h" +#include "../../misc/lv_fs_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_FILE_EXPLORER != 0 #include "../../lvgl.h" @@ -598,8 +600,7 @@ static void show_dir(lv_obj_t * obj, const char * path) /*Move the table to the top*/ lv_obj_scroll_to_y(explorer->file_table, 0, LV_ANIM_OFF); - lv_memzero(explorer->current_path, sizeof(explorer->current_path)); - lv_strncpy(explorer->current_path, path, sizeof(explorer->current_path) - 1); + lv_strlcpy(explorer->current_path, path, sizeof(explorer->current_path)); lv_label_set_text_fmt(explorer->path_label, LV_SYMBOL_EYE_OPEN" %s", path); size_t current_path_len = lv_strlen(explorer->current_path); diff --git a/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.h b/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.h index 9d1c3cc8a..8dd7762f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.h +++ b/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer.h @@ -42,30 +42,6 @@ typedef enum { } lv_file_explorer_dir_t; #endif -/*Data of canvas*/ -typedef struct { - lv_obj_t obj; - lv_obj_t * cont; - lv_obj_t * head_area; - lv_obj_t * browser_area; - lv_obj_t * file_table; - lv_obj_t * path_label; -#if LV_FILE_EXPLORER_QUICK_ACCESS - lv_obj_t * quick_access_area; - lv_obj_t * list_device; - lv_obj_t * list_places; - char * home_dir; - char * music_dir; - char * pictures_dir; - char * video_dir; - char * docs_dir; - char * fs_dir; -#endif - const char * sel_fn; - char current_path[LV_FILE_EXPLORER_PATH_MAX_LEN]; - lv_file_explorer_sort_t sort; -} lv_file_explorer_t; - extern const lv_obj_class_t lv_file_explorer_class; /*********************** diff --git a/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer_private.h b/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer_private.h new file mode 100644 index 000000000..1b7eca1dd --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/file_explorer/lv_file_explorer_private.h @@ -0,0 +1,69 @@ +/** + * @file lv_file_explorer_private.h + * + */ + +#ifndef LV_FILE_EXPLORER_PRIVATE_H +#define LV_FILE_EXPLORER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_file_explorer.h" + +#if LV_USE_FILE_EXPLORER != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of canvas*/ +struct lv_file_explorer_t { + lv_obj_t obj; + lv_obj_t * cont; + lv_obj_t * head_area; + lv_obj_t * browser_area; + lv_obj_t * file_table; + lv_obj_t * path_label; +#if LV_FILE_EXPLORER_QUICK_ACCESS + lv_obj_t * quick_access_area; + lv_obj_t * list_device; + lv_obj_t * list_places; + char * home_dir; + char * music_dir; + char * pictures_dir; + char * video_dir; + char * docs_dir; + char * fs_dir; +#endif + const char * sel_fn; + char current_path[LV_FILE_EXPLORER_PATH_MAX_LEN]; + lv_file_explorer_sort_t sort; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FILE_EXPLORER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FILE_EXPLORER_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.c b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.c index c04b3e84c..6deb4e785 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.c +++ b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ -#include "lv_fragment.h" +#include "lv_fragment_private.h" #if LV_USE_FRAGMENT #include "../../stdlib/lv_string.h" diff --git a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.h b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.h index 593b5b575..f93473757 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.h +++ b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.h @@ -25,13 +25,9 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct _lv_fragment_manager_t lv_fragment_manager_t; +typedef struct lv_fragment_manager_t lv_fragment_manager_t; -typedef struct _lv_fragment_t lv_fragment_t; -typedef struct _lv_fragment_class_t lv_fragment_class_t; -typedef struct _lv_fragment_managed_states_t lv_fragment_managed_states_t; - -struct _lv_fragment_t { +struct lv_fragment_t { /** * Class of this fragment */ @@ -53,7 +49,7 @@ struct _lv_fragment_t { }; -struct _lv_fragment_class_t { +struct lv_fragment_class_t { /** * Constructor function for fragment class * @param self Fragment instance @@ -124,40 +120,6 @@ struct _lv_fragment_class_t { size_t instance_size; }; -/** - * Fragment states - */ -struct _lv_fragment_managed_states_t { - /** - * Class of the fragment - */ - const lv_fragment_class_t * cls; - /** - * Manager the fragment attached to - */ - lv_fragment_manager_t * manager; - /** - * Container object the fragment adding view to - */ - lv_obj_t * const * container; - /** - * Fragment instance - */ - lv_fragment_t * instance; - /** - * true between `create_obj_cb` and `obj_deleted_cb` - */ - bool obj_created; - /** - * true before `lv_fragment_delete_obj` is called. Don't touch any object if this is true - */ - bool destroying_obj; - /** - * true if this fragment is in navigation stack that can be popped - */ - bool in_stack; -}; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_manager.c b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_manager.c index 73b0c9df2..a8565185b 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_manager.c +++ b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_manager.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ -#include "lv_fragment.h" +#include "lv_fragment_private.h" #if LV_USE_FRAGMENT @@ -21,11 +21,11 @@ /********************** * TYPEDEFS **********************/ -typedef struct _lv_fragment_stack_item_t { +typedef struct lv_fragment_stack_item_t { lv_fragment_managed_states_t * states; } lv_fragment_stack_item_t; -struct _lv_fragment_manager_t { +struct lv_fragment_manager_t { lv_fragment_t * parent; /** * Linked list to store attached fragments @@ -66,8 +66,8 @@ lv_fragment_manager_t * lv_fragment_manager_create(lv_fragment_t * parent) { lv_fragment_manager_t * instance = lv_malloc_zeroed(sizeof(lv_fragment_manager_t)); instance->parent = parent; - _lv_ll_init(&instance->attached, sizeof(lv_fragment_managed_states_t)); - _lv_ll_init(&instance->stack, sizeof(lv_fragment_stack_item_t)); + lv_ll_init(&instance->attached, sizeof(lv_fragment_managed_states_t)); + lv_ll_init(&instance->stack, sizeof(lv_fragment_stack_item_t)); return instance; } @@ -75,21 +75,21 @@ void lv_fragment_manager_delete(lv_fragment_manager_t * manager) { LV_ASSERT_NULL(manager); lv_fragment_managed_states_t * states; - _LV_LL_READ_BACK(&manager->attached, states) { + LV_LL_READ_BACK(&manager->attached, states) { item_delete_obj(states); item_delete_fragment(states); } - _lv_ll_clear(&manager->attached); - _lv_ll_clear(&manager->stack); + lv_ll_clear(&manager->attached); + lv_ll_clear(&manager->stack); lv_free(manager); } void lv_fragment_manager_create_obj(lv_fragment_manager_t * manager) { LV_ASSERT_NULL(manager); - lv_fragment_stack_item_t * top = _lv_ll_get_tail(&manager->stack); + lv_fragment_stack_item_t * top = lv_ll_get_tail(&manager->stack); lv_fragment_managed_states_t * states = NULL; - _LV_LL_READ(&manager->attached, states) { + LV_LL_READ(&manager->attached, states) { if(states->in_stack && top->states != states) { /*Only create obj for top item in stack*/ continue; @@ -102,7 +102,7 @@ void lv_fragment_manager_delete_obj(lv_fragment_manager_t * manager) { LV_ASSERT_NULL(manager); lv_fragment_managed_states_t * states = NULL; - _LV_LL_READ_BACK(&manager->attached, states) { + LV_LL_READ_BACK(&manager->attached, states) { item_delete_obj(states); } } @@ -125,25 +125,25 @@ void lv_fragment_manager_remove(lv_fragment_manager_t * manager, lv_fragment_t * lv_fragment_managed_states_t * prev = NULL; bool was_top = false; if(states->in_stack) { - void * stack_top = _lv_ll_get_tail(&manager->stack); + void * stack_top = lv_ll_get_tail(&manager->stack); lv_fragment_stack_item_t * item = NULL; - _LV_LL_READ_BACK(&manager->stack, item) { + LV_LL_READ_BACK(&manager->stack, item) { if(item->states == states) { was_top = stack_top == item; - void * stack_prev = _lv_ll_get_prev(&manager->stack, item); + void * stack_prev = lv_ll_get_prev(&manager->stack, item); if(!stack_prev) break; prev = ((lv_fragment_stack_item_t *) stack_prev)->states; break; } } if(item) { - _lv_ll_remove(&manager->stack, item); + lv_ll_remove(&manager->stack, item); lv_free(item); } } item_delete_obj(states); item_delete_fragment(states); - _lv_ll_remove(&manager->attached, states); + lv_ll_remove(&manager->attached, states); lv_free(states); if(prev && was_top) { item_create_obj(prev); @@ -152,14 +152,14 @@ void lv_fragment_manager_remove(lv_fragment_manager_t * manager, lv_fragment_t * void lv_fragment_manager_push(lv_fragment_manager_t * manager, lv_fragment_t * fragment, lv_obj_t * const * container) { - lv_fragment_stack_item_t * top = _lv_ll_get_tail(&manager->stack); + lv_fragment_stack_item_t * top = lv_ll_get_tail(&manager->stack); if(top != NULL) { item_delete_obj(top->states); } lv_fragment_managed_states_t * states = fragment_attach(manager, fragment, container); states->in_stack = true; /*Add fragment to the top of the stack*/ - lv_fragment_stack_item_t * item = _lv_ll_ins_tail(&manager->stack); + lv_fragment_stack_item_t * item = lv_ll_ins_tail(&manager->stack); lv_memzero(item, sizeof(lv_fragment_stack_item_t)); item->states = states; item_create_obj(states); @@ -187,7 +187,7 @@ bool lv_fragment_manager_send_event(lv_fragment_manager_t * manager, int code, v { LV_ASSERT_NULL(manager); lv_fragment_managed_states_t * p = NULL; - _LV_LL_READ_BACK(&manager->attached, p) { + LV_LL_READ_BACK(&manager->attached, p) { if(!p->obj_created || p->destroying_obj) continue; lv_fragment_t * instance = p->instance; if(!instance) continue; @@ -200,13 +200,13 @@ bool lv_fragment_manager_send_event(lv_fragment_manager_t * manager, int code, v size_t lv_fragment_manager_get_stack_size(lv_fragment_manager_t * manager) { LV_ASSERT_NULL(manager); - return _lv_ll_get_len(&manager->stack); + return lv_ll_get_len(&manager->stack); } lv_fragment_t * lv_fragment_manager_get_top(lv_fragment_manager_t * manager) { LV_ASSERT(manager); - lv_fragment_stack_item_t * top = _lv_ll_get_tail(&manager->stack); + lv_fragment_stack_item_t * top = lv_ll_get_tail(&manager->stack); if(!top)return NULL; return top->states->instance; } @@ -215,7 +215,7 @@ lv_fragment_t * lv_fragment_manager_find_by_container(lv_fragment_manager_t * ma { LV_ASSERT(manager); lv_fragment_managed_states_t * states; - _LV_LL_READ(&manager->attached, states) { + LV_LL_READ(&manager->attached, states) { if(*states->container == container) return states->instance; } return NULL; @@ -263,7 +263,7 @@ static lv_fragment_managed_states_t * fragment_attach(lv_fragment_manager_t * ma LV_ASSERT(manager); LV_ASSERT(fragment); LV_ASSERT(fragment->managed == NULL); - lv_fragment_managed_states_t * states = _lv_ll_ins_tail(&manager->attached); + lv_fragment_managed_states_t * states = lv_ll_ins_tail(&manager->attached); lv_memzero(states, sizeof(lv_fragment_managed_states_t)); states->cls = fragment->cls; states->manager = manager; diff --git a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_private.h b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_private.h new file mode 100644 index 000000000..3af36ddbc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_private.h @@ -0,0 +1,77 @@ +/** + * @file lv_fragment_private.h + * + */ + +#ifndef LV_FRAGMENT_PRIVATE_H +#define LV_FRAGMENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_fragment.h" + +#if LV_USE_FRAGMENT + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Fragment states + */ +struct lv_fragment_managed_states_t { + /** + * Class of the fragment + */ + const lv_fragment_class_t * cls; + /** + * Manager the fragment attached to + */ + lv_fragment_manager_t * manager; + /** + * Container object the fragment adding view to + */ + lv_obj_t * const * container; + /** + * Fragment instance + */ + lv_fragment_t * instance; + /** + * true between `create_obj_cb` and `obj_deleted_cb` + */ + bool obj_created; + /** + * true before `lv_fragment_delete_obj` is called. Don't touch any object if this is true + */ + bool destroying_obj; + /** + * true if this fragment is in navigation stack that can be popped + */ + bool in_stack; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FRAGMENT */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FRAGMENT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.c b/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.c index f49c62d0c..5f348af58 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.c +++ b/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.c @@ -12,6 +12,7 @@ #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" #include "../../indev/lv_indev.h" +#include "../../core/lv_obj_private.h" /********************* * DEFINES @@ -43,7 +44,7 @@ static void gridnav_event_cb(lv_event_t * e); static lv_obj_t * find_chid(lv_obj_t * obj, lv_obj_t * start_child, find_mode_t mode); static lv_obj_t * find_first_focusable(lv_obj_t * obj); static lv_obj_t * find_last_focusable(lv_obj_t * obj); -static bool obj_is_focuable(lv_obj_t * obj); +static bool obj_is_focusable(lv_obj_t * obj); static int32_t get_x_center(lv_obj_t * obj); static int32_t get_y_center(lv_obj_t * obj); @@ -108,7 +109,7 @@ void lv_gridnav_set_focused(lv_obj_t * cont, lv_obj_t * to_focus, lv_anim_enable return; } - if(obj_is_focuable(to_focus) == false) { + if(obj_is_focusable(to_focus) == false) { LV_LOG_WARN("The object to focus is not focusable"); return; } @@ -143,7 +144,7 @@ static void gridnav_event_cb(lv_event_t * e) uint32_t key = lv_event_get_key(e); lv_obj_t * guess = NULL; - if(key == LV_KEY_RIGHT) { + if(key == LV_KEY_RIGHT && !(dsc->ctrl & LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY)) { if((dsc->ctrl & LV_GRIDNAV_CTRL_SCROLL_FIRST) && lv_obj_has_flag(dsc->focused_obj, LV_OBJ_FLAG_SCROLLABLE) && lv_obj_get_scroll_right(dsc->focused_obj) > 0) { int32_t d = lv_obj_get_width(dsc->focused_obj) / 4; @@ -163,7 +164,7 @@ static void gridnav_event_cb(lv_event_t * e) } } } - else if(key == LV_KEY_LEFT) { + else if(key == LV_KEY_LEFT && !(dsc->ctrl & LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY)) { if((dsc->ctrl & LV_GRIDNAV_CTRL_SCROLL_FIRST) && lv_obj_has_flag(dsc->focused_obj, LV_OBJ_FLAG_SCROLLABLE) && lv_obj_get_scroll_left(dsc->focused_obj) > 0) { int32_t d = lv_obj_get_width(dsc->focused_obj) / 4; @@ -183,7 +184,7 @@ static void gridnav_event_cb(lv_event_t * e) } } } - else if(key == LV_KEY_DOWN) { + else if(key == LV_KEY_DOWN && !(dsc->ctrl & LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY)) { if((dsc->ctrl & LV_GRIDNAV_CTRL_SCROLL_FIRST) && lv_obj_has_flag(dsc->focused_obj, LV_OBJ_FLAG_SCROLLABLE) && lv_obj_get_scroll_bottom(dsc->focused_obj) > 0) { int32_t d = lv_obj_get_height(dsc->focused_obj) / 4; @@ -202,7 +203,7 @@ static void gridnav_event_cb(lv_event_t * e) } } } - else if(key == LV_KEY_UP) { + else if(key == LV_KEY_UP && !(dsc->ctrl & LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY)) { if((dsc->ctrl & LV_GRIDNAV_CTRL_SCROLL_FIRST) && lv_obj_has_flag(dsc->focused_obj, LV_OBJ_FLAG_SCROLLABLE) && lv_obj_get_scroll_top(dsc->focused_obj) > 0) { int32_t d = lv_obj_get_height(dsc->focused_obj) / 4; @@ -229,7 +230,9 @@ static void gridnav_event_cb(lv_event_t * e) if(guess && guess != dsc->focused_obj) { lv_obj_remove_state(dsc->focused_obj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_send_event(dsc->focused_obj, LV_EVENT_DEFOCUSED, lv_indev_active()); lv_obj_add_state(guess, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_send_event(guess, LV_EVENT_FOCUSED, lv_indev_active()); lv_obj_scroll_to_view(guess, LV_ANIM_ON); dsc->focused_obj = guess; } @@ -298,7 +301,7 @@ static lv_obj_t * find_chid(lv_obj_t * obj, lv_obj_t * start_child, find_mode_t for(i = 0; i < child_cnt; i++) { lv_obj_t * child = lv_obj_get_child(obj, i); if(child == start_child) continue; - if(obj_is_focuable(child) == false) continue; + if(obj_is_focusable(child) == false) continue; int32_t x_err = 0; int32_t y_err = 0; @@ -360,7 +363,7 @@ static lv_obj_t * find_first_focusable(lv_obj_t * obj) uint32_t i; for(i = 0; i < child_cnt; i++) { lv_obj_t * child = lv_obj_get_child(obj, i); - if(obj_is_focuable(child)) return child; + if(obj_is_focusable(child)) return child; } return NULL; @@ -372,12 +375,12 @@ static lv_obj_t * find_last_focusable(lv_obj_t * obj) int32_t i; for(i = child_cnt - 1; i >= 0; i--) { lv_obj_t * child = lv_obj_get_child(obj, i); - if(obj_is_focuable(child)) return child; + if(obj_is_focusable(child)) return child; } return NULL; } -static bool obj_is_focuable(lv_obj_t * obj) +static bool obj_is_focusable(lv_obj_t * obj) { if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return false; if(lv_obj_has_flag(obj, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CLICK_FOCUSABLE)) return true; diff --git a/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.h b/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.h index 29b86fc1d..65bd1e092 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.h +++ b/lib/libesp32_lvgl/lvgl/src/others/gridnav/lv_gridnav.h @@ -1,50 +1,10 @@ -/** - * @file lv_templ.c - * - */ - -/********************* - * INCLUDES - *********************/ - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/*This typedef exists purely to keep -Wpedantic happy when the file is empty.*/ -/*It can be removed.*/ -typedef int _keep_pedantic_happy; - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/********************** - * STATIC FUNCTIONS - **********************/ /** * @file lv_gridnav.h * */ -#ifndef LV_GRIDFOCUS_H -#define LV_GRIDFOCUS_H +#ifndef LV_GRIDNAV_H +#define LV_GRIDNAV_H #ifdef __cplusplus extern "C" { @@ -80,6 +40,18 @@ typedef enum { * If there is no more room for scrolling the next/previous object will be focused normally */ LV_GRIDNAV_CTRL_SCROLL_FIRST = 0x2, + /** + * Only use left/right keys for grid navigation. Up/down key events will be sent to the + * focused object. + */ + LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY = 0x4, + + /** + * Only use up/down keys for grid navigation. Left/right key events will be sent to the + * focused object. + */ + LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY = 0x8 + } lv_gridnav_ctrl_t; /********************** @@ -120,4 +92,4 @@ void lv_gridnav_set_focused(lv_obj_t * cont, lv_obj_t * to_focus, lv_anim_enable } /*extern "C"*/ #endif -#endif /*LV_GRIDFOCUS_H*/ +#endif /* LV_GRIDNAV_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c index 1cb6a5e54..08f43a143 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c +++ b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.c @@ -6,11 +6,12 @@ /********************* * INCLUDES *********************/ -#include "lv_ime_pinyin.h" +#include "lv_ime_pinyin_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_IME_PINYIN != 0 -#include #include "../../lvgl.h" +#include "../../core/lv_global.h" /********************* * DEFINES @@ -583,7 +584,7 @@ static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * pinyin_k9_init_data(obj); - _lv_ll_init(&(pinyin_ime->k9_legal_py_ll), sizeof(ime_pinyin_k9_py_str_t)); + lv_ll_init(&(pinyin_ime->k9_legal_py_ll), sizeof(ime_pinyin_k9_py_str_t)); #endif } @@ -627,7 +628,7 @@ static void lv_ime_pinyin_kb_event(lv_event_t * e) uint16_t tmp_button_str_len = lv_strlen(pinyin_ime->input_char); if((btn_id >= 16) && (tmp_button_str_len > 0) && (btn_id < (16 + LV_IME_PINYIN_K9_CAND_TEXT_NUM))) { lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char)); - strcat(pinyin_ime->input_char, txt); + lv_strcat(pinyin_ime->input_char, txt); pinyin_input_proc(obj); for(int index = 0; index < (pinyin_ime->ta_count + tmp_button_str_len); index++) { @@ -706,7 +707,7 @@ static void lv_ime_pinyin_kb_event(lv_event_t * e) } else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) && ((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' && txt[0] <= 'Z'))) { - strcat(pinyin_ime->input_char, txt); + lv_strcat(pinyin_ime->input_char, txt); pinyin_input_proc(obj); pinyin_ime->ta_count++; } @@ -830,7 +831,7 @@ static void pinyin_page_proc(lv_obj_t * obj, uint16_t dir) uint16_t offset = pinyin_ime->py_page * (3 * LV_IME_PINYIN_CAND_TEXT_NUM); for(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) { if((remainder > 0) && (pinyin_ime->py_page == page_num)) { - if(i > remainder) + if(i >= remainder) break; } for(uint8_t j = 0; j < 3; j++) { @@ -1006,19 +1007,19 @@ static void pinyin_k9_get_legal_py(lv_obj_t * obj, char * k9_input, const char * uint32_t ll_len = 0; ime_pinyin_k9_py_str_t * ll_index = NULL; - ll_len = _lv_ll_get_len(&pinyin_ime->k9_legal_py_ll); - ll_index = _lv_ll_get_head(&pinyin_ime->k9_legal_py_ll); + ll_len = lv_ll_get_len(&pinyin_ime->k9_legal_py_ll); + ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll); while(index != -1) { if(index == len) { if(pinyin_k9_is_valid_py(obj, py_comp)) { if((count >= ll_len) || (ll_len == 0)) { - ll_index = _lv_ll_ins_tail(&pinyin_ime->k9_legal_py_ll); + ll_index = lv_ll_ins_tail(&pinyin_ime->k9_legal_py_ll); lv_strcpy(ll_index->py_str, py_comp); } else if((count < ll_len)) { lv_strcpy(ll_index->py_str, py_comp); - ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); + ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); } count++; } @@ -1096,7 +1097,7 @@ static void pinyin_k9_fill_cand(lv_obj_t * obj) cand_len = tmp_len; } - ll_index = _lv_ll_get_head(&pinyin_ime->k9_legal_py_ll); + ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll); lv_strcpy(pinyin_ime->input_char, ll_index->py_str); for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) { @@ -1111,7 +1112,7 @@ static void pinyin_k9_fill_cand(lv_obj_t * obj) lv_strcpy(lv_pinyin_k9_cand_str[index], ll_index->py_str); } - ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/ + ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/ index++; } pinyin_ime->k9_py_ll_pos = index; @@ -1129,17 +1130,17 @@ static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir) lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj; lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb); - uint16_t ll_len = _lv_ll_get_len(&pinyin_ime->k9_legal_py_ll); + uint16_t ll_len = lv_ll_get_len(&pinyin_ime->k9_legal_py_ll); if((ll_len > LV_IME_PINYIN_K9_CAND_TEXT_NUM) && (pinyin_ime->k9_legal_py_count > LV_IME_PINYIN_K9_CAND_TEXT_NUM)) { ime_pinyin_k9_py_str_t * ll_index = NULL; int count = 0; - ll_index = _lv_ll_get_head(&pinyin_ime->k9_legal_py_ll); + ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll); while(ll_index) { if(count >= pinyin_ime->k9_py_ll_pos) break; - ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/ + ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/ count++; } @@ -1161,7 +1162,7 @@ static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir) break; lv_strcpy(lv_pinyin_k9_cand_str[count], ll_index->py_str); - ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/ + ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/ count++; } pinyin_ime->k9_py_ll_pos += count - 1; @@ -1173,12 +1174,12 @@ static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir) lv_strcpy(lv_pinyin_k9_cand_str[i], " "); } count = LV_IME_PINYIN_K9_CAND_TEXT_NUM - 1; - ll_index = _lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index); + ll_index = lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index); while(ll_index) { if(count < 0) break; lv_strcpy(lv_pinyin_k9_cand_str[count], ll_index->py_str); - ll_index = _lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the previous list*/ + ll_index = lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the previous list*/ count--; } diff --git a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.h b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.h index a342d2c72..ff85eee88 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.h +++ b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin.h @@ -43,29 +43,6 @@ typedef struct { char py_str[7]; } ime_pinyin_k9_py_str_t; -/*Data of lv_ime_pinyin*/ -typedef struct { - lv_obj_t obj; - lv_obj_t * kb; - lv_obj_t * cand_panel; - const lv_pinyin_dict_t * dict; - lv_ll_t k9_legal_py_ll; - char * cand_str; /* Candidate string */ - char input_char[16]; /* Input box character */ -#if LV_IME_PINYIN_USE_K9_MODE - char k9_input_str[LV_IME_PINYIN_K9_MAX_INPUT + 1]; /* 9-key input(k9) mode input string */ - uint16_t k9_py_ll_pos; /* Current pinyin map pages(k9) */ - uint16_t k9_legal_py_count; /* Count of legal Pinyin numbers(k9) */ - uint16_t k9_input_str_len; /* 9-key input(k9) mode input string max len */ -#endif - uint16_t ta_count; /* The number of characters entered in the text box this time */ - uint16_t cand_num; /* Number of candidates */ - uint16_t py_page; /* Current pinyin map pages(k26) */ - uint16_t py_num[26]; /* Number and length of Pinyin */ - uint16_t py_pos[26]; /* Pinyin position */ - lv_ime_pinyin_mode_t mode; /* Set mode, 1: 26-key input(k26), 0: 9-key input(k9). Default: 1. */ -} lv_ime_pinyin_t; - /*********************** * GLOBAL VARIABLES ***********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin_private.h b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin_private.h new file mode 100644 index 000000000..6ec42fc09 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/ime/lv_ime_pinyin_private.h @@ -0,0 +1,68 @@ +/** + * @file lv_ime_pinyin_private.h + * + */ + +#ifndef LV_IME_PINYIN_PRIVATE_H +#define LV_IME_PINYIN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_ime_pinyin.h" + +#if LV_USE_IME_PINYIN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/*Data of lv_ime_pinyin*/ +struct lv_ime_pinyin_t { + lv_obj_t obj; + lv_obj_t * kb; + lv_obj_t * cand_panel; + const lv_pinyin_dict_t * dict; + lv_ll_t k9_legal_py_ll; + char * cand_str; /* Candidate string */ + char input_char[16]; /* Input box character */ +#if LV_IME_PINYIN_USE_K9_MODE + char k9_input_str[LV_IME_PINYIN_K9_MAX_INPUT + 1]; /* 9-key input(k9) mode input string */ + uint16_t k9_py_ll_pos; /* Current pinyin map pages(k9) */ + uint16_t k9_legal_py_count; /* Count of legal Pinyin numbers(k9) */ + uint16_t k9_input_str_len; /* 9-key input(k9) mode input string max len */ +#endif + uint16_t ta_count; /* The number of characters entered in the text box this time */ + uint16_t cand_num; /* Number of candidates */ + uint16_t py_page; /* Current pinyin map pages(k26) */ + uint16_t py_num[26]; /* Number and length of Pinyin */ + uint16_t py_pos[26]; /* Pinyin position */ + lv_ime_pinyin_mode_t mode; /* Set mode, 1: 26-key input(k26), 0: 9-key input(k9). Default: 1. */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_IME_PINYIN != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IME_PINYIN_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/imgfont/lv_imgfont.c b/lib/libesp32_lvgl/lvgl/src/others/imgfont/lv_imgfont.c index 1a7768852..edc69907d 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/imgfont/lv_imgfont.c +++ b/lib/libesp32_lvgl/lvgl/src/others/imgfont/lv_imgfont.c @@ -26,8 +26,7 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode, - lv_draw_buf_t * draw_buf); +static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); static bool imgfont_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode, uint32_t unicode_next); @@ -80,15 +79,11 @@ void lv_imgfont_destroy(lv_font_t * font) * STATIC FUNCTIONS **********************/ -static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode, - lv_draw_buf_t * draw_buf) +static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) { LV_UNUSED(draw_buf); - const lv_font_t * font = g_dsc->resolved_font; - imgfont_dsc_t * dsc = (imgfont_dsc_t *)font->dsc; - int32_t offset_y = 0; - const void * img_src = dsc->path_cb(font, unicode, 0, &offset_y, dsc->user_data); + const void * img_src = g_dsc->gid.src; return img_src; } @@ -118,6 +113,7 @@ static bool imgfont_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out->ofs_x = 0; dsc_out->ofs_y = offset_y; dsc_out->format = LV_FONT_GLYPH_FORMAT_IMAGE; /* is image identifier */ + dsc_out->gid.src = img_src; return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.c b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.c index 9f970919d..97ba10a51 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.c +++ b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_monkey.h" +#include "lv_monkey_private.h" #if LV_USE_MONKEY != 0 @@ -24,7 +24,7 @@ /********************** * TYPEDEFS **********************/ -struct _lv_monkey { +struct lv_monkey_t { lv_monkey_config_t config; lv_indev_data_t indev_data; lv_indev_t * indev; @@ -98,7 +98,7 @@ void lv_monkey_set_enable(lv_monkey_t * monkey, bool en) bool lv_monkey_get_enable(lv_monkey_t * monkey) { LV_ASSERT_NULL(monkey); - return !monkey->timer->paused; + return !lv_timer_get_paused(monkey->timer); } void lv_monkey_set_user_data(lv_monkey_t * monkey, void * user_data) @@ -147,7 +147,7 @@ static int32_t lv_monkey_random(int32_t howsmall, int32_t howbig) static void lv_monkey_timer_cb(lv_timer_t * timer) { - lv_monkey_t * monkey = timer->user_data; + lv_monkey_t * monkey = lv_timer_get_user_data(timer); lv_indev_data_t * data = &monkey->indev_data; switch(lv_indev_get_type(monkey->indev)) { diff --git a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.h b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.h index 3791abc85..6cbe0ec56 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.h +++ b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.h @@ -24,10 +24,10 @@ extern "C" { /********************** * TYPEDEFS **********************/ -struct _lv_monkey; -typedef struct _lv_monkey lv_monkey_t; -typedef struct { +typedef struct lv_monkey_t lv_monkey_t; + +struct lv_monkey_config_t { /**< Input device type*/ lv_indev_type_t type; @@ -44,7 +44,7 @@ typedef struct { int32_t min; int32_t max; } input_range; -} lv_monkey_config_t; +}; /********************** * GLOBAL PROTOTYPES diff --git a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey_private.h b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey_private.h new file mode 100644 index 000000000..a08ea0731 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey_private.h @@ -0,0 +1,43 @@ +/** + * @file lv_monkey_private.h + * + */ + +#ifndef LV_MONKEY_PRIVATE_H +#define LV_MONKEY_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_monkey.h" + +#if LV_USE_MONKEY != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_MONKEY != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MONKEY_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.c b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.c index 10b3186d2..8d43f52de 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.c +++ b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.c @@ -7,10 +7,12 @@ * INCLUDES *********************/ -#include "lv_observer.h" +#include "lv_observer_private.h" #if LV_USE_OBSERVER #include "../../lvgl.h" +#include "../../core/lv_obj_private.h" +#include "../../misc/lv_event_private.h" /********************* * DEFINES @@ -34,10 +36,7 @@ static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, int32_t ref_value, bool inv); static void obj_flag_observer_cb(lv_observer_t * observer, lv_subject_t * subject); static void obj_state_observer_cb(lv_observer_t * observer, lv_subject_t * subject); - -#if LV_USE_BUTTON - static void btn_value_changed_event_cb(lv_event_t * e); -#endif +static void obj_value_changed_event_cb(lv_event_t * e); #if LV_USE_LABEL static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject); @@ -81,7 +80,7 @@ void lv_subject_init_int(lv_subject_t * subject, int32_t value) subject->type = LV_SUBJECT_TYPE_INT; subject->value.num = value; subject->prev_value.num = value; - _lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); + lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); } void lv_subject_set_int(lv_subject_t * subject, int32_t value) @@ -119,15 +118,15 @@ int32_t lv_subject_get_previous_int(lv_subject_t * subject) void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value) { lv_memzero(subject, sizeof(lv_subject_t)); - lv_strncpy(buf, value, size); - if(prev_buf) lv_strncpy(prev_buf, value, size); + lv_strlcpy(buf, value, size); + if(prev_buf) lv_strlcpy(prev_buf, value, size); subject->type = LV_SUBJECT_TYPE_STRING; subject->size = size; subject->value.pointer = buf; subject->prev_value.pointer = prev_buf; - _lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); + lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); } void lv_subject_copy_string(lv_subject_t * subject, const char * buf) @@ -139,10 +138,10 @@ void lv_subject_copy_string(lv_subject_t * subject, const char * buf) if(subject->size < 1) return; if(subject->prev_value.pointer) { - lv_strncpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size - 1); + lv_strlcpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size); } - lv_strncpy((char *)subject->value.pointer, buf, subject->size - 1); + lv_strlcpy((char *)subject->value.pointer, buf, subject->size); lv_subject_notify(subject); @@ -174,7 +173,7 @@ void lv_subject_init_pointer(lv_subject_t * subject, void * value) subject->type = LV_SUBJECT_TYPE_POINTER; subject->value.pointer = value; subject->prev_value.pointer = value; - _lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); + lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); } void lv_subject_set_pointer(lv_subject_t * subject, void * ptr) @@ -215,7 +214,7 @@ void lv_subject_init_color(lv_subject_t * subject, lv_color_t color) subject->type = LV_SUBJECT_TYPE_COLOR; subject->value.color = color; subject->prev_value.color = color; - _lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); + lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); } void lv_subject_set_color(lv_subject_t * subject, lv_color_t color) @@ -254,7 +253,7 @@ void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32 { subject->type = LV_SUBJECT_TYPE_GROUP; subject->size = list_len; - _lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); + lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); subject->value.pointer = list; /* bind all subjects to this subject */ @@ -265,6 +264,24 @@ void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32 } } +void lv_subject_deinit(lv_subject_t * subject) +{ + lv_observer_t * observer = lv_ll_get_head(&subject->subs_ll); + while(observer) { + lv_observer_t * observer_next = lv_ll_get_next(&subject->subs_ll, observer); + + if(observer->for_obj) { + lv_obj_remove_event_cb(observer->target, unsubscribe_on_delete_cb); + lv_obj_remove_event_cb_with_user_data(observer->target, NULL, subject); + } + + lv_observer_remove(observer); + observer = observer_next; + } + + lv_ll_clear(&subject->subs_ll); +} + lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index) { if(subject->type != LV_SUBJECT_TYPE_GROUP) { @@ -280,6 +297,9 @@ lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t inde lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t cb, void * user_data) { lv_observer_t * observer = lv_subject_add_observer_obj(subject, cb, NULL, user_data); + if(observer == NULL) return NULL; + + observer->for_obj = 0; return observer; } @@ -291,7 +311,7 @@ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_ LV_LOG_WARN("Subject not initialized yet"); return NULL; } - lv_observer_t * observer = _lv_ll_ins_tail(&(subject->subs_ll)); + lv_observer_t * observer = lv_ll_ins_tail(&(subject->subs_ll)); LV_ASSERT_MALLOC(observer); if(observer == NULL) return NULL; @@ -301,6 +321,7 @@ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_ observer->cb = cb; observer->user_data = user_data; observer->target = obj; + observer->for_obj = 1; /* subscribe to delete event of the object */ if(obj != NULL) { lv_obj_add_event_cb(obj, unsubscribe_on_delete_cb, LV_EVENT_DELETE, observer); @@ -320,7 +341,7 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o LV_LOG_WARN("Subject not initialized yet"); return NULL; } - lv_observer_t * observer = _lv_ll_ins_tail(&(subject->subs_ll)); + lv_observer_t * observer = lv_ll_ins_tail(&(subject->subs_ll)); LV_ASSERT_MALLOC(observer); if(observer == NULL) return NULL; @@ -337,13 +358,14 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o return observer; } + void lv_observer_remove(lv_observer_t * observer) { LV_ASSERT_NULL(observer); observer->subject->notify_restart_query = 1; - _lv_ll_remove(&(observer->subject->subs_ll), observer); + lv_ll_remove(&(observer->subject->subs_ll), observer); if(observer->auto_free_user_data) { lv_free(observer->user_data); @@ -351,39 +373,19 @@ void lv_observer_remove(lv_observer_t * observer) lv_free(observer); } -void lv_subject_remove_all_obj(lv_subject_t * subject, lv_obj_t * obj) +void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject) { - LV_ASSERT_NULL(subject); - if(subject->type == LV_SUBJECT_TYPE_INVALID) { - LV_LOG_WARN("Subject not initialized yet"); - return; - } - - while(lv_obj_remove_event_cb(obj, unsubscribe_on_delete_cb)); - -#if LV_USE_BUTTON - while(lv_obj_remove_event_cb(obj, btn_value_changed_event_cb)); -#endif /*LV_USE_BUTTON*/ - -#if LV_USE_ARC - while(lv_obj_remove_event_cb(obj, arc_value_changed_event_cb)); -#endif /*LV_USE_ARC*/ - -#if LV_USE_ROLLER - while(lv_obj_remove_event_cb(obj, roller_value_changed_event_cb)); -#endif /*LV_USE_ROLLER*/ - -#if LV_USE_DROPDOWN - while(lv_obj_remove_event_cb(obj, dropdown_value_changed_event_cb)); -#endif /*LV_USE_DROPDOWN*/ - - lv_observer_t * observer = _lv_ll_get_head(&subject->subs_ll); - while(observer) { - lv_observer_t * observer_next = _lv_ll_get_next(&subject->subs_ll, observer); - if(observer->target == obj) { - lv_observer_remove(observer); + int32_t i; + int32_t event_cnt = (int32_t)(obj->spec_attr ? lv_array_size(&obj->spec_attr->event_list) : 0); + for(i = event_cnt - 1; i >= 0; i--) { + lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(obj, i); + if(event_dsc->cb == unsubscribe_on_delete_cb) { + lv_observer_t * observer = event_dsc->user_data; + if(subject == NULL || subject == observer->subject) { + lv_observer_remove(observer); + lv_obj_remove_event(obj, i); + } } - observer = observer_next; } } @@ -399,13 +401,13 @@ void lv_subject_notify(lv_subject_t * subject) LV_ASSERT_NULL(subject); lv_observer_t * observer; - _LV_LL_READ(&(subject->subs_ll), observer) { + LV_LL_READ(&(subject->subs_ll), observer) { observer->notified = 0; } do { subject->notify_restart_query = 0; - _LV_LL_READ(&(subject->subs_ll), observer) { + LV_LL_READ(&(subject->subs_ll), observer) { if(observer->cb && observer->notified == 0) { observer->cb(observer, subject); if(subject->notify_restart_query) break; @@ -440,14 +442,12 @@ lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subje return observable; } -#if LV_USE_BUTTON -lv_observer_t * lv_button_bind_checked(lv_obj_t * obj, lv_subject_t * subject) +lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject) { lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, LV_STATE_CHECKED, 1, false); - lv_obj_add_event_cb(obj, btn_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + lv_obj_add_event_cb(obj, obj_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); return observable; } -#endif /*LV_USE_BUTTON*/ #if LV_USE_LABEL lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt) @@ -536,6 +536,18 @@ lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject) #endif /*LV_USE_DROPDOWN*/ +lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer) +{ + return (lv_obj_t *)lv_observer_get_target(observer); +} + +void * lv_observer_get_user_data(const lv_observer_t * observer) +{ + LV_ASSERT_NULL(observer); + + return observer->user_data; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -606,9 +618,7 @@ static void obj_state_observer_cb(lv_observer_t * observer, lv_subject_t * subje } } -#if LV_USE_BUTTON - -static void btn_value_changed_event_cb(lv_event_t * e) +static void obj_value_changed_event_cb(lv_event_t * e) { lv_obj_t * obj = lv_event_get_current_target(e); lv_subject_t * subject = lv_event_get_user_data(e); @@ -616,8 +626,6 @@ static void btn_value_changed_event_cb(lv_event_t * e) lv_subject_set_int(subject, lv_obj_has_state(obj, LV_STATE_CHECKED)); } -#endif /*LV_USE_BUTTON*/ - #if LV_USE_LABEL static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject) diff --git a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.h b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.h index e1c9cb6b7..cec77feed 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.h +++ b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.h @@ -25,9 +25,9 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_observer_t; -typedef struct _lv_observer_t lv_observer_t; - +/** + * Values for lv_submect_t's `type` field. + */ typedef enum { LV_SUBJECT_TYPE_INVALID = 0, /**< indicates subject not initialized yet*/ LV_SUBJECT_TYPE_NONE = 1, /**< a null value like None or NILt*/ @@ -67,18 +67,6 @@ typedef struct { */ typedef void (*lv_observer_cb_t)(lv_observer_t * observer, lv_subject_t * subject); -/** - * The observer object: a descriptor returned when subscribing LVGL widgets to subjects - */ -struct _lv_observer_t { - lv_subject_t * subject; /**< The observed value */ - lv_observer_cb_t cb; /**< Callback that should be called when the value changes*/ - void * target; /**< A target for the observer, e.g. a widget or style*/ - void * user_data; /**< Additional parameter supplied when subscribing*/ - uint32_t auto_free_user_data : 1; /**< Automatically free user data when the observer is removed */ - uint32_t notified : 1; /**< Mark if this observer was already notified*/ -}; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -155,49 +143,49 @@ void lv_subject_init_pointer(lv_subject_t * subject, void * value); /** * Set the value of a pointer subject. It will notify all the observers as well. * @param subject pointer to the subject - * @param value the new value + * @param ptr new value */ void lv_subject_set_pointer(lv_subject_t * subject, void * ptr); /** * Get the current value of a pointer subject * @param subject pointer to the subject - * @return the current value + * @return current value */ const void * lv_subject_get_pointer(lv_subject_t * subject); /** * Get the previous value of a pointer subject * @param subject pointer to the subject - * @return the current value + * @return current value */ const void * lv_subject_get_previous_pointer(lv_subject_t * subject); /** * Initialize an color type subject * @param subject pointer to the subject - * @param value initial value + * @param color initial value */ void lv_subject_init_color(lv_subject_t * subject, lv_color_t color); /** * Set the value of a color subject. It will notify all the observers as well. * @param subject pointer to the subject - * @param value the new value + * @param color new value */ void lv_subject_set_color(lv_subject_t * subject, lv_color_t color); /** * Get the current value of a color subject * @param subject pointer to the subject - * @return the current value + * @return current value */ lv_color_t lv_subject_get_color(lv_subject_t * subject); /** * Get the previous value of a color subject * @param subject pointer to the subject - * @return the current value + * @return current value */ lv_color_t lv_subject_get_previous_color(lv_subject_t * subject); @@ -209,6 +197,14 @@ lv_color_t lv_subject_get_previous_color(lv_subject_t * subject); */ void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len); +/** + * Remove all the observers from a subject and free all allocated memories in it + * @param subject pointer to the subject + * @note objects added with `lv_subject_add_observer_obj` should be already deleted or + * removed manually. + */ +void lv_subject_deinit(lv_subject_t * subject); + /** * Get an element from the subject group's list * @param subject pointer to the subject @@ -220,7 +216,7 @@ lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t inde /** * Add an observer to a subject. When the subject changes `observer_cb` will be called. * @param subject pointer to the subject - * @param observer_cb the callback to call + * @param observer_cb callback to call * @param user_data optional user data * @return pointer to the created observer */ @@ -230,7 +226,7 @@ lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t * Add an observer to a subject for an object. * When the object is deleted, it will be removed from the subject automatically. * @param subject pointer to the subject - * @param observer_cb the callback to call + * @param observer_cb callback to call * @param obj pointer to an object * @param user_data optional user data * @return pointer to the created observer @@ -241,13 +237,13 @@ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_ /** * Add an observer to a subject and also save a target. * @param subject pointer to the subject - * @param observer_cb the callback to call + * @param observer_cb callback to call * @param target pointer to any data * @param user_data optional user data * @return pointer to the created observer */ -lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_observer_cb_t cb, void * target, - void * user_data); +lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_observer_cb_t observer_cb, + void * target, void * user_data); /** * Remove an observer from its subject @@ -256,11 +252,12 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o void lv_observer_remove(lv_observer_t * observer); /** - * Remove all observers from their subject related to an object - * @param observer pointer to an observer - * @param obj pointer to an object + * Remove the observers of an object from a subject or all subjects + * @param obj the object whose observers should be removed + * @param subject the subject to remove the object from, or `NULL` to remove from all subjects + * @note This function can be used e.g. when an object's subject(s) needs to be replaced by other subject(s) */ -void lv_subject_remove_all_obj(lv_subject_t * subject, lv_obj_t * obj); +void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject); /** * Get the target of an observer @@ -276,10 +273,14 @@ void * lv_observer_get_target(lv_observer_t * observer); * @param observer pointer to an observer * @return pointer to the saved object target */ -static inline lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer) -{ - return (lv_obj_t *)lv_observer_get_target(observer); -} +lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer); + +/** + * Get the user data of the observer. + * @param observer pointer to an observer + * @return void pointer to the saved user data +*/ +void * lv_observer_get_user_data(const lv_observer_t * observer); /** * Notify all observers of subject @@ -291,8 +292,8 @@ void lv_subject_notify(lv_subject_t * subject); * Set an object flag if an integer subject's value is equal to a reference value, clear the flag otherwise * @param obj pointer to an object * @param subject pointer to a subject - * @param flag a flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) - * @param ref_value a reference value to compare the subject's value with + * @param flag flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare the subject's value with * @return pointer to the created observer */ lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); @@ -301,8 +302,8 @@ lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, l * Set an object flag if an integer subject's value is not equal to a reference value, clear the flag otherwise * @param obj pointer to an object * @param subject pointer to a subject - * @param flag a flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) - * @param ref_value a reference value to compare the subject's value with + * @param flag flag to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare the subject's value with * @return pointer to the created observer */ lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, @@ -312,8 +313,8 @@ lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subjec * Set an object state if an integer subject's value is equal to a reference value, clear the flag otherwise * @param obj pointer to an object * @param subject pointer to a subject - * @param flag a state to set or clear (e.g. `LV_STATE_CHECKED`) - * @param ref_value a reference value to compare the subject's value with + * @param state state to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare the subject's value with * @return pointer to the created observer */ lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); @@ -322,29 +323,28 @@ lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, * Set an object state if an integer subject's value is not equal to a reference value, clear the flag otherwise * @param obj pointer to an object * @param subject pointer to a subject - * @param flag a state to set or clear (e.g. `LV_STATE_CHECKED`) - * @param ref_value a reference value to compare the subject's value with + * @param state state to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare the subject's value with * @return pointer to the created observer */ lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); -#if LV_USE_BUTTON /** - * Set an integer subject to 1 when a button is checked and set it 0 when unchecked. - * @param obj pointer to a button + * Set an integer subject to 1 when an object is checked and set it 0 when unchecked. + * @param obj pointer to an object * @param subject pointer to a subject * @return pointer to the created observer + * @note Ensure the object's `LV_OBJ_FLAG_CHECKABLE` flag is set */ -lv_observer_t * lv_button_bind_checked(lv_obj_t * obj, lv_subject_t * subject); -#endif +lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject); #if LV_USE_LABEL /** * Bind an integer, string, or pointer subject to a label. * @param obj pointer to a label * @param subject pointer to a subject - * @param fmt an optional format string with 1 format specifier (e.g. "%d °C") + * @param fmt optional format string with 1 format specifier (e.g. "%d °C") * or NULL to bind the value directly. * @return pointer to the created observer * @note fmt == NULL can be used only with string and pointer subjects. diff --git a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer_private.h b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer_private.h new file mode 100644 index 000000000..04a7992eb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_observer_private.h + * + */ + +#ifndef LV_OBSERVER_PRIVATE_H +#define LV_OBSERVER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_observer.h" + +#if LV_USE_OBSERVER + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * The observer object: a descriptor returned when subscribing LVGL widgets to subjects + */ +struct lv_observer_t { + lv_subject_t * subject; /**< The observed value */ + lv_observer_cb_t cb; /**< Callback that should be called when the value changes*/ + void * target; /**< A target for the observer, e.g. a widget or style*/ + void * user_data; /**< Additional parameter supplied when subscribing*/ + uint32_t auto_free_user_data : 1; /**< Automatically free user data when the observer is removed */ + uint32_t notified : 1; /**< Mark if this observer was already notified*/ + uint32_t for_obj : 1; /**< `target` is an `lv_obj_t *`*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OBSERVER */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBSERVER_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.c b/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.c index 021467bea..f3f182b8d 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.c +++ b/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.c @@ -6,12 +6,14 @@ /********************* * INCLUDES *********************/ +#include "../../draw/lv_draw_private.h" +#include "../../core/lv_obj_draw_private.h" #include "lv_snapshot.h" #if LV_USE_SNAPSHOT #include #include "../../display/lv_display.h" -#include "../../core/lv_refr.h" +#include "../../core/lv_refr_private.h" #include "../../display/lv_display_private.h" #include "../../stdlib/lv_string.h" @@ -47,7 +49,7 @@ lv_draw_buf_t * lv_snapshot_create_draw_buf(lv_obj_t * obj, lv_color_format_t cf lv_obj_update_layout(obj); int32_t w = lv_obj_get_width(obj); int32_t h = lv_obj_get_height(obj); - int32_t ext_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_size = lv_obj_get_ext_draw_size(obj); w += ext_size * 2; h += ext_size * 2; if(w == 0 || h == 0) return NULL; @@ -60,7 +62,7 @@ lv_result_t lv_snapshot_reshape_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_bu lv_obj_update_layout(obj); int32_t w = lv_obj_get_width(obj); int32_t h = lv_obj_get_height(obj); - int32_t ext_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_size = lv_obj_get_ext_draw_size(obj); w += ext_size * 2; h += ext_size * 2; if(w == 0 || h == 0) return LV_RESULT_INVALID; @@ -80,6 +82,8 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l case LV_COLOR_FORMAT_RGB888: case LV_COLOR_FORMAT_XRGB8888: case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_L8: + case LV_COLOR_FORMAT_I1: break; default: LV_LOG_WARN("Not supported color format"); @@ -95,7 +99,7 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l lv_area_t snapshot_area; int32_t w = draw_buf->header.w; int32_t h = draw_buf->header.h; - int32_t ext_size = _lv_obj_get_ext_draw_size(obj); + int32_t ext_size = lv_obj_get_ext_draw_size(obj); lv_obj_get_coords(obj, &snapshot_area); lv_area_increase(&snapshot_area, ext_size, ext_size); @@ -109,22 +113,26 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l layer.buf_area.y2 = snapshot_area.y1 + h - 1; layer.color_format = cf; layer._clip_area = snapshot_area; + layer.phy_clip_area = snapshot_area; +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_matrix_identity(&layer.matrix); +#endif - lv_display_t * disp_old = _lv_refr_get_disp_refreshing(); + lv_display_t * disp_old = lv_refr_get_disp_refreshing(); lv_display_t * disp_new = lv_obj_get_display(obj); lv_layer_t * layer_old = disp_new->layer_head; disp_new->layer_head = &layer; - _lv_refr_set_disp_refreshing(disp_new); + lv_refr_set_disp_refreshing(disp_new); lv_obj_redraw(&layer, obj); while(layer.draw_task_head) { lv_draw_dispatch_wait_for_request(); - lv_draw_dispatch_layer(NULL, &layer); + lv_draw_dispatch(); } disp_new->layer_head = layer_old; - _lv_refr_set_disp_refreshing(disp_old); + lv_refr_set_disp_refreshing(disp_old); return LV_RESULT_OK; } @@ -143,6 +151,26 @@ lv_draw_buf_t * lv_snapshot_take(lv_obj_t * obj, lv_color_format_t cf) return draw_buf; } +void lv_snapshot_free(lv_image_dsc_t * dsc) +{ + LV_LOG_WARN("Deprecated API, use lv_draw_buf_destroy directly."); + lv_draw_buf_destroy((lv_draw_buf_t *)dsc); +} + +lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_image_dsc_t * dsc, + void * buf, + uint32_t buf_size) +{ + lv_draw_buf_t draw_buf; + LV_LOG_WARN("Deprecated API, use lv_snapshot_take_to_draw_buf instead."); + lv_draw_buf_init(&draw_buf, 1, 1, cf, buf_size, buf, buf_size); + lv_result_t res = lv_snapshot_take_to_draw_buf(obj, cf, &draw_buf); + if(res == LV_RESULT_OK) { + lv_memcpy((void *)dsc, &draw_buf, sizeof(lv_image_dsc_t)); + } + return res; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.h b/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.h index f8cd0cae2..90de106cd 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.h +++ b/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.h @@ -13,16 +13,17 @@ extern "C" { /********************* * INCLUDES *********************/ +#include "../../core/lv_obj.h" + +#if LV_USE_SNAPSHOT + #include #include -#include "../../core/lv_obj.h" - /********************* * DEFINES *********************/ -#if LV_USE_SNAPSHOT /********************** * TYPEDEFS **********************/ @@ -72,11 +73,7 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l * Free the snapshot image returned by @ref lv_snapshot_take * @param dsc the image descriptor generated by lv_snapshot_take. */ -static inline void lv_snapshot_free(lv_image_dsc_t * dsc) -{ - LV_LOG_WARN("Deprecated API, use lv_draw_buf_destroy directly."); - lv_draw_buf_destroy((lv_draw_buf_t *)dsc); -} +void lv_snapshot_free(lv_image_dsc_t * dsc); /** * Take snapshot for object with its children, save image info to provided buffer. @@ -88,19 +85,9 @@ static inline void lv_snapshot_free(lv_image_dsc_t * dsc) * @return LV_RESULT_OK on success, LV_RESULT_INVALID on error. * @deprecated Use lv_snapshot_take_to_draw_buf instead. */ -static inline lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_image_dsc_t * dsc, - void * buf, - uint32_t buf_size) -{ - lv_draw_buf_t draw_buf; - LV_LOG_WARN("Deprecated API, use lv_snapshot_take_to_draw_buf instead."); - lv_draw_buf_init(&draw_buf, 1, 1, cf, buf_size, buf, buf_size); - lv_result_t res = lv_snapshot_take_to_draw_buf(obj, cf, &draw_buf); - if(res == LV_RESULT_OK) { - lv_memcpy((void *)dsc, &draw_buf, sizeof(lv_image_dsc_t)); - } - return res; -} +lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_image_dsc_t * dsc, + void * buf, + uint32_t buf_size); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c index a9f311fbc..1814dddf9 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c +++ b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c @@ -7,7 +7,8 @@ * INCLUDES *********************/ -#include "lv_sysmon.h" +#include "lv_sysmon_private.h" +#include "../../misc/lv_timer_private.h" #if LV_USE_SYSMON @@ -15,26 +16,17 @@ #include "../../misc/lv_async.h" #include "../../stdlib/lv_string.h" #include "../../widgets/label/lv_label.h" +#include "../../display/lv_display_private.h" /********************* * DEFINES *********************/ -#define MY_CLASS (&lv_sysmon_class) - -#define SYSMON_REFR_PERIOD_DEF 300 /* ms */ - -#if defined(LV_USE_PERF_MONITOR) && LV_USE_PERF_MONITOR - #define sysmon_perf LV_GLOBAL_DEFAULT()->sysmon_perf - #define _USE_PERF_MONITOR 1 -#else - #define _USE_PERF_MONITOR 0 +#ifndef LV_SYSMON_REFR_PERIOD_DEF + #define LV_SYSMON_REFR_PERIOD_DEF 300 /* ms */ #endif -#if defined(LV_USE_MEM_MONITOR) && LV_USE_MEM_MONITOR +#if LV_USE_MEM_MONITOR #define sysmon_mem LV_GLOBAL_DEFAULT()->sysmon_mem - #define _USE_MEM_MONITOR 1 -#else - #define _USE_MEM_MONITOR 0 #endif /********************** @@ -45,12 +37,13 @@ * STATIC PROTOTYPES **********************/ -#if _USE_PERF_MONITOR +#if LV_USE_PERF_MONITOR static void perf_update_timer_cb(lv_timer_t * t); static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject); + static void perf_monitor_disp_event_cb(lv_event_t * e); #endif -#if _USE_MEM_MONITOR +#if LV_USE_MEM_MONITOR static void mem_update_timer_cb(lv_timer_t * t); static void mem_observer_cb(lv_observer_t * observer, lv_subject_t * subject); #endif @@ -67,36 +60,33 @@ * GLOBAL FUNCTIONS **********************/ -void _lv_sysmon_builtin_init(void) +void lv_sysmon_builtin_init(void) { -#if _USE_PERF_MONITOR - static lv_sysmon_perf_info_t perf_info; - lv_subject_init_pointer(&sysmon_perf.subject, &perf_info); - sysmon_perf.timer = lv_timer_create(perf_update_timer_cb, SYSMON_REFR_PERIOD_DEF, &perf_info); -#endif -#if _USE_MEM_MONITOR +#if LV_USE_MEM_MONITOR static lv_mem_monitor_t mem_info; lv_subject_init_pointer(&sysmon_mem.subject, &mem_info); - sysmon_mem.timer = lv_timer_create(mem_update_timer_cb, SYSMON_REFR_PERIOD_DEF, &mem_info); + sysmon_mem.timer = lv_timer_create(mem_update_timer_cb, LV_SYSMON_REFR_PERIOD_DEF, &mem_info); #endif } -void _lv_sysmon_builtin_deinit(void) +void lv_sysmon_builtin_deinit(void) { -#if _USE_PERF_MONITOR - lv_timer_delete(sysmon_perf.timer); -#endif - -#if _USE_MEM_MONITOR +#if LV_USE_MEM_MONITOR lv_timer_delete(sysmon_mem.timer); #endif } -lv_obj_t * lv_sysmon_create(lv_obj_t * parent) +lv_obj_t * lv_sysmon_create(lv_display_t * disp) { LV_LOG_INFO("begin"); - lv_obj_t * label = lv_label_create(parent); + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return NULL; + } + + lv_obj_t * label = lv_label_create(lv_display_get_layer_sys(disp)); lv_obj_set_style_bg_opa(label, LV_OPA_50, 0); lv_obj_set_style_bg_color(label, lv_color_black(), 0); lv_obj_set_style_text_color(label, lv_color_white(), 0); @@ -105,16 +95,94 @@ lv_obj_t * lv_sysmon_create(lv_obj_t * parent) return label; } +#if LV_USE_PERF_MONITOR + +void lv_sysmon_show_performance(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return; + } + + disp->perf_label = lv_sysmon_create(disp); + if(disp->perf_label == NULL) { + LV_LOG_WARN("Couldn't create sysmon"); + return; + } + + lv_subject_init_pointer(&disp->perf_sysmon_backend.subject, &disp->perf_sysmon_info); + lv_obj_align(disp->perf_label, LV_USE_PERF_MONITOR_POS, 0, 0); + lv_subject_add_observer_obj(&disp->perf_sysmon_backend.subject, perf_observer_cb, disp->perf_label, NULL); + disp->perf_sysmon_backend.timer = lv_timer_create(perf_update_timer_cb, LV_SYSMON_REFR_PERIOD_DEF, disp); + lv_display_add_event_cb(disp, perf_monitor_disp_event_cb, LV_EVENT_ALL, NULL); + +#if LV_USE_PERF_MONITOR_LOG_MODE + lv_obj_add_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN); +#else + lv_obj_remove_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN); +#endif +} + +void lv_sysmon_hide_performance(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return; + } + + lv_obj_add_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN); +} + +#endif + +#if LV_USE_MEM_MONITOR + +void lv_sysmon_show_memory(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return; + } + + disp->mem_label = lv_sysmon_create(disp); + if(disp->mem_label == NULL) { + LV_LOG_WARN("Couldn't create sysmon"); + return; + } + + lv_obj_align(disp->mem_label, LV_USE_MEM_MONITOR_POS, 0, 0); + lv_subject_add_observer_obj(&sysmon_mem.subject, mem_observer_cb, disp->mem_label, NULL); + + lv_obj_remove_flag(disp->mem_label, LV_OBJ_FLAG_HIDDEN); +} + +void lv_sysmon_hide_memory(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return; + } + + lv_obj_add_flag(disp->mem_label, LV_OBJ_FLAG_HIDDEN); +} + +#endif + /********************** * STATIC FUNCTIONS **********************/ -#if _USE_PERF_MONITOR +#if LV_USE_PERF_MONITOR static void perf_monitor_disp_event_cb(lv_event_t * e) { + lv_display_t * disp = lv_event_get_target(e); lv_event_code_t code = lv_event_get_code(e); - lv_sysmon_perf_info_t * info = (lv_sysmon_perf_info_t *)lv_subject_get_pointer(&sysmon_perf.subject); + lv_sysmon_perf_info_t * info = &disp->perf_sysmon_info; switch(code) { case LV_EVENT_REFR_START: @@ -152,6 +220,10 @@ static void perf_monitor_disp_event_cb(lv_event_t * e) info->measured.flush_not_in_render_elaps_sum += lv_tick_elaps(info->measured.flush_not_in_render_start); } break; + case LV_EVENT_DELETE: + lv_timer_delete(disp->perf_sysmon_backend.timer); + lv_subject_deinit(&disp->perf_sysmon_backend.subject); + break; default: break; } @@ -159,24 +231,11 @@ static void perf_monitor_disp_event_cb(lv_event_t * e) static void perf_update_timer_cb(lv_timer_t * t) { - /*Wait for a display*/ - if(!sysmon_perf.inited && lv_display_get_default()) { - lv_display_add_event_cb(lv_display_get_default(), perf_monitor_disp_event_cb, LV_EVENT_ALL, NULL); - - lv_obj_t * obj1 = lv_sysmon_create(lv_layer_sys()); - lv_obj_align(obj1, LV_USE_PERF_MONITOR_POS, 0, 0); - lv_subject_add_observer_obj(&sysmon_perf.subject, perf_observer_cb, obj1, NULL); -#if LV_USE_PERF_MONITOR_LOG_MODE - lv_obj_add_flag(obj1, LV_OBJ_FLAG_HIDDEN); -#endif - sysmon_perf.inited = true; - } - - if(!sysmon_perf.inited) return; + lv_display_t * disp = lv_timer_get_user_data(t); uint32_t LV_SYSMON_GET_IDLE(void); - lv_sysmon_perf_info_t * info = lv_timer_get_user_data(t); + lv_sysmon_perf_info_t * info = &disp->perf_sysmon_info; info->calculated.run_cnt++; uint32_t time_since_last_report = lv_tick_elaps(info->measured.last_report_timestamp); @@ -204,7 +263,7 @@ static void perf_update_timer_cb(lv_timer_t * t) info->calculated.fps_avg_total = ((info->calculated.fps_avg_total * (info->calculated.run_cnt - 1)) + info->calculated.fps) / info->calculated.run_cnt; - lv_subject_set_pointer(&sysmon_perf.subject, info); + lv_subject_set_pointer(&disp->perf_sysmon_backend.subject, info); lv_sysmon_perf_info_t prev_info = *info; lv_memzero(info, sizeof(lv_sysmon_perf_info_t)); @@ -244,20 +303,10 @@ static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) #endif -#if _USE_MEM_MONITOR +#if LV_USE_MEM_MONITOR static void mem_update_timer_cb(lv_timer_t * t) { - /*Wait for a display*/ - if(!sysmon_mem.inited && lv_display_get_default()) { - lv_obj_t * obj2 = lv_sysmon_create(lv_layer_sys()); - lv_obj_align(obj2, LV_USE_MEM_MONITOR_POS, 0, 0); - lv_subject_add_observer_obj(&sysmon_mem.subject, mem_observer_cb, obj2, NULL); - sysmon_mem.inited = true; - } - - if(!sysmon_mem.inited) return; - lv_mem_monitor_t * mem_mon = lv_timer_get_user_data(t); lv_mem_monitor(mem_mon); lv_subject_set_pointer(&sysmon_mem.subject, mem_mon); diff --git a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.h b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.h index 849e4d86d..0859c064d 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.h +++ b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.h @@ -35,72 +35,48 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct { - lv_subject_t subject; - lv_timer_t * timer; - bool inited; -} lv_sysmon_backend_data_t; - -#if LV_USE_PERF_MONITOR -typedef struct { - struct { - bool inited; - uint32_t refr_start; - uint32_t refr_interval_sum; - uint32_t refr_elaps_sum; - uint32_t refr_cnt; - uint32_t render_start; - uint32_t render_elaps_sum; /*Contains the flush time too*/ - uint32_t render_cnt; - uint32_t flush_in_render_start; - uint32_t flush_in_render_elaps_sum; - uint32_t flush_not_in_render_start; - uint32_t flush_not_in_render_elaps_sum; - uint32_t last_report_timestamp; - uint32_t render_in_progress : 1; - } measured; - - struct { - uint32_t fps; - uint32_t cpu; - uint32_t refr_avg_time; - uint32_t render_avg_time; /**< Pure rendering time without flush time*/ - uint32_t flush_avg_time; /**< Pure flushing time without rendering time*/ - uint32_t cpu_avg_total; - uint32_t fps_avg_total; - uint32_t run_cnt; - } calculated; - -} lv_sysmon_perf_info_t; -#endif - /********************** * GLOBAL PROTOTYPES **********************/ /** - * Create a system monitor object. - * @param parent pointer to an object, it will be the parent of the new system monitor - * @return pointer to the new system monitor object + * Create a new system monitor label + * @param disp create the sys. mon. on this display's system layer + * @return the create label */ -lv_obj_t * lv_sysmon_create(lv_obj_t * parent); +lv_obj_t * lv_sysmon_create(lv_display_t * disp); + +#if LV_USE_PERF_MONITOR /** - * Set the refresh period of the system monitor object - * @param obj pointer to a system monitor object - * @param period the refresh period in milliseconds + * Show system performance monitor: CPU usage and FPS count + * @param disp target display, NULL: use the default displays */ -void lv_sysmon_set_refr_period(lv_obj_t * obj, uint32_t period); +void lv_sysmon_show_performance(lv_display_t * disp); /** - * Initialize built-in system monitor, such as performance and memory monitor. + * Hide system performance monitor + * @param disp target display, NULL: use the default */ -void _lv_sysmon_builtin_init(void); +void lv_sysmon_hide_performance(lv_display_t * disp); + +#endif /*LV_USE_PERF_MONITOR*/ + +#if LV_USE_MEM_MONITOR /** - * DeInitialize built-in system monitor, such as performance and memory monitor. + * Show system memory monitor: used memory and the memory fragmentation + * @param disp target display, NULL: use the default displays */ -void _lv_sysmon_builtin_deinit(void); +void lv_sysmon_show_memory(lv_display_t * disp); + +/** + * Hide system memory monitor + * @param disp target display, NULL: use the default displays + */ +void lv_sysmon_hide_memory(lv_display_t * disp); + +#endif /*LV_USE_MEM_MONITOR*/ /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon_private.h b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon_private.h new file mode 100644 index 000000000..08d6156d3 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon_private.h @@ -0,0 +1,91 @@ +/** + * @file lv_sysmon_private.h + * + */ + +#ifndef LV_SYSMON_PRIVATE_H +#define LV_SYSMON_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_sysmon.h" + +#if LV_USE_SYSMON + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_sysmon_backend_data_t { + lv_subject_t subject; + lv_timer_t * timer; +}; + +#if LV_USE_PERF_MONITOR +struct lv_sysmon_perf_info_t { + struct { + bool inited; + uint32_t refr_start; + uint32_t refr_interval_sum; + uint32_t refr_elaps_sum; + uint32_t refr_cnt; + uint32_t render_start; + uint32_t render_elaps_sum; /*Contains the flush time too*/ + uint32_t render_cnt; + uint32_t flush_in_render_start; + uint32_t flush_in_render_elaps_sum; + uint32_t flush_not_in_render_start; + uint32_t flush_not_in_render_elaps_sum; + uint32_t last_report_timestamp; + uint32_t render_in_progress : 1; + } measured; + + struct { + uint32_t fps; + uint32_t cpu; + uint32_t refr_avg_time; + uint32_t render_avg_time; /**< Pure rendering time without flush time*/ + uint32_t flush_avg_time; /**< Pure flushing time without rendering time*/ + uint32_t cpu_avg_total; + uint32_t fps_avg_total; + uint32_t run_cnt; + } calculated; + +}; +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize built-in system monitor, such as performance and memory monitor. + */ +void lv_sysmon_builtin_init(void); + +/** + * DeInitialize built-in system monitor, such as performance and memory monitor. + */ +void lv_sysmon_builtin_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SYSMON */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SYSMON_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite.h b/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite.h index 2f970fbca..abbd6e86a 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite.h +++ b/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite.h @@ -32,9 +32,16 @@ extern "C" { #endif +/** + * causes MSVC error C1189. + * Not needed because "The __inline keyword is equivalent to inline." + * See: https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170 +*/ +/* #if defined(_MSC_VER) #define inline __inline #endif +*/ #include #include @@ -567,7 +574,7 @@ typedef unsigned int vg_lite_color_t; typedef enum vg_lite_index_endian { VG_LITE_INDEX_LITTLE_ENDIAN, /*! Parse the index pixel from low to high, - *! when using index1, the parsing order is bit0~bit7. + *! when using index1, the parsing order is bit0~bit7. *! when using index2, the parsing order is bit0:1,bit2:3,bit4:5.bit6:7. *! when using index4, the parsing order is bit0:3,bit4:7. */ @@ -810,7 +817,7 @@ typedef unsigned int vg_lite_color_t; vg_lite_paint_type_t paintType; /*! Get paintcolor from different paint types. */ vg_lite_uint8_t fc_enable; /*! enable im fastclear. */ vg_lite_uint8_t scissor_layer; /*! The buffer is scissor buffer. */ - vg_lite_uint8_t premultiplied; /*! The RGB pixel values are alpha-premultipled */ + vg_lite_uint8_t premultiplied; /*! The RGB pixel values are alpha-premultiplied */ } vg_lite_buffer_t; /* Memory allocation info by kernel. */ @@ -919,14 +926,14 @@ typedef unsigned int vg_lite_color_t; /* Colorkey definition */ typedef struct vg_lite_color_key { - vg_lite_uint8_t enable; /*! The color key is effective only when "enable" is ture, */ - vg_lite_uint8_t low_r; /*! The R chanel of low_rgb. */ - vg_lite_uint8_t low_g; /*! The G chanel of low_rgb. */ - vg_lite_uint8_t low_b; /*! The B chanel of low_rgb. */ + vg_lite_uint8_t enable; /*! The color key is effective only when "enable" is true, */ + vg_lite_uint8_t low_r; /*! The R channel of low_rgb. */ + vg_lite_uint8_t low_g; /*! The G channel of low_rgb. */ + vg_lite_uint8_t low_b; /*! The B channel of low_rgb. */ vg_lite_uint8_t alpha; /*! The alpha channel to replace destination pixel alpha channel.*/ - vg_lite_uint8_t hign_r; /*! The R chanel of hign_rgb. */ - vg_lite_uint8_t hign_g; /*! The G chanel of hign_rgb. */ - vg_lite_uint8_t hign_b; /*! The B chanel of hign_rgb. */ + vg_lite_uint8_t hign_r; /*! The R channel of hign_rgb. */ + vg_lite_uint8_t hign_g; /*! The G channel of hign_rgb. */ + vg_lite_uint8_t hign_b; /*! The B channel of hign_rgb. */ } vg_lite_color_key_t; /* Four colorkey definition. @@ -1274,7 +1281,7 @@ typedef unsigned int vg_lite_color_t; /* Setup 3x3 gaussian blur weight values to filter image pixels. * - * Paramters w0, w1, w2 define a 3x3 gaussian blur weight matrix as below + * Parameters w0, w1, w2 define a 3x3 gaussian blur weight matrix as below * * | w2 w1 w2 | * | w1 w0 w1 | @@ -1377,4 +1384,4 @@ typedef unsigned int vg_lite_color_t; #ifdef __cplusplus } #endif -#endif /* _vg_lite_h_ */ \ No newline at end of file +#endif /* _vg_lite_h_ */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_matrix.c b/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_matrix.c index a6e57d104..42f8ce38b 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_matrix.c +++ b/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_matrix.c @@ -129,7 +129,7 @@ vg_lite_error_t vg_lite_rotate(vg_lite_float_t degrees, vg_lite_matrix_t * matri /* Convert degrees into radians. */ vg_lite_float_t angle = (degrees / 180.0f) * 3.141592654f; - /* Compuet cosine and sine values. */ + /* Compute cosine and sine values. */ vg_lite_float_t cos_angle = cosf(angle); vg_lite_float_t sin_angle = sinf(angle); diff --git a/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_tvg.cpp b/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_tvg.cpp index 97c63d71d..28338be96 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_tvg.cpp +++ b/lib/libesp32_lvgl/lvgl/src/others/vg_lite_tvg/vg_lite_tvg.cpp @@ -271,6 +271,7 @@ static FillRule fill_rule_conv(vg_lite_fill_t fill); static BlendMethod blend_method_conv(vg_lite_blend_t blend); static StrokeCap stroke_cap_conv(vg_lite_cap_style_t cap); static StrokeJoin stroke_join_conv(vg_lite_join_style_t join); +static FillSpread fill_spread_conv(vg_lite_gradient_spreadmode_t spread); static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix); static Result shape_append_rect(std::unique_ptr & shape, const vg_lite_buffer_t * target, const vg_lite_rectangle_t * rect); @@ -309,9 +310,9 @@ static vg_lite_converter conv_bgra8888_to_bgr565( [](vg_color16_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) { while(px_size--) { - dest->red = src->red >> 3; - dest->green = src->green >> 2; - dest->blue = src->blue >> 3; + dest->red = src->red * 0x1F / 0xFF; + dest->green = src->green * 0x3F / 0xFF; + dest->blue = src->blue * 0x1F / 0xFF; src++; dest++; } @@ -321,9 +322,9 @@ static vg_lite_converter conv_bgra8888_to_bgra [](vg_color16_alpha_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) { while(px_size--) { - dest->c.red = src->red >> 3; - dest->c.green = src->green >> 2; - dest->c.blue = src->blue >> 3; + dest->c.red = src->red * 0x1F / 0xFF; + dest->c.green = src->green * 0x3F / 0xFF; + dest->c.blue = src->blue * 0x1F / 0xFF; dest->alpha = src->alpha; src++; dest++; @@ -334,9 +335,9 @@ static vg_lite_converter conv_bgr565_to_bgra8888( [](vg_color32_t * dest, const vg_color16_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) { while(px_size--) { - dest->red = src->red << 3; - dest->green = src->green << 2; - dest->blue = src->blue << 3; + dest->red = src->red * 0xFF / 0x1F; + dest->green = src->green * 0xFF / 0x3F; + dest->blue = src->blue * 0xFF / 0x1F; dest->alpha = 0xFF; src++; dest++; @@ -347,9 +348,9 @@ static vg_lite_converter conv_bgra5658_to_bgra [](vg_color32_t * dest, const vg_color16_alpha_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) { while(px_size--) { - dest->red = src->c.red << 3; - dest->green = src->c.green << 2; - dest->blue = src->c.blue << 3; + dest->red = src->c.red * 0xFF / 0x1F; + dest->green = src->c.green * 0xFF / 0x3F; + dest->blue = src->c.blue * 0xFF / 0x1F; dest->alpha = src->alpha; src++; dest++; @@ -462,7 +463,14 @@ extern "C" { vg_lite_uint32_t stride = VG_LITE_ALIGN((buffer->width * mul / div), align); buffer->stride = stride; - buffer->memory = aligned_alloc(LV_VG_LITE_THORVG_BUF_ADDR_ALIGN, stride * buffer->height); + + /* Size must be multiple of align, See: https://en.cppreference.com/w/c/memory/aligned_alloc */ + size_t size = VG_LITE_ALIGN(buffer->height * stride, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN); +#ifndef _WIN32 + buffer->memory = aligned_alloc(LV_VG_LITE_THORVG_BUF_ADDR_ALIGN, size); +#else + buffer->memory = _aligned_malloc(size, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN); +#endif LV_ASSERT(buffer->memory); buffer->address = (vg_lite_uint32_t)(uintptr_t)buffer->memory; buffer->handle = buffer->memory; @@ -472,7 +480,11 @@ extern "C" { vg_lite_error_t vg_lite_free(vg_lite_buffer_t * buffer) { LV_ASSERT(buffer->memory); +#ifndef _WIN32 free(buffer->memory); +#else + _aligned_free(buffer->memory); +#endif memset(buffer, 0, sizeof(vg_lite_buffer_t)); return VG_LITE_SUCCESS; } @@ -506,6 +518,7 @@ extern "C" { auto shape = Shape::gen(); TVG_CHECK_RETURN_VG_ERROR(shape_append_rect(shape, target, rectangle)); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(BlendMethod::SrcOver)); TVG_CHECK_RETURN_VG_ERROR(shape->fill(TVG_COLOR(color))); TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); @@ -605,9 +618,9 @@ extern "C" { static void picture_bgra8888_to_bgr565(vg_color16_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) { while(px_size--) { - dest->red = src->red >> 3; - dest->green = src->green >> 2; - dest->blue = src->blue >> 3; + dest->red = src->red * 0x1F / 0xFF; + dest->green = src->green * 0x3F / 0xFF; + dest->blue = src->blue * 0x1F / 0xFF; src++; dest++; } @@ -616,9 +629,9 @@ extern "C" { static void picture_bgra8888_to_bgra5658(vg_color16_alpha_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) { while(px_size--) { - dest->c.red = src->red >> 3; - dest->c.green = src->green >> 2; - dest->c.blue = src->blue >> 3; + dest->c.red = src->red * 0x1F / 0xFF; + dest->c.green = src->green * 0x3F / 0xFF; + dest->c.blue = src->blue * 0x1F / 0xFF; dest->alpha = src->alpha; src++; dest++; @@ -808,6 +821,8 @@ extern "C" { case gcFEATURE_BIT_VG_24BIT: case gcFEATURE_BIT_VG_DITHER: case gcFEATURE_BIT_VG_USE_DST: + case gcFEATURE_BIT_VG_RADIAL_GRADIENT: + case gcFEATURE_BIT_VG_IM_REPEAT_REFLECT: #if LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT case gcFEATURE_BIT_VG_LVGL_SUPPORT: @@ -817,6 +832,10 @@ extern "C" { case gcFEATURE_BIT_VG_YUV_INPUT: #endif +#if LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + case gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT: +#endif + #if LV_VG_LITE_THORVG_16PIXELS_ALIGN case gcFEATURE_BIT_VG_16PIXELS_ALIGN: #endif @@ -839,6 +858,8 @@ extern "C" { return VG_LITE_INVALID_ARGUMENT; } + lv_memzero(path, sizeof(vg_lite_path_t)); + path->format = data_format; path->quality = quality; path->bounding_box[0] = min_x; @@ -1060,7 +1081,7 @@ extern "C" { /* Clamp color. */ ClampColor(COLOR_FROM_RAMP(src_ramp), COLOR_FROM_RAMP(trg_ramp), 0); - /* First stop greater then zero? */ + /* First stop greater than zero? */ if((trg_count == 0) && (src_ramp->stop > 0.0f)) { /* Force the first stop to 0.0f. */ trg_ramp->stop = 0.0f; @@ -1252,6 +1273,49 @@ Empty_sequence_handler: return VG_LITE_SUCCESS; } + vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_ext_linear_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) + { + LV_UNUSED(paint_color); + LV_UNUSED(filter); + + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, path_matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(path_matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + + auto linearGrad = LinearGradient::gen(); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(grad->linear_grad.X0, grad->linear_grad.Y0, grad->linear_grad.X1, + grad->linear_grad.Y1)); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad->matrix))); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(fill_spread_conv(grad->spread_mode))); + + tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS]; + for(vg_lite_uint32_t i = 0; i < grad->ramp_length; i++) { + colorStops[i].offset = grad->color_ramp[i].stop; + colorStops[i].r = grad->color_ramp[i].red * 255.0f; + colorStops[i].g = grad->color_ramp[i].green * 255.0f; + colorStops[i].b = grad->color_ramp[i].blue * 255.0f; + colorStops[i].a = grad->color_ramp[i].alpha * 255.0f; + } + TVG_CHECK_RETURN_VG_ERROR(linearGrad->colorStops(colorStops, grad->ramp_length)); + + TVG_CHECK_RETURN_VG_ERROR(shape->fill(std::move(linearGrad))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; + } + vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t * grad, vg_lite_uint32_t count, vg_lite_color_ramp_t * color_ramp, @@ -1328,7 +1392,7 @@ Empty_sequence_handler: /* Clamp color. */ ClampColor(COLOR_FROM_RAMP(srcRamp), COLOR_FROM_RAMP(trgRamp), 0); - /* First stop greater then zero? */ + /* First stop greater than zero? */ if((trgCount == 0) && (srcRamp->stop > 0.0f)) { /* Force the first stop to 0.0f. */ trgRamp->stop = 0.0f; @@ -1708,8 +1772,8 @@ Empty_sequence_handler: float y_max = y_min + dlen * sinf(angle); LV_LOG_TRACE("linear gradient {%.2f, %.2f} ~ {%.2f, %.2f}", x_min, y_min, x_max, y_max); auto linearGrad = LinearGradient::gen(); - linearGrad->linear(x_min, y_min, x_max, y_max); - linearGrad->spread(FillSpread::Pad); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(x_min, y_min, x_max, y_max)); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(FillSpread::Pad)); tvg::Fill::ColorStop colorStops[VLC_MAX_GRADIENT_STOPS]; for(vg_lite_uint32_t i = 0; i < grad->count; i++) { @@ -1736,15 +1800,37 @@ Empty_sequence_handler: vg_lite_blend_t blend, vg_lite_filter_t filter) { - LV_UNUSED(target); - LV_UNUSED(path); - LV_UNUSED(fill_rule); - LV_UNUSED(path_matrix); - LV_UNUSED(grad); LV_UNUSED(paint_color); - LV_UNUSED(blend); LV_UNUSED(filter); - return VG_LITE_NOT_SUPPORT; + + auto ctx = vg_lite_ctx::get_instance(); + TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + + auto shape = Shape::gen(); + TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, path_matrix)); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(path_matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); + TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + + auto radialGrad = RadialGradient::gen(); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->transform(matrix_conv(&grad->matrix))); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->radial(grad->radial_grad.cx, grad->radial_grad.cy, grad->radial_grad.r)); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->spread(fill_spread_conv(grad->spread_mode))); + + tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS]; + for(vg_lite_uint32_t i = 0; i < grad->ramp_length; i++) { + colorStops[i].offset = grad->color_ramp[i].stop; + colorStops[i].r = grad->color_ramp[i].red * 255.0f; + colorStops[i].g = grad->color_ramp[i].green * 255.0f; + colorStops[i].b = grad->color_ramp[i].blue * 255.0f; + colorStops[i].a = grad->color_ramp[i].alpha * 255.0f; + } + TVG_CHECK_RETURN_VG_ERROR(radialGrad->colorStops(colorStops, grad->ramp_length)); + + TVG_CHECK_RETURN_VG_ERROR(shape->fill(std::move(radialGrad))); + TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape))); + + return VG_LITE_SUCCESS; } vg_lite_error_t vg_lite_set_command_buffer_size(vg_lite_uint32_t size) @@ -1979,6 +2065,20 @@ static StrokeJoin stroke_join_conv(vg_lite_join_style_t join) return StrokeJoin::Bevel; } +static FillSpread fill_spread_conv(vg_lite_gradient_spreadmode_t spread) +{ + switch(spread) { + case VG_LITE_GRADIENT_SPREAD_PAD: + return FillSpread::Pad; + case VG_LITE_GRADIENT_SPREAD_REPEAT: + return FillSpread::Repeat; + case VG_LITE_GRADIENT_SPREAD_REFLECT: + return FillSpread::Reflect; + default: + return FillSpread::Pad; + } +} + static float vlc_get_arg(const void * data, vg_lite_format_t format) { switch(format) { @@ -2054,10 +2154,19 @@ static uint8_t vlc_op_arg_len(uint8_t vlc_op) static Result shape_set_stroke(std::unique_ptr & shape, const vg_lite_path_t * path) { - /* if path is not a stroke, return */ - if(path->path_type == VG_LITE_DRAW_ZERO - || path->path_type == VG_LITE_DRAW_FILL_PATH) { - return Result::Success; + switch(path->path_type) { + case VG_LITE_DRAW_ZERO: + case VG_LITE_DRAW_FILL_PATH: + /* if path is not a stroke, return */ + return Result::Success; + + case VG_LITE_DRAW_STROKE_PATH: + case VG_LITE_DRAW_FILL_STROKE_PATH: + break; + + default: + LV_LOG_ERROR("unknown path type: %d", path->path_type); + return Result::InvalidArguments; } LV_ASSERT_NULL(path->stroke); @@ -2151,8 +2260,8 @@ static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * float x_max = path->bounding_box[2]; float y_max = path->bounding_box[3]; - if(math_equal(x_min, __FLT_MIN__) && math_equal(y_min, __FLT_MIN__) - && math_equal(x_max, __FLT_MAX__) && math_equal(y_max, __FLT_MAX__)) { + if(math_equal(x_min, FLT_MIN) && math_equal(y_min, FLT_MIN) + && math_equal(x_max, FLT_MAX) && math_equal(y_max, FLT_MAX)) { return Result::Success; } diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_mem_core_builtin.c b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_mem_core_builtin.c index b7b707de3..23a218154 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_mem_core_builtin.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_mem_core_builtin.c @@ -86,10 +86,10 @@ void lv_mem_init(void) state.tlsf = lv_tlsf_create_with_pool((void *)LV_MEM_ADR, LV_MEM_SIZE); #endif - _lv_ll_init(&state.pool_ll, sizeof(lv_pool_t)); + lv_ll_init(&state.pool_ll, sizeof(lv_pool_t)); /*Record the first pool*/ - lv_pool_t * pool_p = _lv_ll_ins_tail(&state.pool_ll); + lv_pool_t * pool_p = lv_ll_ins_tail(&state.pool_ll); LV_ASSERT_MALLOC(pool_p); *pool_p = lv_tlsf_get_pool(state.tlsf); @@ -100,7 +100,7 @@ void lv_mem_init(void) void lv_mem_deinit(void) { - _lv_ll_clear(&state.pool_ll); + lv_ll_clear(&state.pool_ll); lv_tlsf_destroy(state.tlsf); #if LV_USE_OS lv_mutex_delete(&state.mutex); @@ -115,7 +115,7 @@ lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes) return NULL; } - lv_pool_t * pool_p = _lv_ll_ins_tail(&state.pool_ll); + lv_pool_t * pool_p = lv_ll_ins_tail(&state.pool_ll); LV_ASSERT_MALLOC(pool_p); *pool_p = new_pool; @@ -125,9 +125,9 @@ lv_mem_pool_t lv_mem_add_pool(void * mem, size_t bytes) void lv_mem_remove_pool(lv_mem_pool_t pool) { lv_pool_t * pool_p; - _LV_LL_READ(&state.pool_ll, pool_p) { + LV_LL_READ(&state.pool_ll, pool_p) { if(*pool_p == pool) { - _lv_ll_remove(&state.pool_ll, pool_p); + lv_ll_remove(&state.pool_ll, pool_p); lv_free(pool_p); lv_tlsf_remove_pool(state.tlsf, pool); return; @@ -201,7 +201,7 @@ void lv_mem_monitor_core(lv_mem_monitor_t * mon_p) LV_TRACE_MEM("begin"); lv_pool_t * pool_p; - _LV_LL_READ(&state.pool_ll, pool_p) { + LV_LL_READ(&state.pool_ll, pool_p) { lv_tlsf_walk_pool(*pool_p, lv_mem_walker, mon_p); } @@ -233,7 +233,7 @@ lv_result_t lv_mem_test_core(void) } lv_pool_t * pool_p; - _LV_LL_READ(&state.pool_ll, pool_p) { + LV_LL_READ(&state.pool_ll, pool_p) { if(lv_tlsf_check_pool(*pool_p)) { LV_LOG_WARN("pool failed"); #if LV_USE_OS diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_sprintf_builtin.c b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_sprintf_builtin.c index d5fc55537..fc34db4d1 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_sprintf_builtin.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_sprintf_builtin.c @@ -552,7 +552,7 @@ static size_t _etoa(out_fct_type out, char * buffer, size_t idx, size_t maxlen, #endif // PRINTF_SUPPORT_FLOAT // internal vsnprintf -static int _lv_vsnprintf(out_fct_type out, char * buffer, const size_t maxlen, const char * format, va_list va) +static int lv_vsnprintf_inner(out_fct_type out, char * buffer, const size_t maxlen, const char * format, va_list va) { unsigned int flags, width, precision, n; size_t idx = 0U; @@ -759,7 +759,7 @@ static int _lv_vsnprintf(out_fct_type out, char * buffer, const size_t maxlen, c va_list copy; va_copy(copy, *vaf->va); - idx += _lv_vsnprintf(out, buffer + idx, maxlen - idx, vaf->fmt, copy); + idx += lv_vsnprintf_inner(out, buffer + idx, maxlen - idx, vaf->fmt, copy); va_end(copy); } else { @@ -873,14 +873,14 @@ int lv_snprintf(char * buffer, size_t count, const char * format, ...) { va_list va; va_start(va, format); - const int ret = _lv_vsnprintf(_out_buffer, buffer, count, format, va); + const int ret = lv_vsnprintf_inner(_out_buffer, buffer, count, format, va); va_end(va); return ret; } int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va) { - return _lv_vsnprintf(_out_buffer, buffer, count, format, va); + return lv_vsnprintf_inner(_out_buffer, buffer, count, format, va); } #endif /*LV_STDLIB_BUILTIN*/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_string_builtin.c b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_string_builtin.c index a033a78b9..f225adccf 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_string_builtin.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_string_builtin.c @@ -171,6 +171,17 @@ void * LV_ATTRIBUTE_FAST_MEM lv_memmove(void * dst, const void * src, size_t len return dst; } +int lv_memcmp(const void * p1, const void * p2, size_t len) +{ + const char * s1 = (const char *) p1; + const char * s2 = (const char *) p2; + while(--len > 0 && (*s1 == *s2)) { + s1++; + s2++; + } + return *s1 - *s2; +} + /* See https://en.cppreference.com/w/c/string/byte/strlen for reference */ size_t lv_strlen(const char * str) { @@ -180,13 +191,28 @@ size_t lv_strlen(const char * str) return i; } +size_t lv_strlcpy(char * dst, const char * src, size_t dst_size) +{ + size_t i = 0; + if(dst_size > 0) { + for(; i < dst_size - 1 && src[i]; i++) { + dst[i] = src[i]; + } + dst[i] = '\0'; + } + while(src[i]) i++; + return i; +} + char * lv_strncpy(char * dst, const char * src, size_t dst_size) { size_t i; - for(i = 0; i < dst_size - 1 && src[i]; i++) { + for(i = 0; i < dst_size && src[i]; i++) { dst[i] = src[i]; } - dst[i] = '\0'; + for(; i < dst_size; i++) { + dst[i] = '\0'; + } return dst; } @@ -197,7 +223,7 @@ char * lv_strcpy(char * dst, const char * src) return tmp; } -int32_t lv_strcmp(const char * s1, const char * s2) +int lv_strcmp(const char * s1, const char * s2) { while(*s1 && (*s1 == *s2)) { s1++; @@ -212,10 +238,30 @@ char * lv_strdup(const char * src) char * dst = lv_malloc(len); if(dst == NULL) return NULL; - lv_memcpy(dst, src, len); /*do memcpy is faster than strncpy when length is known*/ + lv_memcpy(dst, src, len); /*memcpy is faster than strncpy when length is known*/ return dst; } +char * lv_strcat(char * dst, const char * src) +{ + lv_strcpy(dst + lv_strlen(dst), src); + return dst; +} + +char * lv_strncat(char * dst, const char * src, size_t src_len) +{ + char * tmp = dst; + while(*dst != '\0') { + dst++; + } + while(src_len != 0 && *src != '\0') { + src_len--; + *dst++ = *src++; + } + *dst = '\0'; + return tmp; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.c b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.c index 8910b05ef..4232ae324 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.c @@ -1,11 +1,11 @@ #include "../../lv_conf_internal.h" #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN -#include -#include "lv_tlsf.h" +#include "lv_tlsf_private.h" #include "../../stdlib/lv_string.h" #include "../../misc/lv_log.h" #include "../../misc/lv_assert.h" +#include "../../misc/lv_types.h" #undef printf #define printf LV_LOG_ERROR @@ -80,7 +80,7 @@ && defined (__GNUC_PATCHLEVEL__) #if defined (__SNC__) -/* SNC for Playstation 3. */ +/* SNC for PlayStation 3. */ tlsf_decl int tlsf_ffs(unsigned int word) { @@ -219,16 +219,16 @@ tlsf_decl int tlsf_fls_sizet(size_t size) */ /* Public constants: may be modified. */ -enum tlsf_public { +typedef enum { /* log2 of number of linear subdivisions of block sizes. Larger ** values require more memory in the control structure. Values of ** 4 or 5 are typical. */ SL_INDEX_COUNT_LOG2 = 5, -}; +} tlsf_public; /* Private constants: do not modify. */ -enum tlsf_private { +typedef enum { #if defined (TLSF_64BIT) /* All allocation sizes and addresses are aligned to 8 bytes. */ ALIGN_SIZE_LOG2 = 3, @@ -265,7 +265,7 @@ enum tlsf_private { FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), -}; +} tlsf_private; /* ** Cast and min/max macros. @@ -586,8 +586,8 @@ static void remove_free_block(control_t * control, block_header_t * block, int f { block_header_t * prev = block->prev_free; block_header_t * next = block->next_free; - tlsf_assert(prev && "prev_free field can not be null"); - tlsf_assert(next && "next_free field can not be null"); + tlsf_assert(prev && "prev_free field cannot be null"); + tlsf_assert(next && "next_free field cannot be null"); next->prev_free = prev; prev->next_free = next; diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.h b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.h index 98126636a..4127271db 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.h @@ -41,10 +41,9 @@ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include - #include "../../osal/lv_os.h" #include "../../misc/lv_ll.h" +#include "../../misc/lv_types.h" #if defined(__cplusplus) extern "C" { @@ -55,16 +54,6 @@ extern "C" { typedef void * lv_tlsf_t; typedef void * lv_pool_t; -typedef struct { -#if LV_USE_OS - lv_mutex_t mutex; -#endif - lv_tlsf_t tlsf; - size_t cur_used; - size_t max_used; - lv_ll_t pool_ll; -} lv_tlsf_state_t; - /* Create/destroy a memory pool. */ lv_tlsf_t lv_tlsf_create(void * mem); lv_tlsf_t lv_tlsf_create_with_pool(void * mem, size_t bytes); diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf_private.h b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf_private.h new file mode 100644 index 000000000..036e9d73e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_tlsf_private.h + * + */ + +#ifndef LV_TLSF_PRIVATE_H +#define LV_TLSF_PRIVATE_H + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_tlsf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { +#if LV_USE_OS + lv_mutex_t mutex; +#endif + lv_tlsf_t tlsf; + size_t cur_used; + size_t max_used; + lv_ll_t pool_ll; +} lv_tlsf_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ + +#endif /*LV_TLSF_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/clib/lv_string_clib.c b/lib/libesp32_lvgl/lvgl/src/stdlib/clib/lv_string_clib.c index 359b2e039..fd01b93f9 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/clib/lv_string_clib.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/clib/lv_string_clib.c @@ -50,19 +50,30 @@ void * LV_ATTRIBUTE_FAST_MEM lv_memmove(void * dst, const void * src, size_t len return memmove(dst, src, len); } +int lv_memcmp(const void * p1, const void * p2, size_t len) +{ + return memcmp(p1, p2, len); +} + size_t lv_strlen(const char * str) { return strlen(str); } +size_t lv_strlcpy(char * dst, const char * src, size_t dst_size) +{ + size_t src_len = strlen(src); + if(dst_size > 0) { + size_t copy_size = src_len < dst_size ? src_len : dst_size - 1; + memcpy(dst, src, copy_size); + dst[copy_size] = '\0'; + } + return src_len; +} + char * lv_strncpy(char * dst, const char * src, size_t dest_size) { - if(dest_size > 0) { - dst[0] = '\0'; - strncat(dst, src, dest_size - 1); - } - - return dst; + return strncpy(dst, src, dest_size); } char * lv_strcpy(char * dst, const char * src) @@ -70,7 +81,7 @@ char * lv_strcpy(char * dst, const char * src) return strcpy(dst, src); } -int32_t lv_strcmp(const char * s1, const char * s2) +int lv_strcmp(const char * s1, const char * s2) { return strcmp(s1, s2); } @@ -86,6 +97,16 @@ char * lv_strdup(const char * src) return dst; } +char * lv_strcat(char * dst, const char * src) +{ + return strcat(dst, src); +} + +char * lv_strncat(char * dst, const char * src, size_t src_len) +{ + return strncat(dst, src, src_len); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c index c1ab647e3..bfc887fff 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c @@ -5,7 +5,7 @@ /********************* * INCLUDES *********************/ -#include "lv_mem.h" +#include "lv_mem_private.h" #include "lv_string.h" #include "../misc/lv_assert.h" #include "../misc/lv_log.h" diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h index f66f3d6f0..210c18988 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h @@ -15,9 +15,7 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" -#include -#include -#include +#include "lv_string.h" #include "../misc/lv_types.h" @@ -35,14 +33,14 @@ typedef void * lv_mem_pool_t; * Heap information structure. */ typedef struct { - size_t total_size; /**< Total heap size*/ + size_t total_size; /**< Total heap size */ size_t free_cnt; - size_t free_size; /**< Size of available memory*/ + size_t free_size; /**< Size of available memory */ size_t free_biggest_size; size_t used_cnt; - size_t max_used; /**< Max size of Heap memory used*/ - uint8_t used_pct; /**< Percentage used*/ - uint8_t frag_pct; /**< Amount of fragmentation*/ + size_t max_used; /**< Max size of Heap memory used */ + uint8_t used_pct; /**< Percentage used */ + uint8_t frag_pct; /**< Amount of fragmentation */ } lv_mem_monitor_t; /********************** @@ -112,8 +110,8 @@ void lv_free_core(void * p); void * lv_realloc_core(void * p, size_t new_size); /** - * Used internally to execute a plain malloc operation - * @param size size in bytes to malloc + * Used internally by lv_mem_monitor() to gather LVGL heap state information. + * @param mon_p pointer to lv_mem_monitor_t object to be populated. */ void lv_mem_monitor_core(lv_mem_monitor_t * mon_p); diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem_private.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem_private.h new file mode 100644 index 000000000..9e70ae1af --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem_private.h @@ -0,0 +1,39 @@ +/** + * @file lv_mem_private.h + * + */ + +#ifndef LV_MEM_PRIVATE_H +#define LV_MEM_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_mem.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MEM_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h index cd5a80346..a7f2188d6 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h @@ -1,14 +1,14 @@ /** - * lv_snprintf.h + * @file lv_sprintf.h * */ -#ifndef _LV_SPRINTF_H_ -#define _LV_SPRINTF_H_ +#ifndef LV_SPRINTF_H +#define LV_SPRINTF_H #if defined(__has_include) - #if __has_include() - #include + #if __has_include(LV_INTTYPES_INCLUDE) + #include LV_INTTYPES_INCLUDE /* platform-specific printf format for int32_t, usually "d" or "ld" */ #define LV_PRId32 PRId32 #define LV_PRIu32 PRIu32 @@ -28,9 +28,7 @@ #define LV_PRIX32 "X" #endif -#include -#include -#include +#include "../misc/lv_types.h" #ifdef __cplusplus extern "C" { @@ -44,4 +42,4 @@ int lv_vsnprintf(char * buffer, size_t count, const char * format, va_list va); } /*extern "C"*/ #endif -#endif /* _LV_SPRINTF_H_*/ +#endif /* LV_SPRINTF_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h index 745cd49e5..10aee500f 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h @@ -1,5 +1,5 @@ /** - * @file lv_stringn.h + * @file lv_string.h * */ @@ -14,8 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" -#include -#include +#include "../misc/lv_types.h" /********************* * DEFINES @@ -57,6 +56,15 @@ void lv_memset(void * dst, uint8_t v, size_t len); */ void * lv_memmove(void * dst, const void * src, size_t len); +/** + * @brief This function will compare two memory blocks + * @param p1 Pointer to the first memory block + * @param p2 Pointer to the second memory block + * @param len Number of bytes to compare + * @return The difference between the value of the first unmatching byte. + */ +int lv_memcmp(const void * p1, const void * p2, size_t len); + /** * Same as `memset(dst, 0x00, len)`. * @param dst pointer to the destination buffer @@ -75,11 +83,22 @@ static inline void lv_memzero(void * dst, size_t len) size_t lv_strlen(const char * str); /** - * @brief Copies up to dest_size characters from the string pointed to by src to the character array pointed to by dst. + * @brief Copies up to dst_size-1 (non-null) characters from src to dst. A null terminator is always added. * @param dst Pointer to the destination array where the content is to be copied. * @param src Pointer to the source of data to be copied. - * @param dest_size Maximum number of characters to be copied to dst, including the null character. + * @param dst_size Maximum number of characters to be copied to dst, including the null character. + * @return The length of src. The return value is equivalent to the value returned by lv_strlen(src) + */ +size_t lv_strlcpy(char * dst, const char * src, size_t dst_size); + +/** + * @brief Copies up to dest_size characters from the string pointed to by src to the character array pointed to by dst + * and fills the remaining length with null bytes. + * @param dst Pointer to the destination array where the content is to be copied. + * @param src Pointer to the source of data to be copied. + * @param dest_size Maximum number of characters to be copied to dst. * @return A pointer to the destination array, which is dst. + * @note dst will not be null terminated if dest_size bytes were copied from src before the end of src was reached. */ char * lv_strncpy(char * dst, const char * src, size_t dest_size); @@ -98,7 +117,7 @@ char * lv_strcpy(char * dst, const char * src); * @param s2 pointer to the second string * @return the difference between the value of the first unmatching character. */ -int32_t lv_strcmp(const char * s1, const char * s2); +int lv_strcmp(const char * s1, const char * s2); /** * @brief Duplicate a string by allocating a new one and copying the content. @@ -107,6 +126,27 @@ int32_t lv_strcmp(const char * s1, const char * s2); */ char * lv_strdup(const char * src); +/** + * @brief Copies the string pointed to by src, including the terminating null character, + * to the end of the string pointed to by dst. + * @param dst Pointer to the destination string where the content is to be appended. + * @param src Pointer to the source of data to be copied. + * @return A pointer to the destination string, which is dst. + */ +char * lv_strcat(char * dst, const char * src); + +/** + * @brief Copies up to src_len characters from the string pointed to by src + * to the end of the string pointed to by dst. + * A terminating null character is appended to dst even if no null character + * was encountered in src after src_len characters were copied. + * @param dst Pointer to the destination string where the content is to be appended. + * @param src Pointer to the source of data to be copied. + * @param src_len Maximum number of characters from src to be copied to the end of dst. + * @return A pointer to the destination string, which is dst. + */ +char * lv_strncat(char * dst, const char * src, size_t src_len); + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/micropython/lv_mem_core_micropython.c b/lib/libesp32_lvgl/lvgl/src/stdlib/micropython/lv_mem_core_micropython.c index 69c8bd681..a671b5e1c 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/micropython/lv_mem_core_micropython.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/micropython/lv_mem_core_micropython.c @@ -62,17 +62,32 @@ void lv_mem_remove_pool(lv_mem_pool_t pool) void * lv_malloc_core(size_t size) { +#if MICROPY_MALLOC_USES_ALLOCATED_SIZE + return gc_alloc(size, true); +#else return m_malloc(size); +#endif } void * lv_realloc_core(void * p, size_t new_size) { + +#if MICROPY_MALLOC_USES_ALLOCATED_SIZE + return gc_realloc(p, new_size, true); +#else return m_realloc(p, new_size); +#endif } void lv_free_core(void * p) { + +#if MICROPY_MALLOC_USES_ALLOCATED_SIZE + gc_free(p); + +#else m_free(p); +#endif } void lv_mem_monitor_core(lv_mem_monitor_t * mon_p) diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/rtthread/lv_string_rtthread.c b/lib/libesp32_lvgl/lvgl/src/stdlib/rtthread/lv_string_rtthread.c index 86949814c..2ab0a4717 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/rtthread/lv_string_rtthread.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/rtthread/lv_string_rtthread.c @@ -55,6 +55,22 @@ size_t lv_strlen(const char * str) return rt_strlen(str); } +int lv_memcmp(const void * p1, const void * p2, size_t len) +{ + return rt_memcmp(p1, p2, len); +} + +size_t lv_strlcpy(char * dst, const char * src, size_t dst_size) +{ + size_t src_len = lv_strlen(src); + if(dst_size > 0) { + size_t copy_size = src_len < dst_size ? src_len : dst_size - 1; + lv_memcpy(dst, src, copy_size); + dst[copy_size] = '\0'; + } + return src_len; +} + char * lv_strncpy(char * dst, const char * src, size_t dest_size) { return rt_strncpy(dst, src, dest_size); @@ -65,24 +81,39 @@ char * lv_strcpy(char * dst, const char * src) return rt_strcpy(dst, src); } -int32_t lv_strcmp(const char * s1, const char * s2) +int lv_strcmp(const char * s1, const char * s2) { return rt_strcmp(s1, s2); } char * lv_strdup(const char * src) { - /*strdup uses rt_malloc, so use the lv_malloc when LV_USE_STDLIB_MALLOC is not LV_STDLIB_RTTHREAD */ -#if LV_USE_STDLIB_MALLOC != LV_STDLIB_RTTHREAD size_t len = lv_strlen(src) + 1; char * dst = lv_malloc(len); if(dst == NULL) return NULL; - lv_memcpy(dst, src, len); /*do memcpy is faster than strncpy when length is known*/ + lv_memcpy(dst, src, len); /*memcpy is faster than strncpy when length is known*/ return dst; -#else - return rt_strdup(src); -#endif +} + +char * lv_strcat(char * dst, const char * src) +{ + /*Since RT-thread does not have rt_strcat, + the following code is used instead.*/ + lv_strcpy(dst + lv_strlen(dst), src); + return dst; +} + +char * lv_strncat(char * dst, const char * src, size_t src_len) +{ + char * tmp = dst; + dst += lv_strlen(dst); + while(src_len != 0 && *src != '\0') { + src_len--; + *dst++ = *src++; + } + *dst = '\0'; + return tmp; } /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/themes/default/lv_theme_default.c b/lib/libesp32_lvgl/lvgl/src/themes/default/lv_theme_default.c index 66494ba92..fa1266219 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/default/lv_theme_default.c +++ b/lib/libesp32_lvgl/lvgl/src/themes/default/lv_theme_default.c @@ -10,7 +10,7 @@ #if LV_USE_THEME_DEFAULT -#include "../lv_theme.h" +#include "../lv_theme_private.h" #include "../../misc/lv_color.h" #include "../../core/lv_global.h" @@ -24,7 +24,7 @@ typedef struct _my_theme_t my_theme_t; #define theme_def (*(my_theme_t **)(&LV_GLOBAL_DEFAULT()->theme_default)) #define MODE_DARK 1 -#define RADIUS_DEFAULT _LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 12 : 8) +#define RADIUS_DEFAULT LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 12 : 8) /*SCREEN*/ #define LIGHT_COLOR_SCR lv_palette_lighten(LV_PALETTE_GREY, 4) @@ -37,12 +37,12 @@ typedef struct _my_theme_t my_theme_t; #define DARK_COLOR_GREY lv_color_hex(0x2f3237) #define TRANSITION_TIME LV_THEME_DEFAULT_TRANSITION_TIME -#define BORDER_WIDTH _LV_DPX_CALC(theme->disp_dpi, 2) -#define OUTLINE_WIDTH _LV_DPX_CALC(theme->disp_dpi, 3) +#define BORDER_WIDTH LV_DPX_CALC(theme->disp_dpi, 2) +#define OUTLINE_WIDTH LV_DPX_CALC(theme->disp_dpi, 3) -#define PAD_DEF _LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 24 : theme->disp_size == DISP_MEDIUM ? 20 : 16) -#define PAD_SMALL _LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 14 : theme->disp_size == DISP_MEDIUM ? 12 : 10) -#define PAD_TINY _LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 8 : theme->disp_size == DISP_MEDIUM ? 6 : 2) +#define PAD_DEF LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 24 : theme->disp_size == DISP_MEDIUM ? 20 : 16) +#define PAD_SMALL LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 14 : theme->disp_size == DISP_MEDIUM ? 12 : 10) +#define PAD_TINY LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 8 : theme->disp_size == DISP_MEDIUM ? 6 : 2) /********************** * TYPEDEFS @@ -247,8 +247,8 @@ static void style_init(my_theme_t * theme) lv_style_set_bg_color(&theme->styles.scrollbar, sb_color); lv_style_set_radius(&theme->styles.scrollbar, LV_RADIUS_CIRCLE); - lv_style_set_pad_all(&theme->styles.scrollbar, _LV_DPX_CALC(theme->disp_dpi, 7)); - lv_style_set_width(&theme->styles.scrollbar, _LV_DPX_CALC(theme->disp_dpi, 5)); + lv_style_set_pad_all(&theme->styles.scrollbar, LV_DPX_CALC(theme->disp_dpi, 7)); + lv_style_set_width(&theme->styles.scrollbar, LV_DPX_CALC(theme->disp_dpi, 5)); lv_style_set_bg_opa(&theme->styles.scrollbar, LV_OPA_40); #if TRANSITION_TIME lv_style_set_transition(&theme->styles.scrollbar, &theme->trans_normal); @@ -278,7 +278,7 @@ static void style_init(my_theme_t * theme) lv_style_set_pad_row(&theme->styles.card, PAD_SMALL); lv_style_set_pad_column(&theme->styles.card, PAD_SMALL); lv_style_set_line_color(&theme->styles.card, lv_palette_main(LV_PALETTE_GREY)); - lv_style_set_line_width(&theme->styles.card, _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_line_width(&theme->styles.card, LV_DPX_CALC(theme->disp_dpi, 1)); style_init_reset(&theme->styles.outline_primary); lv_style_set_outline_color(&theme->styles.outline_primary, theme->base.color_primary); @@ -293,20 +293,20 @@ static void style_init(my_theme_t * theme) style_init_reset(&theme->styles.btn); lv_style_set_radius(&theme->styles.btn, - _LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 16 : theme->disp_size == DISP_MEDIUM ? 12 : 8)); + LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 16 : theme->disp_size == DISP_MEDIUM ? 12 : 8)); lv_style_set_bg_opa(&theme->styles.btn, LV_OPA_COVER); lv_style_set_bg_color(&theme->styles.btn, theme->color_grey); if(!(theme->base.flags & MODE_DARK)) { lv_style_set_shadow_color(&theme->styles.btn, lv_palette_main(LV_PALETTE_GREY)); lv_style_set_shadow_width(&theme->styles.btn, LV_DPX(3)); lv_style_set_shadow_opa(&theme->styles.btn, LV_OPA_50); - lv_style_set_shadow_offset_y(&theme->styles.btn, _LV_DPX_CALC(theme->disp_dpi, LV_DPX(4))); + lv_style_set_shadow_offset_y(&theme->styles.btn, LV_DPX_CALC(theme->disp_dpi, LV_DPX(4))); } lv_style_set_text_color(&theme->styles.btn, theme->color_text); lv_style_set_pad_hor(&theme->styles.btn, PAD_DEF); lv_style_set_pad_ver(&theme->styles.btn, PAD_SMALL); - lv_style_set_pad_column(&theme->styles.btn, _LV_DPX_CALC(theme->disp_dpi, 5)); - lv_style_set_pad_row(&theme->styles.btn, _LV_DPX_CALC(theme->disp_dpi, 5)); + lv_style_set_pad_column(&theme->styles.btn, LV_DPX_CALC(theme->disp_dpi, 5)); + lv_style_set_pad_row(&theme->styles.btn, LV_DPX_CALC(theme->disp_dpi, 5)); lv_color_filter_dsc_init(&theme->dark_filter, dark_color_filter_cb); lv_color_filter_dsc_init(&theme->grey_filter, grey_filter_cb); @@ -333,11 +333,11 @@ static void style_init(my_theme_t * theme) lv_style_set_pad_gap(&theme->styles.pad_small, PAD_SMALL); style_init_reset(&theme->styles.pad_gap); - lv_style_set_pad_row(&theme->styles.pad_gap, _LV_DPX_CALC(theme->disp_dpi, 10)); - lv_style_set_pad_column(&theme->styles.pad_gap, _LV_DPX_CALC(theme->disp_dpi, 10)); + lv_style_set_pad_row(&theme->styles.pad_gap, LV_DPX_CALC(theme->disp_dpi, 10)); + lv_style_set_pad_column(&theme->styles.pad_gap, LV_DPX_CALC(theme->disp_dpi, 10)); style_init_reset(&theme->styles.line_space_large); - lv_style_set_text_line_space(&theme->styles.line_space_large, _LV_DPX_CALC(theme->disp_dpi, 20)); + lv_style_set_text_line_space(&theme->styles.line_space_large, LV_DPX_CALC(theme->disp_dpi, 20)); style_init_reset(&theme->styles.text_align_center); lv_style_set_text_align(&theme->styles.text_align_center, LV_TEXT_ALIGN_CENTER); @@ -393,14 +393,14 @@ static void style_init(my_theme_t * theme) #if LV_THEME_DEFAULT_GROW style_init_reset(&theme->styles.grow); - lv_style_set_transform_width(&theme->styles.grow, _LV_DPX_CALC(theme->disp_dpi, 3)); - lv_style_set_transform_height(&theme->styles.grow, _LV_DPX_CALC(theme->disp_dpi, 3)); + lv_style_set_transform_width(&theme->styles.grow, LV_DPX_CALC(theme->disp_dpi, 3)); + lv_style_set_transform_height(&theme->styles.grow, LV_DPX_CALC(theme->disp_dpi, 3)); #endif style_init_reset(&theme->styles.knob); lv_style_set_bg_color(&theme->styles.knob, theme->base.color_primary); lv_style_set_bg_opa(&theme->styles.knob, LV_OPA_COVER); - lv_style_set_pad_all(&theme->styles.knob, _LV_DPX_CALC(theme->disp_dpi, 6)); + lv_style_set_pad_all(&theme->styles.knob, LV_DPX_CALC(theme->disp_dpi, 6)); lv_style_set_radius(&theme->styles.knob, LV_RADIUS_CIRCLE); style_init_reset(&theme->styles.anim); @@ -412,7 +412,7 @@ static void style_init(my_theme_t * theme) #if LV_USE_ARC style_init_reset(&theme->styles.arc_indic); lv_style_set_arc_color(&theme->styles.arc_indic, theme->color_grey); - lv_style_set_arc_width(&theme->styles.arc_indic, _LV_DPX_CALC(theme->disp_dpi, 15)); + lv_style_set_arc_width(&theme->styles.arc_indic, LV_DPX_CALC(theme->disp_dpi, 15)); lv_style_set_arc_rounded(&theme->styles.arc_indic, true); style_init_reset(&theme->styles.arc_indic_primary); @@ -425,22 +425,22 @@ static void style_init(my_theme_t * theme) #endif #if LV_USE_CHECKBOX style_init_reset(&theme->styles.cb_marker); - lv_style_set_pad_all(&theme->styles.cb_marker, _LV_DPX_CALC(theme->disp_dpi, 3)); + lv_style_set_pad_all(&theme->styles.cb_marker, LV_DPX_CALC(theme->disp_dpi, 3)); lv_style_set_border_width(&theme->styles.cb_marker, BORDER_WIDTH); lv_style_set_border_color(&theme->styles.cb_marker, theme->base.color_primary); lv_style_set_bg_color(&theme->styles.cb_marker, theme->color_card); lv_style_set_bg_opa(&theme->styles.cb_marker, LV_OPA_COVER); lv_style_set_radius(&theme->styles.cb_marker, RADIUS_DEFAULT / 2); + lv_style_set_text_font(&theme->styles.cb_marker, theme->base.font_small); + lv_style_set_text_color(&theme->styles.cb_marker, lv_color_white()); style_init_reset(&theme->styles.cb_marker_checked); lv_style_set_bg_image_src(&theme->styles.cb_marker_checked, LV_SYMBOL_OK); - lv_style_set_text_color(&theme->styles.cb_marker_checked, lv_color_white()); - lv_style_set_text_font(&theme->styles.cb_marker_checked, theme->base.font_small); #endif #if LV_USE_SWITCH style_init_reset(&theme->styles.switch_knob); - lv_style_set_pad_all(&theme->styles.switch_knob, - _LV_DPX_CALC(theme->disp_dpi, 4)); + lv_style_set_pad_all(&theme->styles.switch_knob, - LV_DPX_CALC(theme->disp_dpi, 4)); lv_style_set_bg_color(&theme->styles.switch_knob, lv_color_white()); #endif @@ -453,16 +453,16 @@ static void style_init(my_theme_t * theme) #if LV_USE_CHART style_init_reset(&theme->styles.chart_bg); lv_style_set_border_post(&theme->styles.chart_bg, false); - lv_style_set_pad_column(&theme->styles.chart_bg, _LV_DPX_CALC(theme->disp_dpi, 10)); + lv_style_set_pad_column(&theme->styles.chart_bg, LV_DPX_CALC(theme->disp_dpi, 10)); lv_style_set_line_color(&theme->styles.chart_bg, theme->color_grey); style_init_reset(&theme->styles.chart_series); - lv_style_set_line_width(&theme->styles.chart_series, _LV_DPX_CALC(theme->disp_dpi, 3)); - lv_style_set_radius(&theme->styles.chart_series, _LV_DPX_CALC(theme->disp_dpi, 3)); + lv_style_set_line_width(&theme->styles.chart_series, LV_DPX_CALC(theme->disp_dpi, 3)); + lv_style_set_radius(&theme->styles.chart_series, LV_DPX_CALC(theme->disp_dpi, 3)); - int32_t chart_size = _LV_DPX_CALC(theme->disp_dpi, 8); + int32_t chart_size = LV_DPX_CALC(theme->disp_dpi, 8); lv_style_set_size(&theme->styles.chart_series, chart_size, chart_size); - lv_style_set_pad_column(&theme->styles.chart_series, _LV_DPX_CALC(theme->disp_dpi, 2)); + lv_style_set_pad_column(&theme->styles.chart_series, LV_DPX_CALC(theme->disp_dpi, 2)); style_init_reset(&theme->styles.chart_indic); lv_style_set_radius(&theme->styles.chart_indic, LV_RADIUS_CIRCLE); @@ -490,7 +490,7 @@ static void style_init(my_theme_t * theme) lv_style_set_pad_hor(&theme->styles.menu_cont, PAD_SMALL); lv_style_set_pad_ver(&theme->styles.menu_cont, PAD_SMALL); lv_style_set_pad_gap(&theme->styles.menu_cont, PAD_SMALL); - lv_style_set_border_width(&theme->styles.menu_cont, _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_border_width(&theme->styles.menu_cont, LV_DPX_CALC(theme->disp_dpi, 1)); lv_style_set_border_opa(&theme->styles.menu_cont, LV_OPA_10); lv_style_set_border_color(&theme->styles.menu_cont, theme->color_text); lv_style_set_border_side(&theme->styles.menu_cont, LV_BORDER_SIDE_NONE); @@ -498,7 +498,7 @@ static void style_init(my_theme_t * theme) style_init_reset(&theme->styles.menu_sidebar_cont); lv_style_set_pad_all(&theme->styles.menu_sidebar_cont, 0); lv_style_set_pad_gap(&theme->styles.menu_sidebar_cont, 0); - lv_style_set_border_width(&theme->styles.menu_sidebar_cont, _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_border_width(&theme->styles.menu_sidebar_cont, LV_DPX_CALC(theme->disp_dpi, 1)); lv_style_set_border_opa(&theme->styles.menu_sidebar_cont, LV_OPA_10); lv_style_set_border_color(&theme->styles.menu_sidebar_cont, theme->color_text); lv_style_set_border_side(&theme->styles.menu_sidebar_cont, LV_BORDER_SIDE_RIGHT); @@ -534,7 +534,7 @@ static void style_init(my_theme_t * theme) #if LV_USE_TABLE style_init_reset(&theme->styles.table_cell); - lv_style_set_border_width(&theme->styles.table_cell, _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_border_width(&theme->styles.table_cell, LV_DPX_CALC(theme->disp_dpi, 1)); lv_style_set_border_color(&theme->styles.table_cell, theme->color_grey); lv_style_set_border_side(&theme->styles.table_cell, LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_BOTTOM); #endif @@ -542,8 +542,8 @@ static void style_init(my_theme_t * theme) #if LV_USE_TEXTAREA style_init_reset(&theme->styles.ta_cursor); lv_style_set_border_color(&theme->styles.ta_cursor, theme->color_text); - lv_style_set_border_width(&theme->styles.ta_cursor, _LV_DPX_CALC(theme->disp_dpi, 2)); - lv_style_set_pad_left(&theme->styles.ta_cursor, - _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_border_width(&theme->styles.ta_cursor, LV_DPX_CALC(theme->disp_dpi, 2)); + lv_style_set_pad_left(&theme->styles.ta_cursor, - LV_DPX_CALC(theme->disp_dpi, 1)); lv_style_set_border_side(&theme->styles.ta_cursor, LV_BORDER_SIDE_LEFT); lv_style_set_anim_duration(&theme->styles.ta_cursor, 400); @@ -559,7 +559,7 @@ static void style_init(my_theme_t * theme) lv_style_set_pad_gap(&theme->styles.calendar_btnm_bg, PAD_SMALL / 2); style_init_reset(&theme->styles.calendar_btnm_day); - lv_style_set_border_width(&theme->styles.calendar_btnm_day, _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_border_width(&theme->styles.calendar_btnm_day, LV_DPX_CALC(theme->disp_dpi, 1)); lv_style_set_border_color(&theme->styles.calendar_btnm_day, theme->color_grey); lv_style_set_bg_color(&theme->styles.calendar_btnm_day, theme->color_card); lv_style_set_bg_opa(&theme->styles.calendar_btnm_day, LV_OPA_20); @@ -602,7 +602,7 @@ static void style_init(my_theme_t * theme) lv_style_set_clip_corner(&theme->styles.list_bg, true); style_init_reset(&theme->styles.list_btn); - lv_style_set_border_width(&theme->styles.list_btn, _LV_DPX_CALC(theme->disp_dpi, 1)); + lv_style_set_border_width(&theme->styles.list_btn, LV_DPX_CALC(theme->disp_dpi, 1)); lv_style_set_border_color(&theme->styles.list_btn, theme->color_grey); lv_style_set_border_side(&theme->styles.list_btn, LV_BORDER_SIDE_BOTTOM); lv_style_set_pad_all(&theme->styles.list_btn, PAD_SMALL); @@ -618,9 +618,9 @@ static void style_init(my_theme_t * theme) lv_style_set_bg_color(&theme->styles.led, lv_color_white()); lv_style_set_bg_grad_color(&theme->styles.led, lv_palette_main(LV_PALETTE_GREY)); lv_style_set_radius(&theme->styles.led, LV_RADIUS_CIRCLE); - lv_style_set_shadow_width(&theme->styles.led, _LV_DPX_CALC(theme->disp_dpi, 15)); + lv_style_set_shadow_width(&theme->styles.led, LV_DPX_CALC(theme->disp_dpi, 15)); lv_style_set_shadow_color(&theme->styles.led, lv_color_white()); - lv_style_set_shadow_spread(&theme->styles.led, _LV_DPX_CALC(theme->disp_dpi, 5)); + lv_style_set_shadow_spread(&theme->styles.led, LV_DPX_CALC(theme->disp_dpi, 5)); #endif #if LV_USE_SCALE @@ -629,6 +629,7 @@ static void style_init(my_theme_t * theme) lv_style_set_line_width(&theme->styles.scale, LV_DPX(2)); lv_style_set_arc_color(&theme->styles.scale, theme->color_text); lv_style_set_arc_width(&theme->styles.scale, LV_DPX(2)); + lv_style_set_length(&theme->styles.scale, LV_DPX(6)); #endif } @@ -640,7 +641,7 @@ lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary const lv_font_t * font) { /*This trick is required only to avoid the garbage collection of - *styles' data if LVGL is used in a binding (e.g. Micropython) + *styles' data if LVGL is used in a binding (e.g. MicroPython) *In a general case styles could be in a simple `static lv_style_t my_style...` variables*/ if(!lv_theme_default_is_inited()) { @@ -727,8 +728,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) LV_UNUSED(th); my_theme_t * theme = theme_def; + lv_obj_t * parent = lv_obj_get_parent(obj); - if(lv_obj_get_parent(obj) == NULL) { + if(parent == NULL) { lv_obj_add_style(obj, &theme->styles.scr, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); lv_obj_add_style(obj, &theme->styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); @@ -737,20 +739,19 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) if(lv_obj_check_type(obj, &lv_obj_class)) { #if LV_USE_TABVIEW - lv_obj_t * parent = lv_obj_get_parent(obj); /*Tabview content area*/ - if(parent && lv_obj_check_type(parent, &lv_tabview_class) && lv_obj_get_index(obj) == 1) { + if(lv_obj_check_type(parent, &lv_tabview_class) && lv_obj_get_child(parent, 1) == obj) { return; } /*Tabview button container*/ - else if(lv_obj_check_type(parent, &lv_tabview_class) && lv_obj_get_index(obj) == 0) { + else if(lv_obj_check_type(parent, &lv_tabview_class) && lv_obj_get_child(parent, 0) == obj) { lv_obj_add_style(obj, &theme->styles.bg_color_white, 0); lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &theme->styles.tab_bg_focus, LV_STATE_FOCUS_KEY); return; } /*Tabview pages*/ - else if(parent && lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) { + else if(lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) { lv_obj_add_style(obj, &theme->styles.pad_normal, 0); lv_obj_add_style(obj, &theme->styles.rotary_scroll, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); @@ -761,13 +762,13 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_WIN /*Header*/ - if(lv_obj_get_index(obj) == 0 && lv_obj_check_type(lv_obj_get_parent(obj), &lv_win_class)) { + if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 0) == obj) { lv_obj_add_style(obj, &theme->styles.bg_color_grey, 0); lv_obj_add_style(obj, &theme->styles.pad_tiny, 0); return; } /*Content*/ - else if(lv_obj_get_index(obj) == 1 && lv_obj_check_type(lv_obj_get_parent(obj), &lv_win_class)) { + else if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 1) == obj) { lv_obj_add_style(obj, &theme->styles.scr, 0); lv_obj_add_style(obj, &theme->styles.pad_normal, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); @@ -777,7 +778,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif #if LV_USE_CALENDAR - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_calendar_class)) { + if(lv_obj_check_type(parent, &lv_calendar_class)) { /*No style*/ return; } @@ -791,9 +792,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_button_class)) { #if LV_USE_TABVIEW - lv_obj_t * parent = lv_obj_get_parent(obj); - if(parent && lv_obj_get_index(parent) == 0) { /*Tabview header*/ - if(lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) { + lv_obj_t * tv = lv_obj_get_parent(parent); /*parent is the tabview header*/ + if(tv && lv_obj_get_child(tv, 0) == parent) { /*The button is on the tab view header*/ + if(lv_obj_check_type(tv, &lv_tabview_class)) { lv_obj_add_style(obj, &theme->styles.pressed, LV_STATE_PRESSED); lv_obj_add_style(obj, &theme->styles.bg_color_primary_muted, LV_STATE_CHECKED); lv_obj_add_style(obj, &theme->styles.tab_btn, LV_STATE_CHECKED); @@ -818,8 +819,8 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.disabled, LV_STATE_DISABLED); #if LV_USE_MENU - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_menu_sidebar_header_cont_class) || - lv_obj_check_type(lv_obj_get_parent(obj), &lv_menu_main_header_cont_class)) { + if(lv_obj_check_type(parent, &lv_menu_sidebar_header_cont_class) || + lv_obj_check_type(parent, &lv_menu_main_header_cont_class)) { lv_obj_add_style(obj, &theme->styles.menu_header_btn, 0); lv_obj_add_style(obj, &theme->styles.menu_pressed, LV_STATE_PRESSED); } @@ -837,7 +838,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_buttonmatrix_class)) { #if LV_USE_CALENDAR - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_calendar_class)) { + if(lv_obj_check_type(parent, &lv_calendar_class)) { lv_obj_add_style(obj, &theme->styles.calendar_btnm_bg, 0); lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &theme->styles.outline_secondary, LV_STATE_EDITED); @@ -1124,6 +1125,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_msgbox_class)) { lv_obj_add_style(obj, &theme->styles.card, 0); lv_obj_add_style(obj, &theme->styles.pad_zero, 0); + lv_obj_add_style(obj, &theme->styles.clip_corner, 0); return; } else if(lv_obj_check_type(obj, &lv_msgbox_backdrop_class)) { @@ -1139,6 +1141,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.pad_tiny, 0); return; } + else if(lv_obj_check_type(obj, &lv_msgbox_content_class)) { + lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); + lv_obj_add_style(obj, &theme->styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); + lv_obj_add_style(obj, &theme->styles.pad_tiny, 0); + return; + } else if(lv_obj_check_type(obj, &lv_msgbox_header_button_class) || lv_obj_check_type(obj, &lv_msgbox_footer_button_class)) { lv_obj_add_style(obj, &theme->styles.btn, 0); @@ -1152,11 +1160,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) return; } - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) { - lv_obj_add_style(obj, &theme->styles.pad_tiny, 0); - return; - } - #endif #if LV_USE_SPINBOX diff --git a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.c b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.c index 352047539..5dcd6c6ae 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.c +++ b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.c @@ -6,6 +6,9 @@ /********************* * INCLUDES *********************/ +#include "lv_theme_private.h" +#include "../core/lv_obj_private.h" +#include "../core/lv_obj_class_private.h" #include "../../lvgl.h" /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.h b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.h index fc19f4c45..21cb09b11 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.h +++ b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme.h @@ -25,19 +25,6 @@ extern "C" { typedef void (*lv_theme_apply_cb_t)(lv_theme_t *, lv_obj_t *); -struct _lv_theme_t { - lv_theme_apply_cb_t apply_cb; - lv_theme_t * parent; /**< Apply the current theme's style on top of this theme.*/ - void * user_data; - lv_display_t * disp; - lv_color_t color_primary; - lv_color_t color_secondary; - const lv_font_t * font_small; - const lv_font_t * font_normal; - const lv_font_t * font_large; - uint32_t flags; /*Any custom flag used by the theme*/ -}; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h new file mode 100644 index 000000000..6fd10a59c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_theme_private.h + * + */ + +#ifndef LV_THEME_PRIVATE_H +#define LV_THEME_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_theme.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_theme_t { + lv_theme_apply_cb_t apply_cb; + lv_theme_t * parent; /**< Apply the current theme's style on top of this theme. */ + void * user_data; + lv_display_t * disp; + lv_color_t color_primary; + lv_color_t color_secondary; + const lv_font_t * font_small; + const lv_font_t * font_normal; + const lv_font_t * font_large; + uint32_t flags; /**< Any custom flag used by the theme */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_THEME_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.c b/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.c index fdcf11dcb..cd71ecb3d 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.c +++ b/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "../lv_theme_private.h" #include "../../../lvgl.h" #if LV_USE_THEME_MONO @@ -205,7 +206,7 @@ void lv_theme_mono_deinit(void) lv_theme_t * lv_theme_mono_init(lv_display_t * disp, bool dark_bg, const lv_font_t * font) { /*This trick is required only to avoid the garbage collection of - *styles' data if LVGL is used in a binding (e.g. Micropython) + *styles' data if LVGL is used in a binding (e.g. MicroPython) *In a general case styles could be in simple `static lv_style_t my_style...` variables*/ if(!lv_theme_mono_is_inited()) { theme_def = lv_malloc_zeroed(sizeof(my_theme_t)); @@ -233,8 +234,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) LV_UNUSED(th); my_theme_t * theme = theme_def; + lv_obj_t * parent = lv_obj_get_parent(obj); - if(lv_obj_get_parent(obj) == NULL) { + if(parent == NULL) { lv_obj_add_style(obj, &theme->styles.scr, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); return; @@ -242,7 +244,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) if(lv_obj_check_type(obj, &lv_obj_class)) { #if LV_USE_TABVIEW - lv_obj_t * parent = lv_obj_get_parent(obj); /*Tabview content area*/ if(lv_obj_check_type(parent, &lv_tabview_class)) { return; @@ -258,13 +259,13 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_WIN /*Header*/ - if(lv_obj_get_index(obj) == 0 && lv_obj_check_type(lv_obj_get_parent(obj), &lv_win_class)) { + if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 0) == 0) { lv_obj_add_style(obj, &theme->styles.card, 0); lv_obj_add_style(obj, &theme->styles.no_radius, 0); return; } /*Content*/ - else if(lv_obj_get_index(obj) == 1 && lv_obj_check_type(lv_obj_get_parent(obj), &lv_win_class)) { + else if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 1) == obj) { lv_obj_add_style(obj, &theme->styles.card, 0); lv_obj_add_style(obj, &theme->styles.no_radius, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); @@ -288,7 +289,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_BUTTONMATRIX else if(lv_obj_check_type(obj, &lv_buttonmatrix_class)) { #if LV_USE_MSGBOX - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) { + if(lv_obj_check_type(parent, &lv_msgbox_class)) { lv_obj_add_style(obj, &theme->styles.pad_gap, 0); lv_obj_add_style(obj, &theme->styles.card, LV_PART_ITEMS); lv_obj_add_style(obj, &theme->styles.pr, LV_PART_ITEMS | LV_STATE_PRESSED); @@ -299,7 +300,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #endif #if LV_USE_TABVIEW - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_tabview_class)) { + if(lv_obj_check_type(parent, &lv_tabview_class)) { lv_obj_add_style(obj, &theme->styles.pad_gap, 0); lv_obj_add_style(obj, &theme->styles.card, LV_PART_ITEMS); lv_obj_add_style(obj, &theme->styles.pr, LV_PART_ITEMS | LV_STATE_PRESSED); diff --git a/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.h b/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.h index fafe27f24..30ac4c488 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.h +++ b/lib/libesp32_lvgl/lvgl/src/themes/mono/lv_theme_mono.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_USE_THEME_MONO_H -#define LV_USE_THEME_MONO_H +#ifndef LV_THEME_MONO_H +#define LV_THEME_MONO_H #ifdef __cplusplus extern "C" { @@ -59,4 +59,4 @@ void lv_theme_mono_deinit(void); } /*extern "C"*/ #endif -#endif /*LV_USE_THEME_MONO_H*/ +#endif /* LV_THEME_MONO_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/themes/simple/lv_theme_simple.c b/lib/libesp32_lvgl/lvgl/src/themes/simple/lv_theme_simple.c index 6eb2b2c9c..8a325550f 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/simple/lv_theme_simple.c +++ b/lib/libesp32_lvgl/lvgl/src/themes/simple/lv_theme_simple.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "../lv_theme_private.h" #include "../../../lvgl.h" /*To see all the widgets*/ #if LV_USE_THEME_SIMPLE @@ -176,7 +177,7 @@ void lv_theme_simple_deinit(void) lv_theme_t * lv_theme_simple_init(lv_display_t * disp) { /*This trick is required only to avoid the garbage collection of - *styles' data if LVGL is used in a binding (e.g. Micropython) + *styles' data if LVGL is used in a binding (e.g. MicroPython) *In a general case styles could be in simple `static lv_style_t my_style...` variables*/ if(!lv_theme_simple_is_inited()) { theme_def = lv_malloc_zeroed(sizeof(my_theme_t)); @@ -206,8 +207,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) LV_UNUSED(th); my_theme_t * theme = theme_def; + lv_obj_t * parent = lv_obj_get_parent(obj); - if(lv_obj_get_parent(obj) == NULL) { + if(parent == NULL) { lv_obj_add_style(obj, &theme->styles.scr, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); return; @@ -215,7 +217,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) if(lv_obj_check_type(obj, &lv_obj_class)) { #if LV_USE_TABVIEW - lv_obj_t * parent = lv_obj_get_parent(obj); /*Tabview content area*/ if(lv_obj_check_type(parent, &lv_tabview_class)) { lv_obj_add_style(obj, &theme->styles.scr, 0); @@ -231,12 +232,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_WIN /*Header*/ - if(lv_obj_get_index(obj) == 0 && lv_obj_check_type(lv_obj_get_parent(obj), &lv_win_class)) { + if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 0) == obj) { lv_obj_add_style(obj, &theme->styles.light, 0); return; } /*Content*/ - else if(lv_obj_get_index(obj) == 1 && lv_obj_check_type(lv_obj_get_parent(obj), &lv_win_class)) { + else if(lv_obj_check_type(parent, &lv_win_class) && lv_obj_get_child(parent, 1) == obj) { lv_obj_add_style(obj, &theme->styles.light, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); return; @@ -254,13 +255,13 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_BUTTONMATRIX else if(lv_obj_check_type(obj, &lv_buttonmatrix_class)) { #if LV_USE_MSGBOX - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) { + if(lv_obj_check_type(parent, &lv_msgbox_class)) { lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS); return; } #endif #if LV_USE_TABVIEW - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_tabview_class)) { + if(lv_obj_check_type(parent, &lv_tabview_class)) { lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS); return; } diff --git a/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.c b/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.c index 2e4626b78..21e22959d 100644 --- a/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.c +++ b/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.c @@ -6,8 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_tick.h" -#include +#include "lv_tick_private.h" +#include "../misc/lv_types.h" #include "../core/lv_global.h" /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.h b/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.h index da8620371..048b93a31 100644 --- a/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.h +++ b/lib/libesp32_lvgl/lvgl/src/tick/lv_tick.h @@ -1,10 +1,10 @@ /** - * @file lv_hal_tick.h + * @file lv_tick.h * Provide access to the system tick with 1 millisecond resolution */ -#ifndef LV_HAL_TICK_H -#define LV_HAL_TICK_H +#ifndef LV_TICK_H +#define LV_TICK_H #ifdef __cplusplus extern "C" { @@ -15,8 +15,7 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" -#include -#include +#include "../misc/lv_types.h" /********************* * DEFINES @@ -32,13 +31,6 @@ typedef uint32_t (*lv_tick_get_cb_t)(void); typedef void (*lv_delay_cb_t)(uint32_t ms); -typedef struct { - uint32_t sys_time; - volatile uint8_t sys_irq_flag; - lv_tick_get_cb_t tick_get_cb; - lv_delay_cb_t delay_cb; -} lv_tick_state_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -77,8 +69,8 @@ void lv_delay_ms(uint32_t ms); void lv_tick_set_cb(lv_tick_get_cb_t cb); /** - * Set a custom callback for 'lv_dalay_ms' - * @param cb call this callback in 'lv_dalay_ms' + * Set a custom callback for 'lv_delay_ms' + * @param cb call this callback in 'lv_delay_ms' */ void lv_delay_set_cb(lv_delay_cb_t cb); @@ -90,4 +82,4 @@ void lv_delay_set_cb(lv_delay_cb_t cb); } /*extern "C"*/ #endif -#endif /*LV_HAL_TICK_H*/ +#endif /*LV_TICK_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/tick/lv_tick_private.h b/lib/libesp32_lvgl/lvgl/src/tick/lv_tick_private.h new file mode 100644 index 000000000..cf8ae9b09 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/tick/lv_tick_private.h @@ -0,0 +1,46 @@ +/** + * @file lv_tick_private.h + * + */ + +#ifndef LV_TICK_PRIVATE_H +#define LV_TICK_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_tick.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint32_t sys_time; + volatile uint8_t sys_irq_flag; + lv_tick_get_cb_t tick_get_cb; + lv_delay_cb_t delay_cb; +} lv_tick_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TICK_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c index d26a848d7..11ec7ca1c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_animimage.h" +#include "lv_animimage_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_ANIMIMG != 0 /*Testing of dependencies*/ @@ -36,7 +37,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static void index_change(lv_obj_t * obj, int32_t index); +static void index_change(lv_obj_t * obj, int32_t idx); static void lv_animimg_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); /********************** @@ -72,7 +73,7 @@ void lv_animimg_set_src(lv_obj_t * obj, const void * dsc[], size_t num) lv_animimg_t * animimg = (lv_animimg_t *)obj; animimg->dsc = dsc; animimg->pic_count = num; - lv_anim_set_values(&animimg->anim, 0, (int32_t)num - 1); + lv_anim_set_values(&animimg->anim, 0, (int32_t)num); } void lv_animimg_start(lv_obj_t * obj) @@ -156,12 +157,16 @@ static void lv_animimg_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob lv_anim_set_repeat_count(&animimg->anim, LV_ANIM_REPEAT_INFINITE); } -static void index_change(lv_obj_t * obj, int32_t index) +static void index_change(lv_obj_t * obj, int32_t idx) { - int32_t idx; lv_animimg_t * animimg = (lv_animimg_t *)obj; - idx = index % animimg->pic_count; + if(animimg->dsc == NULL) { + LV_LOG_WARN("dsc is null"); + return; + } + + if(idx >= animimg->pic_count) idx = animimg->pic_count - 1; lv_image_set_src(obj, animimg->dsc[idx]); } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h index 87df81540..c7b3b0a8b 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h @@ -1,10 +1,10 @@ /** - * @file lv_animimg.h + * @file lv_animimage.h * */ -#ifndef LV_ANIM_IMAGE_H -#define LV_ANIM_IMAGE_H +#ifndef LV_ANIMIMAGE_H +#define LV_ANIMIMAGE_H #ifdef __cplusplus extern "C" { @@ -32,25 +32,10 @@ extern "C" { LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_animimg_class; -/*Data of the animimage*/ -typedef struct { - lv_image_t img; - lv_anim_t anim; - /*picture sequence */ - const void ** dsc; - int8_t pic_count; -} lv_animimg_t; - -/*Image parts*/ -enum _lv_animimg_part_t { +/** Image parts */ +typedef enum { LV_ANIM_IMAGE_PART_MAIN, -}; - -#ifdef DOXYGEN -typedef _lv_animimg_part_t lv_animimg_part_t; -#else -typedef uint8_t lv_animimg_part_t; -#endif +} lv_animimg_part_t; /********************** * GLOBAL PROTOTYPES @@ -133,4 +118,4 @@ uint32_t lv_animimg_get_repeat_count(lv_obj_t * img); } /* extern "C" */ #endif -#endif /*LV_ANIM_IMAGE_H*/ +#endif /*LV_ANIMIMAGE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage_private.h new file mode 100644 index 000000000..c4cf663d5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_animimage_private.h + * + */ + +#ifndef LV_ANIMIMAGE_PRIVATE_H +#define LV_ANIMIMAGE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../image/lv_image_private.h" +#include "../../misc/lv_anim_private.h" +#include "lv_animimage.h" + +#if LV_USE_ANIMIMG != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of the animimage */ +struct lv_animimg_t { + lv_image_t img; + lv_anim_t anim; + /* picture sequence */ + const void ** dsc; + int8_t pic_count; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_ANIMIMG != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIMIMAGE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c index 6d4383971..7e4315c29 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c @@ -6,7 +6,11 @@ /********************* * INCLUDES *********************/ -#include "lv_arc.h" +#include "lv_arc_private.h" +#include "../../misc/lv_area_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_event_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_ARC != 0 #include "../../core/lv_group.h" @@ -417,7 +421,7 @@ static void lv_arc_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) arc->indic_angle_end = 270; arc->type = LV_ARC_MODE_NORMAL; arc->value = VALUE_UNSET; - arc->min_close = 1; + arc->min_close = CLICK_CLOSER_TO_MIN_END; arc->min_value = 0; arc->max_value = 100; arc->dragging = false; @@ -522,12 +526,12 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) *It's mainly to avoid jumping to the opposite end if the "dead" range between min. and max. is crossed. *Check which end was closer on the last valid press (arc->min_close) and prefer that end*/ if(LV_ABS(delta_angle) > 280) { - if(arc->min_close) angle = 0; + if(arc->min_close == CLICK_CLOSER_TO_MIN_END) angle = 0; else angle = deg_range; } /* Check if click was outside the background arc start and end angles */ else if(CLICK_OUTSIDE_BG_ANGLES == arc->in_out) { - if(arc->min_close) angle = -deg_range; + if(arc->min_close == CLICK_CLOSER_TO_MIN_END) angle = -deg_range; else angle = deg_range; } else { /* Keep the angle value */ } @@ -537,10 +541,12 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) if(((min_close_prev == CLICK_CLOSER_TO_MIN_END) && (arc->min_close == CLICK_CLOSER_TO_MAX_END)) && ((CLICK_OUTSIDE_BG_ANGLES == arc->in_out) && (LV_ABS(delta_angle) > 280))) { angle = 0; + arc->min_close = min_close_prev; } else if(((min_close_prev == CLICK_CLOSER_TO_MAX_END) && (arc->min_close == CLICK_CLOSER_TO_MIN_END)) - && (CLICK_OUTSIDE_BG_ANGLES == arc->in_out)) { + && (CLICK_OUTSIDE_BG_ANGLES == arc->in_out) && (360 - LV_ABS(delta_angle) > 280)) { angle = deg_range; + arc->min_close = min_close_prev; } else { /* Keep the angle value */ } @@ -644,14 +650,14 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_area_t a; /*Invalid if clicked inside*/ lv_area_set(&a, p.x - r, p.y - r, p.x + r, p.y + r); - if(_lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE)) { + if(lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE)) { info->res = false; return; } /*Valid if no clicked outside*/ lv_area_increase(&a, w + ext_click_area * 2, w + ext_click_area * 2); - info->res = _lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE); + info->res = lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE); } else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) { int32_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); @@ -923,7 +929,7 @@ static int32_t knob_get_extra_size(lv_obj_t * obj) * and we click a bit to the left, angle is 10, not the expected 40. * * @param obj Pointer to lv_arc - * @param angle Angle to be checked + * @param angle Angle to be checked. Is 0<=angle<=360 and relative to bg_angle_start * @param tolerance_deg Tolerance * * @return true if angle is within arc background bounds, false otherwise @@ -934,92 +940,42 @@ static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const lv_value_precise LV_ASSERT_OBJ(obj, MY_CLASS); lv_arc_t * arc = (lv_arc_t *)obj; - lv_value_precise_t smaller_angle = 0; - lv_value_precise_t bigger_angle = 0; + lv_value_precise_t bounds_angle = arc->bg_angle_end - arc->bg_angle_start; + if(bounds_angle < 0) bounds_angle += 360; - /* Determine which background angle is smaller and bigger */ - if(arc->bg_angle_start < arc->bg_angle_end) { - bigger_angle = arc->bg_angle_end; - smaller_angle = arc->bg_angle_start; - } - else { - bigger_angle = (360 - arc->bg_angle_start) + arc->bg_angle_end; - smaller_angle = 0; - } - - /* Angle is between both background angles */ - if((smaller_angle <= angle) && (angle <= bigger_angle)) { - - if(((bigger_angle - smaller_angle) / 2) >= angle) { - arc->min_close = 1; + /* Angle is in the bounds */ + if(angle <= bounds_angle) { + if(angle < (bounds_angle / 2)) { + arc->min_close = CLICK_CLOSER_TO_MIN_END; } else { - arc->min_close = 0; + arc->min_close = CLICK_CLOSER_TO_MAX_END; } - arc->in_out = CLICK_INSIDE_BG_ANGLES; - return true; } + /* Distance between background start and end angles is less than tolerance, * consider the click inside the arc */ - else if(((smaller_angle - tolerance_deg) <= 0) && - (360 - (bigger_angle + (smaller_angle - tolerance_deg))) != 0) { - - arc->min_close = 1; + if(360 - bounds_angle <= tolerance_deg) { + arc->min_close = CLICK_CLOSER_TO_MIN_END; arc->in_out = CLICK_INSIDE_BG_ANGLES; return true; } - else { /* Case handled below */ } - /* Legends: - * 0° = angle 0 - * 360° = angle 360 - * T: Tolerance - * A: Angle - * S: Arc background start angle - * E: Arc background end angle - * - * Start angle is bigger or equal to tolerance */ - if((smaller_angle >= tolerance_deg) - /* (360° - T) --- A --- 360° */ - && ((angle >= (360 - tolerance_deg)) && (angle <= 360))) { - - arc->min_close = 1; + /* angle is within the tolerance of the min end */ + if(360 - angle <= tolerance_deg) { + arc->min_close = CLICK_CLOSER_TO_MIN_END; arc->in_out = CLICK_OUTSIDE_BG_ANGLES; return true; } - /* Tolerance is bigger than bg start angle */ - else if((smaller_angle < tolerance_deg) - /* (360° - (T - S)) --- A --- 360° */ - && (((360 - (tolerance_deg - smaller_angle)) <= angle)) && (angle <= 360)) { - arc->min_close = 1; + /* angle is within the tolerance of the max end */ + if(angle <= bounds_angle + tolerance_deg) { + arc->min_close = CLICK_CLOSER_TO_MAX_END; arc->in_out = CLICK_OUTSIDE_BG_ANGLES; return true; } - /* 360° is bigger than background end angle + tolerance */ - else if((360 >= (bigger_angle + tolerance_deg)) - /* E --- A --- (E + T) */ - && ((bigger_angle <= (angle + smaller_angle)) && - ((angle + smaller_angle) <= (bigger_angle + tolerance_deg)))) { - - arc->min_close = 0; - arc->in_out = CLICK_OUTSIDE_BG_ANGLES; - return true; - } - /* Background end angle + tolerance is bigger than 360° and bg_start_angle + tolerance is not near 0° + ((bg_end_angle + tolerance) - 360°) - * Here we can assume background is not near 0° because of the first two initial checks */ - else if((360 < (bigger_angle + tolerance_deg)) - && (angle <= 0 + ((bigger_angle + tolerance_deg) - 360)) && (angle > bigger_angle)) { - - arc->min_close = 0; - arc->in_out = CLICK_OUTSIDE_BG_ANGLES; - return true; - } - else { - /* Nothing to do */ - } return false; } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.h b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.h index bea60c6ef..f241745ff 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.h @@ -26,37 +26,11 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum _lv_arc_mode_t { +typedef enum { LV_ARC_MODE_NORMAL, LV_ARC_MODE_SYMMETRICAL, LV_ARC_MODE_REVERSE -}; - -#ifdef DOXYGEN -typedef _lv_arc_mode_t lv_arc_mode_t; -#else -typedef uint8_t lv_arc_mode_t; -#endif /*DOXYGEN*/ - -typedef struct { - lv_obj_t obj; - int32_t rotation; - lv_value_precise_t indic_angle_start; - lv_value_precise_t indic_angle_end; - lv_value_precise_t bg_angle_start; - lv_value_precise_t bg_angle_end; - int32_t value; /*Current value of the arc*/ - int32_t min_value; /*Minimum value of the arc*/ - int32_t max_value; /*Maximum value of the arc*/ - uint32_t dragging : 1; - uint32_t type : 2; - uint32_t min_close : 1; /*1: the last pressed angle was closer to minimum end*/ - uint32_t in_out : 1; /* 1: The click was within the background arc angles. 0: Click outside */ - uint32_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/ - uint32_t last_tick; /*Last dragging event timestamp of the arc*/ - lv_value_precise_t last_angle; /*Last dragging angle of the arc*/ - int16_t knob_offset; /*knob offset from the main arc*/ -} lv_arc_t; +} lv_arc_mode_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_arc_class; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc_private.h new file mode 100644 index 000000000..03513ea60 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc_private.h @@ -0,0 +1,64 @@ +/** + * @file lv_arc_private.h + * + */ + +#ifndef LV_ARC_PRIVATE_H +#define LV_ARC_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj_private.h" +#include "lv_arc.h" + +#if LV_USE_ARC != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_arc_t { + lv_obj_t obj; + int32_t rotation; + lv_value_precise_t indic_angle_start; + lv_value_precise_t indic_angle_end; + lv_value_precise_t bg_angle_start; + lv_value_precise_t bg_angle_end; + int32_t value; /**< Current value of the arc */ + int32_t min_value; /**< Minimum value of the arc */ + int32_t max_value; /**< Maximum value of the arc */ + uint32_t dragging : 1; + uint32_t type : 2; + uint32_t min_close : 1; /**< 1: the last pressed angle was closer to minimum end */ + uint32_t in_out : 1; /**< 1: The click was within the background arc angles. 0: Click outside */ + uint32_t chg_rate; /**< Drag angle rate of change of the arc (degrees/sec) */ + uint32_t last_tick; /**< Last dragging event timestamp of the arc */ + lv_value_precise_t last_angle; /**< Last dragging angle of the arc */ + int16_t knob_offset; /**< knob offset from the main arc */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_ARC != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ARC_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.c b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.c index 7f4ebccfd..6fc7b231a 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.c @@ -6,12 +6,16 @@ /********************* * INCLUDES *********************/ -#include "lv_bar.h" +#include "lv_bar_private.h" +#include "../../misc/lv_area_private.h" +#include "../../draw/lv_draw_mask_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_BAR != 0 #include "../../draw/lv_draw.h" #include "../../misc/lv_assert.h" -#include "../../misc/lv_anim.h" +#include "../../misc/lv_anim_private.h" #include "../../misc/lv_math.h" /********************* @@ -49,8 +53,8 @@ static void lv_bar_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_bar_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_indic(lv_event_t * e); static void lv_bar_set_value_with_anim(lv_obj_t * obj, int32_t new_value, int32_t * value_ptr, - _lv_bar_anim_t * anim_info, lv_anim_enable_t en); -static void lv_bar_init_anim(lv_obj_t * bar, _lv_bar_anim_t * bar_anim); + lv_bar_anim_t * anim_info, lv_anim_enable_t en); +static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim); static void lv_bar_anim(void * bar, int32_t value); static void lv_bar_anim_completed(lv_anim_t * a); @@ -164,6 +168,15 @@ void lv_bar_set_mode(lv_obj_t * obj, lv_bar_mode_t mode) lv_obj_invalidate(obj); } +void lv_bar_set_orientation(lv_obj_t * obj, lv_bar_orientation_t orientation) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_bar_t * bar = (lv_bar_t *)obj; + + bar->orientation = orientation; + lv_obj_invalidate(obj); +} + /*===================== * Getter functions *====================*/ @@ -209,6 +222,14 @@ lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj) return bar->mode; } +lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_bar_t * bar = (lv_bar_t *)obj; + + return bar->orientation; +} + bool lv_bar_is_symmetrical(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -237,6 +258,7 @@ static void lv_bar_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) bar->indic_area.y1 = 0; bar->indic_area.y2 = 0; bar->mode = LV_BAR_MODE_NORMAL; + bar->orientation = LV_BAR_ORIENTATION_AUTO; bar->val_reversed = false; lv_bar_init_anim(obj, &bar->cur_value_anim); @@ -280,7 +302,20 @@ static void draw_indic(lv_event_t * e) range = 1; } - bool hor = barw >= barh; + bool hor = false; + switch(bar->orientation) { + case LV_BAR_ORIENTATION_HORIZONTAL: + hor = true; + break; + case LV_BAR_ORIENTATION_VERTICAL: + hor = false; + break; + case LV_BAR_ORIENTATION_AUTO: + default: + hor = (barw >= barh); + break; + } + bool sym = lv_bar_is_symmetrical(obj); /*Calculate the indicator area*/ @@ -304,7 +339,6 @@ static void draw_indic(lv_event_t * e) bar->indic_area.x1 = obj->coords.x1 + (barw / 2) - (LV_BAR_SIZE_MIN / 2); bar->indic_area.x2 = bar->indic_area.x1 + LV_BAR_SIZE_MIN; } - int32_t indic_max_w = lv_area_get_width(&bar->indic_area); int32_t indic_max_h = lv_area_get_height(&bar->indic_area); @@ -479,7 +513,7 @@ static void draw_indic(lv_event_t * e) /*The indicator is fully drawn if it's larger than the bg*/ if((bg_left < 0 || bg_right < 0 || bg_top < 0 || bg_bottom < 0)) radius_issue = false; else if(indic_radius >= bg_radius) radius_issue = false; - else if(_lv_area_is_in(&indic_area, &bar_coords, bg_radius)) radius_issue = false; + else if(lv_area_is_in(&indic_area, &bar_coords, bg_radius)) radius_issue = false; if(radius_issue || mask_needed) { if(!radius_issue) { @@ -594,14 +628,14 @@ static void lv_bar_event(const lv_obj_class_t * class_p, lv_event_t * e) static void lv_bar_anim(void * var, int32_t value) { - _lv_bar_anim_t * bar_anim = var; + lv_bar_anim_t * bar_anim = var; bar_anim->anim_state = value; lv_obj_invalidate(bar_anim->bar); } static void lv_bar_anim_completed(lv_anim_t * a) { - _lv_bar_anim_t * var = a->var; + lv_bar_anim_t * var = a->var; lv_obj_t * obj = (lv_obj_t *)var->bar; lv_bar_t * bar = (lv_bar_t *)obj; @@ -614,7 +648,7 @@ static void lv_bar_anim_completed(lv_anim_t * a) } static void lv_bar_set_value_with_anim(lv_obj_t * obj, int32_t new_value, int32_t * value_ptr, - _lv_bar_anim_t * anim_info, lv_anim_enable_t en) + lv_bar_anim_t * anim_info, lv_anim_enable_t en) { if(en == LV_ANIM_OFF) { lv_anim_delete(anim_info, NULL); @@ -653,7 +687,7 @@ static void lv_bar_set_value_with_anim(lv_obj_t * obj, int32_t new_value, int32_ } } -static void lv_bar_init_anim(lv_obj_t * obj, _lv_bar_anim_t * bar_anim) +static void lv_bar_init_anim(lv_obj_t * obj, lv_bar_anim_t * bar_anim) { bar_anim->bar = obj; bar_anim->anim_start = 0; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.h b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.h index d2a882a05..93c88786f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.h @@ -28,37 +28,17 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum _lv_bar_mode_t { +typedef enum { LV_BAR_MODE_NORMAL, LV_BAR_MODE_SYMMETRICAL, LV_BAR_MODE_RANGE -}; +} lv_bar_mode_t; -#ifdef DOXYGEN -typedef _lv_bar_mode_t lv_bar_mode_t; -#else -typedef uint8_t lv_bar_mode_t; -#endif /*DOXYGEN*/ - -typedef struct { - lv_obj_t * bar; - int32_t anim_start; - int32_t anim_end; - int32_t anim_state; -} _lv_bar_anim_t; - -typedef struct { - lv_obj_t obj; - int32_t cur_value; /**< Current value of the bar*/ - int32_t min_value; /**< Minimum value of the bar*/ - int32_t max_value; /**< Maximum value of the bar*/ - int32_t start_value; /**< Start value of the bar*/ - lv_area_t indic_area; /**< Save the indicator area. Might be used by derived types*/ - bool val_reversed; /**< Whether value been reversed */ - _lv_bar_anim_t cur_value_anim; - _lv_bar_anim_t start_value_anim; - lv_bar_mode_t mode : 2; /**< Type of bar*/ -} lv_bar_t; +typedef enum { + LV_BAR_ORIENTATION_AUTO, + LV_BAR_ORIENTATION_HORIZONTAL, + LV_BAR_ORIENTATION_VERTICAL +} lv_bar_orientation_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_bar_class; @@ -98,7 +78,7 @@ void lv_bar_set_start_value(lv_obj_t * obj, int32_t start_value, lv_anim_enable_ * @param obj pointer to the bar object * @param min minimum value * @param max maximum value - * @note If min is greater than max, the drawing direction becomes to the oppsite direction. + * @note If min is greater than max, the drawing direction becomes to the opposite direction. */ void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max); @@ -109,6 +89,13 @@ void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max); */ void lv_bar_set_mode(lv_obj_t * obj, lv_bar_mode_t mode); +/** + * Set the orientation of bar. + * @param obj pointer to bar object + * @param orientation bar orientation from `lv_bar_orientation_t` + */ +void lv_bar_set_orientation(lv_obj_t * obj, lv_bar_orientation_t orientation); + /*===================== * Getter functions *====================*/ @@ -148,6 +135,13 @@ int32_t lv_bar_get_max_value(const lv_obj_t * obj); */ lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj); +/** + * Get the orientation of bar. + * @param obj pointer to bar object + * @return bar orientation from ::lv_bar_orientation_t + */ +lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj); + /** * Give the bar is in symmetrical mode or not * @param obj pointer to bar object diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h new file mode 100644 index 000000000..891d14a34 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h @@ -0,0 +1,66 @@ +/** + * @file lv_bar_private.h + * + */ + +#ifndef LV_BAR_PRIVATE_H +#define LV_BAR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_bar.h" + +#if LV_USE_BAR != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_bar_anim_t { + lv_obj_t * bar; + int32_t anim_start; + int32_t anim_end; + int32_t anim_state; +}; + +struct lv_bar_t { + lv_obj_t obj; + int32_t cur_value; /**< Current value of the bar*/ + int32_t min_value; /**< Minimum value of the bar*/ + int32_t max_value; /**< Maximum value of the bar*/ + int32_t start_value; /**< Start value of the bar*/ + lv_area_t indic_area; /**< Save the indicator area. Might be used by derived types*/ + bool val_reversed; /**< Whether value been reversed */ + lv_bar_anim_t cur_value_anim; + lv_bar_anim_t start_value_anim; + lv_bar_mode_t mode : 2; /**< Type of bar*/ + lv_bar_orientation_t orientation : 2; /**< Orientation of bar*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BAR != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BAR_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.c b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.c index 8f57aa409..096dc2954 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.c @@ -7,7 +7,8 @@ * INCLUDES *********************/ -#include "lv_button.h" +#include "lv_button_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_BUTTON != 0 /********************* diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.h b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.h index 08ba1cdbc..eb7a0a57c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.h @@ -1,5 +1,5 @@ /** - * @file lv_btn.h + * @file lv_button.h * */ @@ -22,14 +22,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_obj_t obj; -} lv_button_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_button_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button_private.h new file mode 100644 index 000000000..ce310f32c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_button_private.h + * + */ + +#ifndef LV_BUTTON_PRIVATE_H +#define LV_BUTTON_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_button.h" + +#if LV_USE_BUTTON != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_button_t { + lv_obj_t obj; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BUTTON != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTON_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c index 9b67c31bd..b05602de4 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c @@ -6,7 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_buttonmatrix.h" +#include "lv_buttonmatrix_private.h" +#include "../../misc/lv_area_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_BUTTONMATRIX != 0 #include "../../misc/lv_assert.h" @@ -130,7 +133,7 @@ void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]) uint32_t unit_cnt = 0; /*Number of units in a row*/ uint32_t btn_cnt = 0; /*Number of buttons in a row*/ /*Count the buttons and units in this row*/ - while(map_row[btn_cnt] && strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { + while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { unit_cnt += get_button_width(btnm->ctrl_bits[btn_tot_i + btn_cnt]); btn_cnt++; } @@ -325,7 +328,7 @@ const char * lv_buttonmatrix_get_button_text(const lv_obj_t * obj, uint32_t btn_ while(btn_i != btn_id) { btn_i++; txt_i++; - if(strcmp(btnm->map_p[txt_i], "\n") == 0) txt_i++; + if(lv_strcmp(btnm->map_p[txt_i], "\n") == 0) txt_i++; } if(btn_i == btnm->btn_cnt) return NULL; @@ -703,7 +706,7 @@ static void draw_main(lv_event_t * e) for(btn_i = 0; btn_i < btnm->btn_cnt; btn_i++, txt_i++) { /*Search the next valid text in the map*/ - while(strcmp(btnm->map_p[txt_i], "\n") == 0) { + while(lv_strcmp(btnm->map_p[txt_i], "\n") == 0) { txt_i++; } @@ -775,9 +778,9 @@ static void draw_main(lv_event_t * e) #if LV_USE_ARABIC_PERSIAN_CHARS /*Get the size of the Arabic text and process it*/ - size_t len_ap = _lv_text_ap_calc_bytes_count(txt); + size_t len_ap = lv_text_ap_calc_bytes_count(txt); if(len_ap < sizeof(txt_ap)) { - _lv_text_ap_proc(txt, txt_ap); + lv_text_ap_proc(txt, txt_ap); txt = txt_ap; } #endif @@ -818,7 +821,7 @@ static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char uint32_t btn_cnt = 0; uint32_t i = 0; while(map[i] && map[i][0] != '\0') { - if(strcmp(map[i], "\n") != 0) { /*Do not count line breaks*/ + if(lv_strcmp(map[i], "\n") != 0) { /*Do not count line breaks*/ btn_cnt++; } else { @@ -950,7 +953,7 @@ static uint32_t get_button_from_point(lv_obj_t * obj, lv_point_t * p) BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ else btn_area.y2 += obj_cords.y1 + prow; - if(_lv_area_is_point_on(&btn_area, p, 0) != false) { + if(lv_area_is_point_on(&btn_area, p, 0) != false) { break; } } @@ -1029,7 +1032,7 @@ static bool has_popovers_in_top_row(lv_obj_t * obj) const char ** map_row = btnm->map_p; uint32_t btn_cnt = 0; - while(map_row[btn_cnt] && strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { + while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { if(button_is_popover(btnm->ctrl_bits[btn_cnt])) { return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h index 64c0d1b55..c095eec35 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h @@ -1,5 +1,5 @@ /** - * @file lv_btnmatrix.h + * @file lv_buttonmatrix.h * */ @@ -31,8 +31,7 @@ LV_EXPORT_CONST_INT(LV_BUTTONMATRIX_BUTTON_NONE); /** Type to store button control bits (disabled, hidden etc.) * The first 3 bits are used to store the width*/ -enum _lv_buttonmatrix_ctrl_t { - _LV_BUTTONMATRIX_WIDTH = 0x000F, /**< Reserved to store the size units*/ +typedef enum { LV_BUTTONMATRIX_CTRL_HIDDEN = 0x0010, /**< Button hidden*/ LV_BUTTONMATRIX_CTRL_NO_REPEAT = 0x0020, /**< Do not repeat press this button.*/ LV_BUTTONMATRIX_CTRL_DISABLED = 0x0040, /**< Disable this button.*/ @@ -40,34 +39,16 @@ enum _lv_buttonmatrix_ctrl_t { LV_BUTTONMATRIX_CTRL_CHECKED = 0x0100, /**< Button is currently toggled (e.g. checked).*/ LV_BUTTONMATRIX_CTRL_CLICK_TRIG = 0x0200, /**< 1: Send LV_EVENT_VALUE_CHANGE on CLICK, 0: Send LV_EVENT_VALUE_CHANGE on PRESS*/ LV_BUTTONMATRIX_CTRL_POPOVER = 0x0400, /**< Show a popover when pressing this key*/ - _LV_BUTTONMATRIX_CTRL_RESERVED_1 = 0x0800, /**< Reserved for later use*/ - _LV_BUTTONMATRIX_CTRL_RESERVED_2 = 0x1000, /**< Reserved for later use*/ - _LV_BUTTONMATRIX_CTRL_RESERVED_3 = 0x2000, /**< Reserved for later use*/ + LV_BUTTONMATRIX_CTRL_RESERVED_1 = 0x0800, /**< Reserved for later use*/ + LV_BUTTONMATRIX_CTRL_RESERVED_2 = 0x1000, /**< Reserved for later use*/ + LV_BUTTONMATRIX_CTRL_RESERVED_3 = 0x2000, /**< Reserved for later use*/ LV_BUTTONMATRIX_CTRL_CUSTOM_1 = 0x4000, /**< Custom free to use flag*/ LV_BUTTONMATRIX_CTRL_CUSTOM_2 = 0x8000, /**< Custom free to use flag*/ -}; - -#ifdef DOXYGEN -typedef _lv_buttonmatrix_ctrl_t lv_buttonmatrix_ctrl_t; -#else -typedef uint32_t lv_buttonmatrix_ctrl_t; -#endif /*DOXYGEN*/ +} lv_buttonmatrix_ctrl_t; typedef bool (*lv_buttonmatrix_button_draw_cb_t)(lv_obj_t * btnm, uint32_t btn_id, const lv_area_t * draw_area, const lv_area_t * clip_area); -/*Data of button matrix*/ -typedef struct { - lv_obj_t obj; - const char ** map_p; /*Pointer to the current map*/ - lv_area_t * button_areas; /*Array of areas of buttons*/ - lv_buttonmatrix_ctrl_t * ctrl_bits; /*Array of control bytes*/ - uint32_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/ - uint32_t row_cnt; /*Number of rows in 'map_p'(Handled by the library)*/ - uint32_t btn_id_sel; /*Index of the active button (being pressed/released etc) or LV_BUTTONMATRIX_BUTTON_NONE*/ - uint32_t one_check : 1; /*Single button toggled at once*/ -} lv_buttonmatrix_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_buttonmatrix_class; /********************** @@ -142,7 +123,6 @@ void lv_buttonmatrix_set_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t * Clear the attributes of all buttons of a button matrix * @param obj pointer to a button matrix object * @param ctrl attribute(s) to set from `lv_buttonmatrix_ctrl_t`. Values can be ORed. - * @param en true: set the attributes; false: clear the attributes */ void lv_buttonmatrix_clear_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t ctrl); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h new file mode 100644 index 000000000..6893b0e1e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_buttonmatrix_private.h + * + */ + +#ifndef LV_BUTTONMATRIX_PRIVATE_H +#define LV_BUTTONMATRIX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_buttonmatrix.h" + +#if LV_USE_BUTTONMATRIX != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of button matrix */ +struct lv_buttonmatrix_t { + lv_obj_t obj; + const char ** map_p; /**< Pointer to the current map */ + lv_area_t * button_areas; /**< Array of areas of buttons */ + lv_buttonmatrix_ctrl_t * ctrl_bits; /**< Array of control bytes */ + uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */ + uint32_t row_cnt; /**< Number of rows in 'map_p'(Handled by the library) */ + uint32_t btn_id_sel; /**< Index of the active button (being pressed/released etc) or LV_BUTTONMATRIX_BUTTON_NONE */ + uint32_t one_check : 1; /**< Single button toggled at once */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_BUTTONMATRIX != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTONMATRIX_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.c b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.c index 49b46fb50..560e24a1d 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_calendar.h" +#include "lv_calendar_private.h" +#include "../../draw/lv_draw_private.h" +#include "../../core/lv_obj_class_private.h" #include "../../../lvgl.h" #if LV_USE_CALENDAR @@ -35,6 +37,13 @@ static uint8_t get_month_length(int32_t year, int32_t month); static uint8_t is_leap_year(uint32_t year); static void highlight_update(lv_obj_t * calendar); +#if LV_USE_CALENDAR_CHINESE +static lv_calendar_date_t gregorian_get_last_month_time(lv_calendar_date_t * time); +static lv_calendar_date_t gregorian_get_next_month_time(lv_calendar_date_t * time); +static void chinese_calendar_set_day_name(lv_obj_t * calendar, uint8_t index, uint8_t day, + lv_calendar_date_t * gregorian_time); +#endif + /********************** * STATIC VARIABLES **********************/ @@ -133,18 +142,54 @@ void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month) uint8_t act_mo_len = get_month_length(d.year, d.month); uint8_t day_first = get_day_of_week(d.year, d.month, 1); uint8_t c; + +#if LV_USE_CALENDAR_CHINESE + lv_calendar_date_t gregorian_time; + gregorian_time = d; +#endif + for(i = day_first, c = 1; i < act_mo_len + day_first; i++, c++) { - lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c); +#if LV_USE_CALENDAR_CHINESE + if(calendar->use_chinese_calendar) { + gregorian_time.day = c; + chinese_calendar_set_day_name(obj, i, c, &gregorian_time); + } + else +#endif + lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c); } uint8_t prev_mo_len = get_month_length(d.year, d.month - 1); + +#if LV_USE_CALENDAR_CHINESE + gregorian_time = gregorian_get_last_month_time(&d); +#endif + for(i = 0, c = prev_mo_len - day_first + 1; i < day_first; i++, c++) { - lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c); +#if LV_USE_CALENDAR_CHINESE + if(calendar->use_chinese_calendar) { + gregorian_time.day = c; + chinese_calendar_set_day_name(obj, i, c, &gregorian_time); + } + else +#endif + lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c); lv_buttonmatrix_set_button_ctrl(calendar->btnm, i + 7, LV_BUTTONMATRIX_CTRL_DISABLED); } +#if LV_USE_CALENDAR_CHINESE + gregorian_time = gregorian_get_next_month_time(&d); +#endif + for(i = day_first + act_mo_len, c = 1; i < 6 * 7; i++, c++) { - lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c); +#if LV_USE_CALENDAR_CHINESE + if(calendar->use_chinese_calendar) { + gregorian_time.day = c; + chinese_calendar_set_day_name(obj, i, c, &gregorian_time); + } + else +#endif + lv_snprintf(calendar->nums[i], sizeof(calendar->nums[0]), "%d", c); lv_buttonmatrix_set_button_ctrl(calendar->btnm, i + 7, LV_BUTTONMATRIX_CTRL_DISABLED); } @@ -285,6 +330,8 @@ static void lv_calendar_constructor(const lv_obj_class_t * class_p, lv_obj_t * o lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_grow(calendar->btnm, 1); + lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + lv_calendar_set_showed_date(obj, calendar->showed_date.year, calendar->showed_date.month); lv_calendar_set_today_date(obj, calendar->today.year, calendar->today.month, calendar->today.day); } @@ -341,7 +388,7 @@ static uint8_t get_month_length(int32_t year, int32_t month) { month--; if(month < 0) { - year--; /*Already in the previous year (won't be less then -12 to skip a whole year)*/ + year--; /*Already in the previous year (won't be less than -12 to skip a whole year)*/ month = 12 + month; /*`month` is negative, the result will be < 12*/ } if(month >= 12) { @@ -408,4 +455,49 @@ static void highlight_update(lv_obj_t * obj) } } +#if LV_USE_CALENDAR_CHINESE + +static lv_calendar_date_t gregorian_get_last_month_time(lv_calendar_date_t * time) +{ + lv_calendar_date_t last_month_time; + if(time->month == 1) { + last_month_time.month = 12; + last_month_time.year = time->year - 1; + } + else { + last_month_time.month = time->month - 1; + last_month_time.year = time->year; + } + return last_month_time; +} + +static lv_calendar_date_t gregorian_get_next_month_time(lv_calendar_date_t * time) +{ + lv_calendar_date_t next_month_time; + if(time->month == 12) { + next_month_time.month = 1; + next_month_time.year = time->year + 1; + } + else { + next_month_time.month = time->month + 1; + next_month_time.year = time->year; + } + return next_month_time; +} + +static void chinese_calendar_set_day_name(lv_obj_t * obj, uint8_t index, uint8_t day, + lv_calendar_date_t * gregorian_time) +{ + lv_calendar_t * calendar = (lv_calendar_t *)obj; + const char * day_name = lv_calendar_get_day_name(gregorian_time); + if(day_name != NULL) + lv_snprintf(calendar->nums[index], sizeof(calendar->nums[0]), + "%d\n%s", + day, + day_name); + else + lv_snprintf(calendar->nums[index], sizeof(calendar->nums[0]), "%d", day); +} +#endif + #endif /*LV_USE_CALENDAR*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.h index 00e06a423..38c5d644f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.h @@ -30,23 +30,10 @@ extern "C" { */ typedef struct { uint16_t year; - int8_t month; /** 1..12*/ - int8_t day; /** 1..31*/ + int8_t month; /**< 1..12 */ + int8_t day; /**< 1..31 */ } lv_calendar_date_t; -/*Data of calendar*/ -typedef struct { - lv_obj_t obj; - /*New data for this type*/ - lv_obj_t * btnm; - lv_calendar_date_t today; /**< Date of today*/ - lv_calendar_date_t showed_date; /**< Currently visible month (day is ignored)*/ - lv_calendar_date_t * highlighted_dates; /**< Apply different style on these days (pointer to user-defined array)*/ - size_t highlighted_dates_num; /**< Number of elements in `highlighted_days`*/ - const char * map[8 * 7]; - char nums [7 * 6][4]; -} lv_calendar_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_class; /********************** @@ -162,6 +149,7 @@ lv_result_t lv_calendar_get_pressed_date(const lv_obj_t * calendar, lv_calendar_ #include "lv_calendar_header_arrow.h" #include "lv_calendar_header_dropdown.h" +#include "lv_calendar_chinese.h" #endif /*LV_USE_CALENDAR*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c new file mode 100644 index 000000000..81c844bf1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c @@ -0,0 +1,288 @@ +/** + * @file lv_calendar_chinese.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_calendar_chinese_private.h" +#include "lv_calendar_private.h" +#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char festival_name[20]; + uint8_t month; + uint8_t day; +} lv_calendar_festival_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +static const uint32_t calendar_chinese_table[199] = {/*1901-2099*/ + 0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A, /*1901-1910*/ + 0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754, /*1911-1920*/ + 0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E, /*1921-1930*/ + 0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48, /*1931-1940*/ + 0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51, /*1941-1950*/ + 0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C, /*1951-1960*/ + 0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46, /*1961-1970*/ + 0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50, /*1971-1980*/ + 0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x093746, 0x5497BB, /*1981-1990*/ + 0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645, /*1991-2000*/ + 0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E, /*2001-2010*/ + 0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9, /*2011-2020*/ + 0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x69573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43, /*2021-2030*/ + 0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C, /*2031-2040*/ + 0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37, /*2041-2050*/ + 0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06B244, 0x4AB638, 0x0AAE4C, 0x092E42, /*2051-2060*/ + 0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B, /*2061-2070*/ + 0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6, /*2071-2080*/ + 0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E, /*2081-2090*/ + 0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 /*2091-2099*/ +}; + +static const uint16_t month_total_day[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; + +static const char * chinese_calendar_month_name[] = {"正月", "二月", "三月", "四月", "五月", "六月", + "七月", "八月", "九月", "十月", "十一月", "腊月" + }; + +static const char * chinese_calendar_leep_month_name[] = {"闰正月", "闰二月", "闰三月", "闰四月", "闰五月", "闰六月", + "闰七月", "闰八月", "闰九月", "闰十月", "闰十一月", "闰腊月" + }; + +static const char * chinese_calendar_day_name[] = {"初一", "初二", "初三", "初四", "初五", + "初六", "初七", "初八", "初九", "初十", + "十一", "十二", "十三", "十四", "十五", + "十六", "十七", "十八", "十九", "二十", + "廿一", "廿二", "廿三", "廿四", "廿五", + "廿六", "廿七", "廿八", "廿九", "三十" + }; + +static const lv_calendar_festival_t festivals_base_chinese[] = { + {"春节", 1, 1}, + {"元宵节", 1, 15}, + {"端午节", 5, 5}, + {"七夕节", 7, 7}, + {"中元节", 7, 15}, + {"中秋节", 8, 15}, + {"重阳节", 9, 9}, + {"腊八节", 12, 8}, + {"除夕", 12, 29},/* To determine whether it is 12.29 or 12.30. */ + {"除夕", 12, 30},/* To determine whether it is 12.29 or 12.30. */ +}; + +static const lv_calendar_festival_t festivals_base_gregorian[] = { + {"元旦", 1, 1}, + {"情人节", 2, 14}, + {"妇女节", 3, 8}, + {"植树节", 3, 12}, + {"消费节", 3, 15}, + {"愚人节", 4, 1}, + {"劳动节", 5, 1}, + {"青年节", 5, 4}, + {"儿童节", 6, 1}, + {"建党节", 7, 1}, + {"建军节", 8, 1}, + {"教师节", 9, 10}, + {"国庆节", 10, 1}, + {"万圣节", 10, 31}, + {"平安夜", 12, 24}, + {"圣诞节", 12, 25}, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en) +{ + lv_calendar_t * calendar = (lv_calendar_t *)obj; + calendar->use_chinese_calendar = en; + lv_calendar_set_showed_date(obj, calendar->today.year, calendar->today.month); +} + +const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) +{ + uint16_t i, len; + lv_calendar_chinese_t chinese_calendar; + chinese_calendar = lv_calendar_gregorian_to_chinese(gregorian); + + if(gregorian->year > 2099 || gregorian->year < 1901) + return NULL; + + len = sizeof(festivals_base_chinese) / sizeof(lv_calendar_festival_t); + for(i = 0; i < len; i++) { + if((chinese_calendar.today.month == festivals_base_chinese[i].month) && + (chinese_calendar.today.day == festivals_base_chinese[i].day) && + chinese_calendar.leep_month == false) { + if(chinese_calendar.today.month == 12 && chinese_calendar.today.day == 29) { + if((calendar_chinese_table[chinese_calendar.today.year - 1901] & 0xf00000) != 0) { + if((calendar_chinese_table[chinese_calendar.today.year - 1901] & 0x000080) == 0) { + return festivals_base_chinese[i].festival_name; + } + } + else { + if((calendar_chinese_table[chinese_calendar.today.year - 1901] & 0x000100) == 0) { + return festivals_base_chinese[i].festival_name; + } + } + } + else { + return festivals_base_chinese[i].festival_name; + } + } + } + + len = sizeof(festivals_base_gregorian) / sizeof(lv_calendar_festival_t); + for(i = 0; i < len; i++) { + if((gregorian->month == festivals_base_gregorian[i].month) && + (gregorian->day == festivals_base_gregorian[i].day)) + return festivals_base_gregorian[i].festival_name; + } + + if(chinese_calendar.today.day == 1) { + if(chinese_calendar.leep_month == false) + return chinese_calendar_month_name[chinese_calendar.today.month - 1]; + else { + return chinese_calendar_leep_month_name[chinese_calendar.today.month - 1]; + } + } + + return (char *)chinese_calendar_day_name[chinese_calendar.today.day - 1]; +} + +lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian) +{ + uint16_t year = gregorian->year; + uint8_t month = gregorian->month; + uint8_t day = gregorian->day; + + /*Record the number of days between the Spring Festival + and the New Year's Day of that year.*/ + uint16_t by_spring; + + /*Record the number of days from the gregorian calendar + to the New Year's Day of that year.*/ + uint16_t by_gregorian; + + /*Record the number of days in that month*/ + uint8_t days_per_month; + + /*Record from which month the calculation starts.*/ + uint8_t index; + + bool leep_month; + lv_calendar_chinese_t chinese_calendar; + + if(year < 1901 || year > 2099) { + chinese_calendar.leep_month = 0; + chinese_calendar.today.year = 2000; + chinese_calendar.today.month = 1; + chinese_calendar.today.day = 1; + return chinese_calendar; + } + + if(((calendar_chinese_table[year - 1901] & 0x0060) >> 5) == 1) + by_spring = (calendar_chinese_table[year - 1901] & 0x001F) - 1; + else + by_spring = (calendar_chinese_table[year - 1901] & 0x001F) - 1 + 31; + + by_gregorian = month_total_day[month - 1] + day - 1; + + if((!(year % 4)) && (month > 2)) + by_gregorian++; + + if(by_gregorian >= by_spring) {/*Gregorian calendar days after the Spring Festival*/ + by_gregorian -= by_spring; + month = 1; + index = 1; + leep_month = false; + + if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0) + days_per_month = 29; + else + days_per_month = 30; + + while(by_gregorian >= days_per_month) { + by_gregorian -= days_per_month; + index++; + + if(month == ((calendar_chinese_table[year - 1901] & 0xF00000) >> 20)) { + leep_month = !leep_month; + if(leep_month == false) + month++; + } + else + month++; + + if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0) + days_per_month = 29; + else + days_per_month = 30; + } + day = by_gregorian + 1; + } + else {/*Solar day before the Spring Festival*/ + by_spring -= by_gregorian; + year--; + month = 12; + if(((calendar_chinese_table[year - 1901] & 0xF00000) >> 20) == 0) + index = 12; + else + index = 13; + leep_month = false; + + if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0) + days_per_month = 29; + else + days_per_month = 30; + + while(by_spring > days_per_month) { + by_spring -= days_per_month; + index--; + + if(leep_month == false) + month--; + + if(month == ((calendar_chinese_table[year - 1901] & 0xF00000) >> 20)) + leep_month = !leep_month; + + if((calendar_chinese_table[year - 1901] & (0x80000 >> (index - 1))) == 0) + days_per_month = 29; + else + days_per_month = 30; + } + + day = days_per_month - by_spring + 1; + } + chinese_calendar.today.day = day; + chinese_calendar.today.month = month; + chinese_calendar.today.year = year; + chinese_calendar.leep_month = leep_month; + return chinese_calendar; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_CALENDAR_CHINESE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h new file mode 100644 index 000000000..8d5b174ab --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.h @@ -0,0 +1,59 @@ +/** + * @file lv_calendar_chinese.h + * + */ + +#ifndef LV_CALENDAR_CHINESE_H +#define LV_CALENDAR_CHINESE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_obj.h" +#include "lv_calendar.h" +#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE + +/********************* + * DEFINES + *********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Enable the chinese calendar. + * @param obj pointer to a calendar object. + * @param en true: enable chinese calendar; false: disable + */ +void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en); + +/** + * Get the name of the day + * @param gregorian to obtain the gregorian time for the name + * @return return the name of the day + */ +const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian); + +/** + * Get the chinese time of the gregorian time (reference: https://www.cnblogs.com/liyang31tg/p/4123171.html) + * @param gregorian need to convert to chinese time in gregorian time + * @return return the chinese time of the gregorian time + */ +lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_CALENDAR_CHINESE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_CHINESE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese_private.h new file mode 100644 index 000000000..5572259e2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_calendar_chinese_private.h + * + */ + +#ifndef LV_CALENDAR_CHINESE_PRIVATE_H +#define LV_CALENDAR_CHINESE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_calendar_chinese.h" + +#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_calendar_chinese_t { + lv_calendar_date_t today; + bool leep_month; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_CHINESE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.c b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.c index 3a8eeaa1a..09b201d04 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "../../core/lv_obj_class_private.h" #include "lv_calendar_header_arrow.h" #if LV_USE_CALENDAR && LV_USE_CALENDAR_HEADER_ARROW diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.c b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.c index 77d508be9..41fe53a82 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "../../core/lv_obj_class_private.h" #include "lv_calendar_header_dropdown.h" #if LV_USE_CALENDAR && LV_USE_CALENDAR_HEADER_DROPDOWN @@ -78,12 +79,12 @@ void lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent, const char * y } /* Search for the year dropdown - * Index is 0 because in the header dropdown constructor the year dropdpwn (year_dd) + * Index is 0 because in the header dropdown constructor the year dropdown (year_dd) * is the first created child of the header */ const int32_t year_dropdown_index = 0; lv_obj_t * year_dropdown = lv_obj_get_child_by_type(header, year_dropdown_index, &lv_dropdown_class); if(NULL == year_dropdown) { - /* year dropdpwn not found */ + /* year dropdown not found */ return; } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_private.h new file mode 100644 index 000000000..d4a9b535b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_private.h @@ -0,0 +1,70 @@ +/** + * @file lv_calendar_private.h + * + */ + +#ifndef LV_CALENDAR_PRIVATE_H +#define LV_CALENDAR_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_calendar.h" + +#if LV_USE_CALENDAR + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of calendar */ +struct lv_calendar_t { + lv_obj_t obj; + /* New data for this type */ + lv_obj_t * btnm; + lv_calendar_date_t today; /**< Date of today */ + lv_calendar_date_t showed_date; /**< Currently visible month (day is ignored) */ + lv_calendar_date_t * highlighted_dates; /**< Apply different style on these days (pointer to user-defined array) */ + size_t highlighted_dates_num; /**< Number of elements in `highlighted_days` */ + const char * map[8 * 7]; +#ifdef LV_USE_CALENDAR_CHINESE + bool use_chinese_calendar; + + /** 7 * 6: A week has 7 days, and the calendar displays 6 weeks in total. + * 20: Including the number of dates, line breaks, names for each day, + * and reserving several spaces for addresses. */ + char nums [7 * 6][20]; +#else + /** 7 * 6: A week has 7 days, and the calendar displays 6 weeks in total. + * 6: Including the number of dates, and reserving several spaces for + * addresses.*/ + char nums [7 * 6][4]; +#endif +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CALENDAR */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CALENDAR_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.c b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.c index 4ce2017af..4aa46f33b 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.c @@ -1,16 +1,21 @@ -/** +/** * @file lv_canvas.c * */ +/** + * Modified by NXP in 2024 + */ + /********************* * INCLUDES *********************/ -#include "lv_canvas.h" +#include "lv_canvas_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_CANVAS != 0 #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" -#include "../../draw/lv_draw.h" +#include "../../draw/lv_draw_private.h" #include "../../core/lv_refr.h" #include "../../display/lv_display.h" #include "../../draw/sw/lv_draw_sw.h" @@ -107,20 +112,35 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv lv_draw_buf_t * draw_buf = canvas->draw_buf; lv_color_format_t cf = draw_buf->header.cf; - uint32_t stride = draw_buf->header.stride; uint8_t * data = lv_draw_buf_goto_xy(draw_buf, x, y); if(LV_COLOR_FORMAT_IS_INDEXED(cf)) { - /*Indexed image bpp could be less than 8, calculate again*/ - uint8_t * buf = (uint8_t *)canvas->draw_buf->data; - buf += 8; - buf += y * stride; - buf += x >> 3; - uint32_t bit = 7 - (x & 0x7); - uint32_t c_int = color.blue; + uint8_t shift; + uint8_t c_int = color.blue; + switch(cf) { + case LV_COLOR_FORMAT_I1: + shift = 7 - (x & 0x7); + break; + case LV_COLOR_FORMAT_I2: + shift = 6 - 2 * (x & 0x3); + break; + case LV_COLOR_FORMAT_I4: + shift = 4 - 4 * (x & 0x1); + break; + case LV_COLOR_FORMAT_I8: + /*Indexed8 format is a easy case, process and return.*/ + *data = c_int; + default: + return; + } - *buf &= ~(1 << bit); - *buf |= c_int << bit; + uint8_t bpp = lv_color_format_get_bpp(cf); + uint8_t mask = (1 << bpp) - 1; + c_int &= mask; + *data = (*data & ~(mask << shift)) | (c_int << shift); + } + else if(cf == LV_COLOR_FORMAT_L8) { + *data = lv_color_luminance(color); } else if(cf == LV_COLOR_FORMAT_A8) { *data = opa; @@ -149,6 +169,11 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv buf->blue = color.blue; buf->alpha = opa; } + else if(cf == LV_COLOR_FORMAT_AL88) { + lv_color16a_t * buf = (lv_color16a_t *)data; + buf->lumi = lv_color_luminance(color); + buf->alpha = 255; + } lv_obj_invalidate(obj); } @@ -212,6 +237,13 @@ lv_color32_t lv_canvas_get_px(lv_obj_t * obj, int32_t x, int32_t y) ret.alpha = px[0]; break; } + case LV_COLOR_FORMAT_L8: { + ret.red = *px; + ret.green = *px; + ret.blue = *px; + ret.alpha = 0xFF; + break; + } default: lv_memzero(&ret, sizeof(lv_color32_t)); break; @@ -252,7 +284,7 @@ void lv_canvas_copy_buf(lv_obj_t * obj, const lv_area_t * canvas_area, lv_draw_b lv_canvas_t * canvas = (lv_canvas_t *)obj; if(canvas->draw_buf == NULL) return; - LV_ASSERT_MSG(canvas->draw_buf->header.cf != dest_buf->header.cf, "Color formats must be the same"); + LV_ASSERT_MSG(canvas->draw_buf->header.cf == dest_buf->header.cf, "Color formats must be the same"); lv_draw_buf_copy(canvas->draw_buf, canvas_area, dest_buf, dest_area); } @@ -303,6 +335,27 @@ void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa) } } } + else if(header->cf == LV_COLOR_FORMAT_L8) { + uint8_t c8 = lv_color_luminance(color); + for(y = 0; y < header->h; y++) { + uint8_t * buf = (uint8_t *)(data + y * stride); + for(x = 0; x < header->w; x++) { + buf[x] = c8; + } + } + } + else if(header->cf == LV_COLOR_FORMAT_AL88) { + lv_color16a_t c; + c.lumi = lv_color_luminance(color); + c.alpha = 255; + for(y = 0; y < header->h; y++) { + lv_color16a_t * buf = (lv_color16a_t *)(data + y * stride); + for(x = 0; x < header->w; x++) { + buf[x] = c; + } + } + } + else { for(y = 0; y < header->h; y++) { for(x = 0; x < header->w; x++) { @@ -329,14 +382,33 @@ void lv_canvas_init_layer(lv_obj_t * obj, lv_layer_t * layer) layer->color_format = header->cf; layer->buf_area = canvas_area; layer->_clip_area = canvas_area; + layer->phy_clip_area = canvas_area; +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_matrix_identity(&layer->matrix); +#endif } void lv_canvas_finish_layer(lv_obj_t * canvas, lv_layer_t * layer) { + if(layer->draw_task_head == NULL) return; + + bool task_dispatched; + while(layer->draw_task_head) { lv_draw_dispatch_wait_for_request(); - lv_draw_dispatch_layer(lv_obj_get_display(canvas), layer); + task_dispatched = lv_draw_dispatch_layer(lv_obj_get_display(canvas), layer); + + if(!task_dispatched) { + lv_draw_wait_for_finish(); + lv_draw_dispatch_request(); + } } + lv_obj_invalidate(canvas); +} + +uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride) +{ + return (uint32_t)LV_CANVAS_BUF_SIZE(w, h, bpp, stride); } /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.h b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.h index 945132778..d669b1773 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.h @@ -29,13 +29,6 @@ extern "C" { **********************/ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_canvas_class; -/*Data of canvas*/ -typedef struct { - lv_image_t img; - lv_draw_buf_t * draw_buf; - lv_draw_buf_t static_buf; -} lv_canvas_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -53,22 +46,24 @@ lv_obj_t * lv_canvas_create(lv_obj_t * parent); /** * Set a buffer for the canvas. - * Use `lv_canvas_set_draw_buf` instead if you need to set a buffer with alignment requirement. - * @param buf a buffer where the content of the canvas will be. - * The required size is (lv_image_color_format_get_px_size(cf) * w) / 8 * h) - * It can be allocated with `lv_malloc()` or - * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or - * it can be an address in RAM or external SRAM - * @param canvas pointer to a canvas object - * @param w width of the canvas - * @param h height of the canvas - * @param cf color format. `LV_COLOR_FORMAT...` + * + * Use lv_canvas_set_draw_buf() instead if you need to set a buffer with alignment requirement. + * + * @param obj pointer to a canvas object + * @param buf buffer where content of canvas will be. + * The required size is (lv_image_color_format_get_px_size(cf) * w) / 8 * h) + * It can be allocated with `lv_malloc()` or + * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or + * it can be an address in RAM or external SRAM + * @param w width of canvas + * @param h height of canvas + * @param cf color format. `LV_COLOR_FORMAT...` */ void lv_canvas_set_buffer(lv_obj_t * obj, void * buf, int32_t w, int32_t h, lv_color_format_t cf); /** * Set a draw buffer for the canvas. A draw buffer either can be allocated by `lv_draw_buf_create()` - * or defined statically by `LV_DRAW_BUF_DEFINE`. When buffer start address and stride has alignment + * or defined statically by `LV_DRAW_BUF_DEFINE_STATIC`. When buffer start address and stride has alignment * requirement, it's recommended to use `lv_draw_buf_create`. * @param obj pointer to a canvas object * @param draw_buf pointer to a draw buffer @@ -138,7 +133,7 @@ const void * lv_canvas_get_buf(lv_obj_t * canvas); /** * Copy a buffer to the canvas - * @param canvas pointer to a canvas object + * @param obj pointer to a canvas object * @param canvas_area the area of the canvas to copy * @param dest_buf pointer to a buffer to store the copied data * @param dest_area the area of the destination buffer to copy to. If omitted NULL, copy to the whole `dest_buf` @@ -148,7 +143,7 @@ void lv_canvas_copy_buf(lv_obj_t * obj, const lv_area_t * canvas_area, lv_draw_b /** * Fill the canvas with color - * @param canvas pointer to a canvas + * @param obj pointer to a canvas * @param color the background color * @param opa the desired opacity */ @@ -179,10 +174,7 @@ void lv_canvas_finish_layer(lv_obj_t * canvas, lv_layer_t * layer); /** * Just a wrapper to `LV_CANVAS_BUF_SIZE` for bindings. */ -static inline uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride) -{ - return (uint32_t)LV_CANVAS_BUF_SIZE(w, h, bpp, stride); -} +uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride); #endif /*LV_USE_CANVAS*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas_private.h new file mode 100644 index 000000000..e43b8f3f3 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_canvas_private.h + * + */ + +#ifndef LV_CANVAS_PRIVATE_H +#define LV_CANVAS_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../image/lv_image_private.h" +#include "lv_canvas.h" + +#if LV_USE_CANVAS != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Canvas data */ +struct lv_canvas_t { + lv_image_t img; + lv_draw_buf_t * draw_buf; + lv_draw_buf_t static_buf; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CANVAS != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CANVAS_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.c b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.c index 782b7c5a6..4639cd5a5 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.c @@ -6,7 +6,11 @@ /********************* * INCLUDES *********************/ -#include "lv_chart.h" +#include "lv_chart_private.h" +#include "../../misc/lv_area_private.h" +#include "../../draw/lv_draw_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_CHART != 0 #include "../../misc/lv_assert.h" @@ -81,7 +85,7 @@ void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type) if(chart->type == LV_CHART_TYPE_SCATTER) { lv_chart_series_t * ser; - _LV_LL_READ_BACK(&chart->series_ll, ser) { + LV_LL_READ_BACK(&chart->series_ll, ser) { lv_free(ser->x_points); ser->x_points = NULL; } @@ -89,7 +93,7 @@ void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type) if(type == LV_CHART_TYPE_SCATTER) { lv_chart_series_t * ser; - _LV_LL_READ_BACK(&chart->series_ll, ser) { + LV_LL_READ_BACK(&chart->series_ll, ser) { ser->x_points = lv_malloc(sizeof(lv_point_t) * chart->point_cnt); LV_ASSERT_MALLOC(ser->x_points); if(ser->x_points == NULL) return; @@ -112,7 +116,7 @@ void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt) if(cnt < 1) cnt = 1; - _LV_LL_READ_BACK(&chart->series_ll, ser) { + LV_LL_READ_BACK(&chart->series_ll, ser) { if(chart->type == LV_CHART_TYPE_SCATTER) { if(!ser->x_ext_buf_assigned) new_points_alloc(obj, ser, cnt, &ser->x_points); } @@ -229,7 +233,7 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 p_out->x = lv_map(ser->x_points[id], chart->xmin[ser->x_axis_sec], chart->xmax[ser->x_axis_sec], 0, w); } else if(chart->type == LV_CHART_TYPE_BAR) { - uint32_t ser_cnt = _lv_ll_get_len(&chart->series_ll); + uint32_t ser_cnt = lv_ll_get_len(&chart->series_ll); int32_t ser_gap = lv_obj_get_style_pad_column(obj, LV_PART_ITEMS); /*Gap between the columns on adjacent X ticks*/ @@ -240,7 +244,7 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 p_out->x = (int32_t)((int32_t)(w - block_w) * id) / (chart->point_cnt - 1); lv_chart_series_t * ser_i = NULL; uint32_t ser_idx = 0; - _LV_LL_READ_BACK(&chart->series_ll, ser_i) { + LV_LL_READ_BACK(&chart->series_ll, ser_i) { if(ser_i == ser) break; ser_idx++; } @@ -286,9 +290,10 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_cha lv_chart_t * chart = (lv_chart_t *)obj; /* Allocate space for a new series and add it to the chart series linked list */ - lv_chart_series_t * ser = _lv_ll_ins_tail(&chart->series_ll); + lv_chart_series_t * ser = lv_ll_ins_tail(&chart->series_ll); LV_ASSERT_MALLOC(ser); if(ser == NULL) return NULL; + lv_memzero(ser, sizeof(lv_chart_series_t)); /* Allocate memory for point_cnt points, handle failure below */ ser->y_points = lv_malloc(sizeof(int32_t) * chart->point_cnt); @@ -299,7 +304,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_cha LV_ASSERT_MALLOC(ser->x_points); if(NULL == ser->x_points) { lv_free(ser->y_points); - _lv_ll_remove(&chart->series_ll, ser); + lv_ll_remove(&chart->series_ll, ser); lv_free(ser); return NULL; } @@ -309,7 +314,12 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_cha } if(ser->y_points == NULL) { - _lv_ll_remove(&chart->series_ll, ser); + if(ser->x_points) { + lv_free(ser->x_points); + ser->x_points = NULL; + } + + lv_ll_remove(&chart->series_ll, ser); lv_free(ser); return NULL; } @@ -342,7 +352,7 @@ void lv_chart_remove_series(lv_obj_t * obj, lv_chart_series_t * series) if(!series->y_ext_buf_assigned && series->y_points) lv_free(series->y_points); if(!series->x_ext_buf_assigned && series->x_points) lv_free(series->x_points); - _lv_ll_remove(&chart->series_ll, series); + lv_ll_remove(&chart->series_ll, series); lv_free(series); return; @@ -366,6 +376,15 @@ void lv_chart_set_series_color(lv_obj_t * chart, lv_chart_series_t * series, lv_ lv_chart_refresh(chart); } +lv_color_t lv_chart_get_series_color(lv_obj_t * chart, const lv_chart_series_t * series) +{ + LV_ASSERT_OBJ(chart, MY_CLASS); + LV_ASSERT_NULL(series); + LV_UNUSED(chart); + + return series->color; +} + void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -381,8 +400,8 @@ lv_chart_series_t * lv_chart_get_series_next(const lv_obj_t * obj, const lv_char LV_ASSERT_OBJ(obj, MY_CLASS); lv_chart_t * chart = (lv_chart_t *)obj; - if(ser == NULL) return _lv_ll_get_head(&chart->series_ll); - else return _lv_ll_get_next(&chart->series_ll, ser); + if(ser == NULL) return lv_ll_get_head(&chart->series_ll); + else return lv_ll_get_next(&chart->series_ll, ser); } /*===================== @@ -394,7 +413,7 @@ lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_di LV_ASSERT_OBJ(obj, MY_CLASS); lv_chart_t * chart = (lv_chart_t *)obj; - lv_chart_cursor_t * cursor = _lv_ll_ins_head(&chart->cursor_ll); + lv_chart_cursor_t * cursor = lv_ll_ins_head(&chart->cursor_ll); LV_ASSERT_MALLOC(cursor); if(cursor == NULL) return NULL; @@ -587,8 +606,8 @@ static void lv_chart_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_chart_t * chart = (lv_chart_t *)obj; - _lv_ll_init(&chart->series_ll, sizeof(lv_chart_series_t)); - _lv_ll_init(&chart->cursor_ll, sizeof(lv_chart_cursor_t)); + lv_ll_init(&chart->series_ll, sizeof(lv_chart_series_t)); + lv_ll_init(&chart->cursor_ll, sizeof(lv_chart_cursor_t)); chart->ymin[0] = 0; chart->xmin[0] = 0; @@ -617,24 +636,24 @@ static void lv_chart_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_chart_t * chart = (lv_chart_t *)obj; lv_chart_series_t * ser; while(chart->series_ll.head) { - ser = _lv_ll_get_head(&chart->series_ll); + ser = lv_ll_get_head(&chart->series_ll); if(!ser) continue; if(!ser->y_ext_buf_assigned) lv_free(ser->y_points); if(!ser->x_ext_buf_assigned) lv_free(ser->x_points); - _lv_ll_remove(&chart->series_ll, ser); + lv_ll_remove(&chart->series_ll, ser); lv_free(ser); } - _lv_ll_clear(&chart->series_ll); + lv_ll_clear(&chart->series_ll); lv_chart_cursor_t * cur; while(chart->cursor_ll.head) { - cur = _lv_ll_get_head(&chart->cursor_ll); - _lv_ll_remove(&chart->cursor_ll, cur); + cur = lv_ll_get_head(&chart->cursor_ll); + lv_ll_remove(&chart->cursor_ll, cur); lv_free(cur); } - _lv_ll_clear(&chart->cursor_ll); + lv_ll_clear(&chart->cursor_ll); LV_TRACE_OBJ_CREATE("finished"); } @@ -675,7 +694,7 @@ static void lv_chart_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_layer_t * layer = lv_event_get_layer(e); draw_div_lines(obj, layer); - if(_lv_ll_is_empty(&chart->series_ll) == false) { + if(lv_ll_is_empty(&chart->series_ll) == false) { if(chart->type == LV_CHART_TYPE_LINE) draw_series_line(obj, layer); else if(chart->type == LV_CHART_TYPE_BAR) draw_series_bar(obj, layer); else if(chart->type == LV_CHART_TYPE_SCATTER) draw_series_scatter(obj, layer); @@ -690,7 +709,7 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) lv_chart_t * chart = (lv_chart_t *)obj; lv_area_t series_clip_area; - bool mask_ret = _lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); + bool mask_ret = lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); if(mask_ret == false) return; const lv_area_t clip_area_ori = layer->_clip_area; @@ -764,7 +783,7 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) { lv_area_t clip_area; - if(_lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; + if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area; @@ -783,7 +802,7 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) lv_chart_series_t * ser; lv_area_t series_clip_area; - bool mask_ret = _lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); + bool mask_ret = lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); if(mask_ret == false) return; lv_draw_line_dsc_t line_dsc; @@ -804,10 +823,10 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) /*If there are at least as many points as pixels then draw only vertical lines*/ bool crowded_mode = (int32_t)chart->point_cnt >= w; - line_dsc.base.id1 = _lv_ll_get_len(&chart->series_ll) - 1; + line_dsc.base.id1 = lv_ll_get_len(&chart->series_ll) - 1; point_dsc_default.base.id1 = line_dsc.base.id1; /*Go through all data lines*/ - _LV_LL_READ_BACK(&chart->series_ll, ser) { + LV_LL_READ_BACK(&chart->series_ll, ser) { if(ser->hidden) { line_dsc.base.id1--; point_dsc_default.base.id1--; @@ -918,7 +937,7 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) { lv_area_t clip_area; - if(_lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; + if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area; @@ -951,7 +970,7 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) if(line_dsc.width == 1) line_dsc.raw_end = 1; /*Go through all data lines*/ - _LV_LL_READ_BACK(&chart->series_ll, ser) { + LV_LL_READ_BACK(&chart->series_ll, ser) { if(ser->hidden) continue; line_dsc.color = ser->color; point_dsc_default.bg_color = ser->color; @@ -1038,7 +1057,7 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) { lv_area_t clip_area; - if(_lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; + if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area; @@ -1053,7 +1072,7 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) int32_t h = lv_obj_get_content_height(obj); int32_t y_tmp; lv_chart_series_t * ser; - uint32_t ser_cnt = _lv_ll_get_len(&chart->series_ll); + uint32_t ser_cnt = lv_ll_get_len(&chart->series_ll); int32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Gap between the column on ~adjacent X*/ int32_t block_w = (w - ((chart->point_cnt - 1) * block_gap)) / chart->point_cnt; int32_t ser_gap = lv_obj_get_style_pad_column(obj, LV_PART_ITEMS); /*Gap between the columns on the ~same X*/ @@ -1080,7 +1099,7 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) col_dsc.base.id1 = 0; /*Draw the current point of all data line*/ - _LV_LL_READ(&chart->series_ll, ser) { + LV_LL_READ(&chart->series_ll, ser) { if(ser->hidden) continue; int32_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; @@ -1116,10 +1135,10 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) LV_ASSERT_OBJ(obj, MY_CLASS); lv_chart_t * chart = (lv_chart_t *)obj; - if(_lv_ll_is_empty(&chart->cursor_ll)) return; + if(lv_ll_is_empty(&chart->cursor_ll)) return; lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, &layer->_clip_area, &obj->coords)) return; + if(!lv_area_intersect(&clip_area, &layer->_clip_area, &obj->coords)) return; const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area; @@ -1141,7 +1160,7 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) int32_t point_h = lv_obj_get_style_width(obj, LV_PART_CURSOR) / 2; /*Go through all cursor lines*/ - _LV_LL_READ_BACK(&chart->cursor_ll, cursor) { + LV_LL_READ_BACK(&chart->cursor_ll, cursor) { lv_memcpy(&line_dsc, &line_dsc_ori, sizeof(lv_draw_line_dsc_t)); lv_memcpy(&point_dsc_tmp, &point_dsc_ori, sizeof(lv_draw_rect_dsc_t)); line_dsc.color = cursor->color; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.h b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.h index a010bfda4..de2583146 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.h @@ -33,89 +33,31 @@ LV_EXPORT_CONST_INT(LV_CHART_POINT_NONE); /** * Chart types */ -enum _lv_chart_type_t { +typedef enum { LV_CHART_TYPE_NONE, /**< Don't draw the series*/ LV_CHART_TYPE_LINE, /**< Connect the points with lines*/ LV_CHART_TYPE_BAR, /**< Draw columns*/ LV_CHART_TYPE_SCATTER, /**< Draw points and lines in 2D (x,y coordinates)*/ -}; - -#ifdef DOXYGEN -typedef _lv_chart_type_t lv_chart_type_t; -#else -typedef uint8_t lv_chart_type_t; -#endif /*DOXYGEN*/ +} lv_chart_type_t; /** * Chart update mode for `lv_chart_set_next` */ -enum _lv_chart_update_mode_t { +typedef enum { LV_CHART_UPDATE_MODE_SHIFT, /**< Shift old data to the left and add the new one the right*/ LV_CHART_UPDATE_MODE_CIRCULAR, /**< Add the new data in a circular way*/ -}; - -#ifdef DOXYGEN -typedef _lv_chart_update_mode_t lv_chart_update_mode_t; -#else -typedef uint8_t lv_chart_update_mode_t; -#endif /*DOXYGEN*/ +} lv_chart_update_mode_t; /** * Enumeration of the axis' */ -enum _lv_chart_axis_t { +typedef enum { LV_CHART_AXIS_PRIMARY_Y = 0x00, LV_CHART_AXIS_SECONDARY_Y = 0x01, LV_CHART_AXIS_PRIMARY_X = 0x02, LV_CHART_AXIS_SECONDARY_X = 0x04, - _LV_CHART_AXIS_LAST -}; - -#ifdef DOXYGEN -typedef _lv_chart_axis_t lv_chart_axis_t; -#else -typedef uint8_t lv_chart_axis_t; -#endif /*DOXYGEN*/ - -/** - * Descriptor a chart series - */ -typedef struct { - int32_t * x_points; - int32_t * y_points; - lv_color_t color; - uint32_t start_point; - uint32_t hidden : 1; - uint32_t x_ext_buf_assigned : 1; - uint32_t y_ext_buf_assigned : 1; - uint32_t x_axis_sec : 1; - uint32_t y_axis_sec : 1; -} lv_chart_series_t; - -typedef struct { - lv_point_t pos; - int32_t point_id; - lv_color_t color; - lv_chart_series_t * ser; - lv_dir_t dir; - uint32_t pos_set: 1; /*1: pos is set; 0: point_id is set*/ -} lv_chart_cursor_t; - -typedef struct { - lv_obj_t obj; - lv_ll_t series_ll; /**< Linked list for the series (stores lv_chart_series_t)*/ - lv_ll_t cursor_ll; /**< Linked list for the cursors (stores lv_chart_cursor_t)*/ - int32_t ymin[2]; - int32_t ymax[2]; - int32_t xmin[2]; - int32_t xmax[2]; - int32_t pressed_point_id; - uint32_t hdiv_cnt; /**< Number of horizontal division lines*/ - uint32_t vdiv_cnt; /**< Number of vertical division lines*/ - uint32_t point_cnt; /**< Point number in a data line*/ - lv_chart_type_t type : 3; /**< Line or column chart*/ - lv_chart_update_mode_t update_mode : 1; -} lv_chart_t; + LV_CHART_AXIS_LAST +} lv_chart_axis_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_chart_class; @@ -240,6 +182,14 @@ void lv_chart_hide_series(lv_obj_t * chart, lv_chart_series_t * series, bool hid */ void lv_chart_set_series_color(lv_obj_t * chart, lv_chart_series_t * series, lv_color_t color); +/** + * Get the color of a series + * @param chart pointer to a chart object. + * @param series pointer to a series object + * @return the color of the series + */ +lv_color_t lv_chart_get_series_color(lv_obj_t * chart, const lv_chart_series_t * series); + /** * Set the index of the x-axis start point in the data array. * This point will be considers the first (left) point and the other points will be drawn after it. diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart_private.h new file mode 100644 index 000000000..7cf9052aa --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart_private.h @@ -0,0 +1,85 @@ +/** + * @file lv_chart_private.h + * + */ + +#ifndef LV_CHART_PRIVATE_H +#define LV_CHART_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_chart.h" + +#if LV_USE_CHART != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Descriptor a chart series + */ +struct lv_chart_series_t { + int32_t * x_points; + int32_t * y_points; + lv_color_t color; + uint32_t start_point; + uint32_t hidden : 1; + uint32_t x_ext_buf_assigned : 1; + uint32_t y_ext_buf_assigned : 1; + uint32_t x_axis_sec : 1; + uint32_t y_axis_sec : 1; +}; + +struct lv_chart_cursor_t { + lv_point_t pos; + int32_t point_id; + lv_color_t color; + lv_chart_series_t * ser; + lv_dir_t dir; + uint32_t pos_set: 1; /**< 1: pos is set; 0: point_id is set*/ +}; + +struct lv_chart_t { + lv_obj_t obj; + lv_ll_t series_ll; /**< Linked list for the series (stores lv_chart_series_t)*/ + lv_ll_t cursor_ll; /**< Linked list for the cursors (stores lv_chart_cursor_t)*/ + int32_t ymin[2]; + int32_t ymax[2]; + int32_t xmin[2]; + int32_t xmax[2]; + int32_t pressed_point_id; + uint32_t hdiv_cnt; /**< Number of horizontal division lines*/ + uint32_t vdiv_cnt; /**< Number of vertical division lines*/ + uint32_t point_cnt; /**< Point number in a data line*/ + lv_chart_type_t type : 3; /**< Line or column chart*/ + lv_chart_update_mode_t update_mode : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CHART != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHART_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.c b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.c index ae42e7810..7a987ef3e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_checkbox.h" +#include "lv_checkbox_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_CHECKBOX != 0 #include "../../misc/lv_assert.h" @@ -75,7 +77,7 @@ void lv_checkbox_set_text(lv_obj_t * obj, const char * txt) size_t len; #if LV_USE_ARABIC_PERSIAN_CHARS - len = _lv_text_ap_calc_bytes_count(txt) + 1; + len = lv_text_ap_calc_bytes_count(txt) + 1; #else len = lv_strlen(txt) + 1; #endif @@ -87,7 +89,7 @@ void lv_checkbox_set_text(lv_obj_t * obj, const char * txt) if(NULL == cb->txt) return; #if LV_USE_ARABIC_PERSIAN_CHARS - _lv_text_ap_proc(txt, cb->txt); + lv_text_ap_proc(txt, cb->txt); #else lv_strcpy(cb->txt, txt); #endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.h b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.h index 1a0b3df1d..804ff600f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.h @@ -1,5 +1,5 @@ /** - * @file lv_cb.h + * @file lv_checkbox.h * */ @@ -22,16 +22,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_obj_t obj; - char * txt; - uint32_t static_txt : 1; -} lv_checkbox_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_checkbox_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox_private.h new file mode 100644 index 000000000..c927b65f2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_checkbox_private.h + * + */ + +#ifndef LV_CHECKBOX_PRIVATE_H +#define LV_CHECKBOX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_checkbox.h" + +#if LV_USE_CHECKBOX != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_checkbox_t { + lv_obj_t obj; + char * txt; + uint32_t static_txt : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_CHECKBOX != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHECKBOX_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c index c5d1c0189..1b34b44fc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c @@ -6,12 +6,14 @@ /********************* * INCLUDES *********************/ +#include "lv_dropdown_private.h" +#include "../../misc/lv_area_private.h" +#include "../../core/lv_obj_class_private.h" #include "../../core/lv_obj.h" -#include "lv_dropdown.h" #if LV_USE_DROPDOWN != 0 #include "../../misc/lv_assert.h" -#include "../../draw/lv_draw.h" +#include "../../draw/lv_draw_private.h" #include "../../core/lv_group.h" #include "../../indev/lv_indev.h" #include "../../display/lv_display.h" @@ -19,8 +21,8 @@ #include "../../misc/lv_anim.h" #include "../../misc/lv_math.h" #include "../../misc/lv_text_ap.h" +#include "../../misc/lv_text_private.h" #include "../../stdlib/lv_string.h" -#include /********************* * DEFINES @@ -60,6 +62,55 @@ static lv_obj_t * get_label(const lv_obj_t * obj); /********************** * STATIC VARIABLES **********************/ +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_DROPDOWN_TEXT, + .setter = lv_dropdown_set_text, + .getter = lv_dropdown_get_text, + }, + { + .id = LV_PROPERTY_DROPDOWN_OPTIONS, + .setter = lv_dropdown_set_options, + .getter = lv_dropdown_get_options, + }, + { + .id = LV_PROPERTY_DROPDOWN_OPTION_COUNT, + .setter = NULL, + .getter = lv_dropdown_get_option_count, + }, + { + .id = LV_PROPERTY_DROPDOWN_SELECTED, + .setter = lv_dropdown_set_selected, + .getter = lv_dropdown_get_selected, + }, + { + .id = LV_PROPERTY_DROPDOWN_DIR, + .setter = lv_dropdown_set_dir, + .getter = lv_dropdown_get_dir, + }, + { + .id = LV_PROPERTY_DROPDOWN_SYMBOL, + .setter = lv_dropdown_set_symbol, + .getter = lv_dropdown_get_symbol, + }, + { + .id = LV_PROPERTY_DROPDOWN_SELECTED_HIGHLIGHT, + .setter = lv_dropdown_set_selected_highlight, + .getter = lv_dropdown_get_selected_highlight, + }, + { + .id = LV_PROPERTY_DROPDOWN_LIST, + .setter = NULL, + .getter = lv_dropdown_get_list, + }, + { + .id = LV_PROPERTY_DROPDOWN_IS_OPEN, + .setter = NULL, + .getter = lv_dropdown_is_open, + }, +}; +#endif const lv_obj_class_t lv_dropdown_class = { .constructor_cb = lv_dropdown_constructor, @@ -72,6 +123,17 @@ const lv_obj_class_t lv_dropdown_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .base_class = &lv_obj_class, .name = "dropdown", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_DROPDOWN_START, + .prop_index_end = LV_PROPERTY_DROPDOWN_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_dropdown_property_names, + .names_count = sizeof(lv_dropdown_property_names) / sizeof(lv_property_name_t), +#endif +#endif }; const lv_obj_class_t lv_dropdownlist_class = { @@ -135,7 +197,7 @@ void lv_dropdown_set_options(lv_obj_t * obj, const char * options) #if LV_USE_ARABIC_PERSIAN_CHARS == 0 size_t len = lv_strlen(options) + 1; #else - size_t len = _lv_text_ap_calc_bytes_count(options) + 1; + size_t len = lv_text_ap_calc_bytes_count(options) + 1; #endif if(dropdown->options != NULL && dropdown->static_txt == 0) { @@ -151,7 +213,7 @@ void lv_dropdown_set_options(lv_obj_t * obj, const char * options) #if LV_USE_ARABIC_PERSIAN_CHARS == 0 lv_strcpy(dropdown->options, options); #else - _lv_text_ap_proc(options, dropdown->options); + lv_text_ap_proc(options, dropdown->options); #endif /*Now the text is dynamically allocated*/ @@ -211,7 +273,7 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos) #if LV_USE_ARABIC_PERSIAN_CHARS == 0 size_t ins_len = lv_strlen(option) + 1; #else - size_t ins_len = _lv_text_ap_calc_bytes_count(option) + 1; + size_t ins_len = lv_text_ap_calc_bytes_count(option) + 1; #endif size_t new_len = ins_len + old_len + 2; /*+2 for terminating NULL and possible \n*/ @@ -235,7 +297,7 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos) /*Add delimiter to existing options*/ if((insert_pos > 0) && (pos >= dropdown->option_cnt)) - _lv_text_ins(dropdown->options, _lv_text_encoded_get_char_id(dropdown->options, insert_pos++), "\n"); + lv_text_ins(dropdown->options, lv_text_encoded_get_char_id(dropdown->options, insert_pos++), "\n"); /*Insert the new option, adding \n if necessary*/ char * ins_buf = lv_malloc(ins_len + 2); /*+ 2 for terminating NULL and possible \n*/ @@ -244,11 +306,11 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos) #if LV_USE_ARABIC_PERSIAN_CHARS == 0 lv_strcpy(ins_buf, option); #else - _lv_text_ap_proc(option, ins_buf); + lv_text_ap_proc(option, ins_buf); #endif - if(pos < dropdown->option_cnt) strcat(ins_buf, "\n"); + if(pos < dropdown->option_cnt) lv_strcat(ins_buf, "\n"); - _lv_text_ins(dropdown->options, _lv_text_encoded_get_char_id(dropdown->options, insert_pos), ins_buf); + lv_text_ins(dropdown->options, lv_text_encoded_get_char_id(dropdown->options, insert_pos), ins_buf); lv_free(ins_buf); dropdown->option_cnt++; @@ -412,7 +474,7 @@ int32_t lv_dropdown_get_option_index(lv_obj_t * obj, const char * option) while(start[0] != '\0') { for(char_i = 0; (start[char_i] != '\n') && (start[char_i] != '\0'); char_i++); - if(option_len == char_i && memcmp(start, option, LV_MIN(option_len, char_i)) == 0) { + if(option_len == char_i && lv_memcmp(start, option, LV_MIN(option_len, char_i)) == 0) { return opt_i; } @@ -729,7 +791,7 @@ static void lv_dropdown_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_dropdown_close(obj); } else if(c == LV_KEY_ENTER) { - /* Handle the ENTER key only if it was send by an other object. + /* Handle the ENTER key only if it was send by another object. * Do no process it if ENTER is sent by the dropdown because it's handled in LV_EVENT_RELEASED */ lv_obj_t * indev_obj = lv_indev_get_active_obj(); if(indev_obj != obj) { @@ -920,7 +982,7 @@ static void draw_list(lv_event_t * e) * the selected option can be drawn on only the background*/ lv_area_t clip_area_core; bool has_common; - has_common = _lv_area_intersect(&clip_area_core, &layer->_clip_area, &dropdown->list->coords); + has_common = lv_area_intersect(&clip_area_core, &layer->_clip_area, &dropdown->list->coords); if(has_common) { const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area_core; @@ -1017,7 +1079,7 @@ static void draw_box_label(lv_obj_t * dropdown_obj, lv_layer_t * layer, uint32_t area_sel.x2 = list_obj->coords.x2; lv_area_t mask_sel; bool area_ok; - area_ok = _lv_area_intersect(&mask_sel, &layer->_clip_area, &area_sel); + area_ok = lv_area_intersect(&mask_sel, &layer->_clip_area, &area_sel); if(area_ok) { const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = mask_sel; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.h b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.h index 614f5f192..c9f55be12 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.h @@ -31,29 +31,21 @@ extern "C" { #define LV_DROPDOWN_POS_LAST 0xFFFF LV_EXPORT_CONST_INT(LV_DROPDOWN_POS_LAST); -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_obj_t obj; - lv_obj_t * list; /**< The dropped down list*/ - const char * text; /**< Text to display on the dropdown's button*/ - const void * symbol; /**< Arrow or other icon when the drop-down list is closed*/ - char * options; /**< Options in a '\n' separated list*/ - uint32_t option_cnt; /**< Number of options*/ - uint32_t sel_opt_id; /**< Index of the currently selected option*/ - uint32_t sel_opt_id_orig; /**< Store the original index on focus*/ - uint32_t pr_opt_id; /**< Index of the currently pressed option*/ - lv_dir_t dir : 4; /**< Direction in which the list should open*/ - uint8_t static_txt : 1; /**< 1: Only a pointer is saved in `options`*/ - uint8_t selected_highlight: 1; /**< 1: Make the selected option highlighted in the list*/ -} lv_dropdown_t; - -typedef struct { - lv_obj_t obj; - lv_obj_t * dropdown; -} lv_dropdown_list_t; +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(DROPDOWN, TEXT, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(DROPDOWN, OPTIONS, LV_PROPERTY_TYPE_TEXT, 1), + LV_PROPERTY_ID(DROPDOWN, OPTION_COUNT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(DROPDOWN, SELECTED, LV_PROPERTY_TYPE_INT, 3), + // LV_PROPERTY_ID(DROPDOWN, SELECTED_STR, LV_PROPERTY_TYPE_TEXT, 4), + LV_PROPERTY_ID(DROPDOWN, DIR, LV_PROPERTY_TYPE_INT, 5), + LV_PROPERTY_ID(DROPDOWN, SYMBOL, LV_PROPERTY_TYPE_TEXT, 6), + LV_PROPERTY_ID(DROPDOWN, SELECTED_HIGHLIGHT, LV_PROPERTY_TYPE_INT, 7), + LV_PROPERTY_ID(DROPDOWN, LIST, LV_PROPERTY_TYPE_OBJ, 8), + LV_PROPERTY_ID(DROPDOWN, IS_OPEN, LV_PROPERTY_TYPE_BOOL, 9), + LV_PROPERTY_DROPDOWN_END, +}; +#endif LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_dropdown_class; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_dropdownlist_class; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown_private.h new file mode 100644 index 000000000..67d879aa1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown_private.h @@ -0,0 +1,69 @@ +/** + * @file lv_dropdown_private.h + * + */ + +#ifndef LV_DROPDOWN_PRIVATE_H +#define LV_DROPDOWN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_dropdown.h" + +#if LV_USE_DROPDOWN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_dropdown_t { + lv_obj_t obj; + lv_obj_t * list; /**< The dropped down list*/ + const char * text; /**< Text to display on the dropdown's button*/ + const void * symbol; /**< Arrow or other icon when the drop-down list is closed*/ + char * options; /**< Options in a '\n' separated list*/ + uint32_t option_cnt; /**< Number of options*/ + uint32_t sel_opt_id; /**< Index of the currently selected option*/ + uint32_t sel_opt_id_orig; /**< Store the original index on focus*/ + uint32_t pr_opt_id; /**< Index of the currently pressed option*/ + uint8_t dir : 4; /**< Direction in which the list should open*/ + uint8_t static_txt : 1; /**< 1: Only a pointer is saved in `options`*/ + uint8_t selected_highlight: 1; /**< 1: Make the selected option highlighted in the list*/ +}; + +struct lv_dropdown_list_t { + lv_obj_t obj; + lv_obj_t * dropdown; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DROPDOWN != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DROPDOWN_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c index 8bd70caf1..147429436 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c @@ -6,7 +6,12 @@ /********************* * INCLUDES *********************/ -#include "lv_image.h" +#include "lv_image_private.h" +#include "../../misc/lv_area_private.h" +#include "../../draw/lv_draw_image_private.h" +#include "../../draw/lv_draw_private.h" +#include "../../core/lv_obj_event_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_IMAGE != 0 #include "../../stdlib/lv_string.h" @@ -29,6 +34,10 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_image(lv_event_t * e); static void scale_update(lv_obj_t * obj, int32_t scale_x, int32_t scale_y); static void update_align(lv_obj_t * obj); +#if LV_USE_OBJ_PROPERTY + static void lv_image_set_pivot_helper(lv_obj_t * obj, lv_point_t * pivot); + static lv_point_t lv_image_get_pivot_helper(lv_obj_t * obj); +#endif #if LV_USE_OBJ_PROPERTY static const lv_property_ops_t properties[] = { @@ -54,8 +63,8 @@ static const lv_property_ops_t properties[] = { }, { .id = LV_PROPERTY_IMAGE_PIVOT, - .setter = _lv_image_set_pivot, - .getter = lv_image_get_pivot, + .setter = lv_image_set_pivot_helper, + .getter = lv_image_get_pivot_helper, }, { .id = LV_PROPERTY_IMAGE_SCALE, @@ -83,7 +92,7 @@ static const lv_property_ops_t properties[] = { .getter = lv_image_get_antialias, }, { - .id = LV_PROPERTY_IMAGE_ALIGN, + .id = LV_PROPERTY_IMAGE_INNER_ALIGN, .setter = lv_image_set_inner_align, .getter = lv_image_get_inner_align, }, @@ -107,6 +116,12 @@ const lv_obj_class_t lv_image_class = { .prop_index_end = LV_PROPERTY_IMAGE_END, .properties = properties, .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_image_property_names, + .names_count = sizeof(lv_image_property_names) / sizeof(lv_property_name_t), +#endif + #endif }; @@ -257,7 +272,7 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle) LV_ASSERT_OBJ(obj, MY_CLASS); lv_image_t * img = (lv_image_t *)obj; - if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { + if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) { angle = 0; } else { @@ -273,7 +288,7 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle) lv_area_t a; lv_point_t pivot_px; lv_image_get_pivot(obj, &pivot_px); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); a.x1 += obj->coords.x1; a.y1 += obj->coords.y1; a.x2 += obj->coords.x1; @@ -289,7 +304,7 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle) lv_obj_refresh_ext_draw_size(obj); lv_display_enable_invalidation(disp, true); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); a.x1 += obj->coords.x1; a.y1 += obj->coords.y1; a.x2 += obj->coords.x1; @@ -302,7 +317,7 @@ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y) LV_ASSERT_OBJ(obj, MY_CLASS); lv_image_t * img = (lv_image_t *)obj; - if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { + if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) { x = 0; y = 0; } @@ -315,7 +330,7 @@ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y) lv_area_t a; lv_point_t pivot_px; lv_image_get_pivot(obj, &pivot_px); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); a.x1 += obj->coords.x1; a.y1 += obj->coords.y1; a.x2 += obj->coords.x1; @@ -332,7 +347,7 @@ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y) lv_display_enable_invalidation(disp, true); lv_image_get_pivot(obj, &pivot_px); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); a.x1 += obj->coords.x1; a.y1 += obj->coords.y1; a.x2 += obj->coords.x1; @@ -347,7 +362,7 @@ void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom) lv_image_t * img = (lv_image_t *)obj; /*If scale is set internally, do no overwrite it*/ - if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; + if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; if(zoom == img->scale_x && zoom == img->scale_y) return; @@ -363,7 +378,7 @@ void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom) lv_image_t * img = (lv_image_t *)obj; /*If scale is set internally, do no overwrite it*/ - if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; + if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; if(zoom == img->scale_x) return; @@ -379,7 +394,7 @@ void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom) lv_image_t * img = (lv_image_t *)obj; /*If scale is set internally, do no overwrite it*/ - if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; + if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; if(zoom == img->scale_y) return; @@ -622,7 +637,7 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_area_t a; int32_t w = lv_obj_get_width(obj); int32_t h = lv_obj_get_height(obj); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); *s = LV_MAX(*s, -a.x1); *s = LV_MAX(*s, -a.y1); *s = LV_MAX(*s, a.x2 - w); @@ -641,18 +656,18 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e) int32_t w = lv_obj_get_width(obj); int32_t h = lv_obj_get_height(obj); lv_area_t coords; - _lv_image_buf_get_transformed_area(&coords, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&coords, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); coords.x1 += obj->coords.x1; coords.y1 += obj->coords.y1; coords.x2 += obj->coords.x1; coords.y2 += obj->coords.y1; - info->res = _lv_area_is_point_on(&coords, info->point, 0); + info->res = lv_area_is_point_on(&coords, info->point, 0); } else { lv_area_t a; lv_obj_get_click_area(obj, &a); - info->res = _lv_area_is_point_on(&a, info->point, 0); + info->res = lv_area_is_point_on(&a, info->point, 0); } } else if(code == LV_EVENT_GET_SELF_SIZE) { @@ -696,7 +711,7 @@ static void draw_image(lv_event_t * e) } if(img->scale_x == LV_SCALE_NONE && img->scale_y == LV_SCALE_NONE) { - if(_lv_area_is_in(info->area, &obj->coords, 0) == false) { + if(lv_area_is_in(info->area, &obj->coords, 0) == false) { info->res = LV_COVER_RES_NOT_COVER; return; } @@ -705,14 +720,14 @@ static void draw_image(lv_event_t * e) lv_area_t a; lv_point_t pivot_px; lv_image_get_pivot(obj, &pivot_px); - _lv_image_buf_get_transformed_area(&a, lv_obj_get_width(obj), lv_obj_get_height(obj), 0, img->scale_x, img->scale_y, - &pivot_px); + lv_image_buf_get_transformed_area(&a, lv_obj_get_width(obj), lv_obj_get_height(obj), 0, img->scale_x, img->scale_y, + &pivot_px); a.x1 += obj->coords.x1; a.y1 += obj->coords.y1; a.x2 += obj->coords.x1; a.y2 += obj->coords.y1; - if(_lv_area_is_in(info->area, &a, 0) == false) { + if(lv_area_is_in(info->area, &a, 0) == false) { info->res = LV_COVER_RES_NOT_COVER; return; } @@ -745,23 +760,33 @@ static void draw_image(lv_event_t * e) draw_dsc.bitmap_mask_src = img->bitmap_mask_src; draw_dsc.src = img->src; - lv_area_t img_area = {obj->coords.x1, obj->coords.y1, - obj->coords.x1 + img->w - 1, obj->coords.y1 + img->h - 1 - }; - if(img->align < _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { - lv_area_align(&obj->coords, &img_area, img->align, img->offset.x, img->offset.y); + lv_area_set(&draw_dsc.image_area, obj->coords.x1, + obj->coords.y1, + obj->coords.x1 + img->w - 1, + obj->coords.y1 + img->h - 1); + + draw_dsc.clip_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN); + + lv_area_t coords; + if(img->align < LV_IMAGE_ALIGN_AUTO_TRANSFORM) { + lv_area_align(&obj->coords, &draw_dsc.image_area, img->align, img->offset.x, img->offset.y); + coords = draw_dsc.image_area; } else if(img->align == LV_IMAGE_ALIGN_TILE) { - _lv_area_intersect(&layer->_clip_area, &layer->_clip_area, &obj->coords); - lv_area_move(&img_area, img->offset.x, img->offset.y); + lv_area_intersect(&layer->_clip_area, &layer->_clip_area, &obj->coords); + lv_area_move(&draw_dsc.image_area, img->offset.x, img->offset.y); - lv_area_move(&img_area, - ((layer->_clip_area.x1 - img_area.x1 - (img->w - 1)) / img->w) * img->w, - ((layer->_clip_area.y1 - img_area.y1 - (img->h - 1)) / img->h) * img->h); + lv_area_move(&draw_dsc.image_area, + ((layer->_clip_area.x1 - draw_dsc.image_area.x1 - (img->w - 1)) / img->w) * img->w, + ((layer->_clip_area.y1 - draw_dsc.image_area.y1 - (img->h - 1)) / img->h) * img->h); + coords = layer->_clip_area; draw_dsc.tile = 1; } + else { + coords = draw_dsc.image_area; + } - lv_draw_image(layer, &draw_dsc, &img_area); + lv_draw_image(layer, &draw_dsc, &coords); layer->_clip_area = clip_area_ori; } @@ -793,7 +818,7 @@ static void scale_update(lv_obj_t * obj, int32_t scale_x, int32_t scale_y) lv_area_t a; lv_point_t pivot_px; lv_image_get_pivot(obj, &pivot_px); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); a.x1 += obj->coords.x1 - 1; a.y1 += obj->coords.y1 - 1; a.x2 += obj->coords.x1 + 1; @@ -810,7 +835,7 @@ static void scale_update(lv_obj_t * obj, int32_t scale_x, int32_t scale_y) lv_obj_refresh_ext_draw_size(obj); lv_display_enable_invalidation(disp, true); - _lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->scale_x, img->scale_y, &pivot_px); a.x1 += obj->coords.x1 - 1; a.y1 += obj->coords.y1 - 1; a.x2 += obj->coords.x1 + 1; @@ -835,4 +860,19 @@ static void update_align(lv_obj_t * obj) } } + +#if LV_USE_OBJ_PROPERTY +static void lv_image_set_pivot_helper(lv_obj_t * obj, lv_point_t * pivot) +{ + lv_image_set_pivot(obj, pivot->x, pivot->y); +} + +static lv_point_t lv_image_get_pivot_helper(lv_obj_t * obj) +{ + lv_point_t pivot; + lv_image_get_pivot(obj, &pivot); + return pivot; +} +#endif + #endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.h b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.h index 4b58c14ee..abc521774 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.h @@ -1,5 +1,5 @@ /** - * @file lv_img.h + * @file lv_image.h * */ @@ -34,33 +34,12 @@ extern "C" { * TYPEDEFS **********************/ -/** - * Data of image - */ -typedef struct { - lv_obj_t obj; - const void * src; /**< Image source: Pointer to an array or a file or a symbol*/ - const lv_image_dsc_t * bitmap_mask_src; /**< Pointer to an A8 bitmap mask */ - lv_point_t offset; - int32_t w; /**< Width of the image (Handled by the library)*/ - int32_t h; /**< Height of the image (Handled by the library)*/ - uint32_t rotation; /**< Rotation angle of the image*/ - uint32_t scale_x; /**< 256 means no zoom, 512 double size, 128 half size*/ - uint32_t scale_y; /**< 256 means no zoom, 512 double size, 128 half size*/ - lv_point_t pivot; /**< Rotation center of the image*/ - uint32_t src_type : 2; /**< See: lv_image_src_t*/ - uint32_t cf : 5; /**< Color format from `lv_color_format_t`*/ - uint32_t antialias : 1; /**< Apply anti-aliasing in transformations (rotate, zoom)*/ - uint32_t align: 4; /**< Image size mode when image size and object size is different. See `lv_image_align_t`*/ - uint32_t blend_mode: 4; /**< Element of `lv_blend_mode_t`*/ -} lv_image_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_image_class; /** * Image size mode, when image size and object size is different */ -enum _lv_image_align_t { +typedef enum { LV_IMAGE_ALIGN_DEFAULT = 0, LV_IMAGE_ALIGN_TOP_LEFT, LV_IMAGE_ALIGN_TOP_MID, @@ -71,30 +50,24 @@ enum _lv_image_align_t { LV_IMAGE_ALIGN_LEFT_MID, LV_IMAGE_ALIGN_RIGHT_MID, LV_IMAGE_ALIGN_CENTER, - _LV_IMAGE_ALIGN_AUTO_TRANSFORM, + LV_IMAGE_ALIGN_AUTO_TRANSFORM, LV_IMAGE_ALIGN_STRETCH, LV_IMAGE_ALIGN_TILE, -}; - -#ifdef DOXYGEN -typedef _lv_image_align_t lv_image_align_t; -#else -typedef uint8_t lv_image_align_t; -#endif /*DOXYGEN*/ +} lv_image_align_t; #if LV_USE_OBJ_PROPERTY enum { - LV_PROPERTY_ID(IMAGE, SRC, LV_PROPERTY_TYPE_IMGSRC, 0), - LV_PROPERTY_ID(IMAGE, OFFSET_X, LV_PROPERTY_TYPE_INT, 1), - LV_PROPERTY_ID(IMAGE, OFFSET_Y, LV_PROPERTY_TYPE_INT, 2), - LV_PROPERTY_ID(IMAGE, ROTATION, LV_PROPERTY_TYPE_INT, 3), - LV_PROPERTY_ID(IMAGE, PIVOT, LV_PROPERTY_TYPE_POINTER, 4), - LV_PROPERTY_ID(IMAGE, SCALE, LV_PROPERTY_TYPE_INT, 5), - LV_PROPERTY_ID(IMAGE, SCALE_X, LV_PROPERTY_TYPE_INT, 6), - LV_PROPERTY_ID(IMAGE, SCALE_Y, LV_PROPERTY_TYPE_INT, 7), - LV_PROPERTY_ID(IMAGE, BLEND_MODE, LV_PROPERTY_TYPE_INT, 8), - LV_PROPERTY_ID(IMAGE, ANTIALIAS, LV_PROPERTY_TYPE_INT, 9), - LV_PROPERTY_ID(IMAGE, ALIGN, LV_PROPERTY_TYPE_INT, 10), + LV_PROPERTY_ID(IMAGE, SRC, LV_PROPERTY_TYPE_IMGSRC, 0), + LV_PROPERTY_ID(IMAGE, OFFSET_X, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(IMAGE, OFFSET_Y, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(IMAGE, ROTATION, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_ID(IMAGE, PIVOT, LV_PROPERTY_TYPE_POINT, 4), + LV_PROPERTY_ID(IMAGE, SCALE, LV_PROPERTY_TYPE_INT, 5), + LV_PROPERTY_ID(IMAGE, SCALE_X, LV_PROPERTY_TYPE_INT, 6), + LV_PROPERTY_ID(IMAGE, SCALE_Y, LV_PROPERTY_TYPE_INT, 7), + LV_PROPERTY_ID(IMAGE, BLEND_MODE, LV_PROPERTY_TYPE_INT, 8), + LV_PROPERTY_ID(IMAGE, ANTIALIAS, LV_PROPERTY_TYPE_INT, 9), + LV_PROPERTY_ID(IMAGE, INNER_ALIGN, LV_PROPERTY_TYPE_INT, 10), LV_PROPERTY_IMAGE_END, }; #endif @@ -160,50 +133,42 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle); */ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y); -/** - * Set pivot similar to get_pivot - */ -static inline void _lv_image_set_pivot(lv_obj_t * obj, lv_point_t * pivot) -{ - lv_image_set_pivot(obj, pivot->x, pivot->y); -} - /** * Set the zoom factor of the image. * Note that indexed and alpha only images can't be transformed. - * @param img pointer to an image object - * @param zoom the zoom factor. - * @example 256 or LV_ZOOM_IMAGE_NONE for no zoom - * @example <256: scale down - * @example >256 scale up - * @example 128 half size - * @example 512 double size + * @param obj pointer to an image object + * @param zoom the zoom factor. Example values: + * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - <256: scale down + * - >256: scale up + * - 128: half size + * - 512: double size */ void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom); /** * Set the horizontal zoom factor of the image. * Note that indexed and alpha only images can't be transformed. - * @param img pointer to an image object - * @param zoom the zoom factor. - * @example 256 or LV_ZOOM_IMAGE_NONE for no zoom - * @example <256: scale down - * @example >256 scale up - * @example 128 half size - * @example 512 double size + * @param obj pointer to an image object + * @param zoom the zoom factor. Example values: + * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - <256: scale down + * - >256: scale up + * - 128: half size + * - 512: double size */ void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom); /** * Set the vertical zoom factor of the image. * Note that indexed and alpha only images can't be transformed. - * @param img pointer to an image object - * @param zoom the zoom factor. - * @example 256 or LV_ZOOM_IMAGE_NONE for no zoom - * @example <256: scale down - * @example >256 scale up - * @example 128 half size - * @example 512 double size + * @param obj pointer to an image object + * @param zoom the zoom factor. Example values: + * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - <256: scale down + * - >256: scale up + * - 128: half size + * - 512: double size */ void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom); @@ -318,7 +283,7 @@ bool lv_image_get_antialias(lv_obj_t * obj); /** * Get the size mode of the image * @param obj pointer to an image object - * @return element of @ref lv_image_align_t + * @return element of `lv_image_align_t` */ lv_image_align_t lv_image_get_inner_align(lv_obj_t * obj); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image_private.h new file mode 100644 index 000000000..e880f5d68 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image_private.h @@ -0,0 +1,66 @@ +/** + * @file lv_image_private.h + * + */ + +#ifndef LV_IMAGE_PRIVATE_H +#define LV_IMAGE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_image.h" + +#if LV_USE_IMAGE != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * Data of image + */ +struct lv_image_t { + lv_obj_t obj; + const void * src; /**< Image source: Pointer to an array or a file or a symbol*/ + const lv_image_dsc_t * bitmap_mask_src; /**< Pointer to an A8 bitmap mask */ + lv_point_t offset; + int32_t w; /**< Width of the image (Handled by the library)*/ + int32_t h; /**< Height of the image (Handled by the library)*/ + uint32_t rotation; /**< Rotation angle of the image*/ + uint32_t scale_x; /**< 256 means no zoom, 512 double size, 128 half size*/ + uint32_t scale_y; /**< 256 means no zoom, 512 double size, 128 half size*/ + lv_point_t pivot; /**< Rotation center of the image*/ + uint32_t src_type : 2; /**< See: lv_image_src_t*/ + uint32_t cf : 5; /**< Color format from `lv_color_format_t`*/ + uint32_t antialias : 1; /**< Apply anti-aliasing in transformations (rotate, zoom)*/ + uint32_t align: 4; /**< Image size mode when image size and object size is different. See lv_image_align_t*/ + uint32_t blend_mode: 4; /**< Element of `lv_blend_mode_t`*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_IMAGE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.c b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.c index dcecf9534..3aef3a42b 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.c @@ -6,8 +6,13 @@ /********************* * INCLUDES *********************/ +#include "lv_imagebutton_private.h" +#include "../../misc/lv_area_private.h" +#include "../../draw/lv_draw_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_event_private.h" +#include "../../core/lv_obj_class_private.h" -#include "lv_imagebutton.h" #if LV_USE_IMAGEBUTTON != 0 @@ -231,7 +236,7 @@ static void draw_main(lv_event_t * e) coords_part.y2 = coords.y2; lv_area_t clip_area_center; - if(_lv_area_intersect(&clip_area_center, &coords_part, &layer->_clip_area)) { + if(lv_area_intersect(&clip_area_center, &coords_part, &layer->_clip_area)) { lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area_center; img_dsc.src = src_info->img_src; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.h b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.h index 1f91eb682..ed6dc3a5e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.h @@ -27,25 +27,12 @@ typedef enum { LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, LV_IMAGEBUTTON_STATE_CHECKED_PRESSED, LV_IMAGEBUTTON_STATE_CHECKED_DISABLED, - _LV_IMAGEBUTTON_STATE_NUM, + LV_IMAGEBUTTON_STATE_NUM, } lv_imagebutton_state_t; -typedef struct { - const void * img_src; - lv_image_header_t header; -} lv_imagebutton_src_info_t; - /********************** * TYPEDEFS **********************/ -/*Data of image button*/ -typedef struct { - lv_obj_t obj; - lv_imagebutton_src_info_t src_mid[_LV_IMAGEBUTTON_STATE_NUM]; /*Store center images to each state*/ - lv_imagebutton_src_info_t src_left[_LV_IMAGEBUTTON_STATE_NUM]; /*Store left side images to each state*/ - lv_imagebutton_src_info_t src_right[_LV_IMAGEBUTTON_STATE_NUM]; /*Store right side images to each state*/ -} lv_imagebutton_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_imagebutton_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton_private.h new file mode 100644 index 000000000..bf9c4ef24 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton_private.h @@ -0,0 +1,58 @@ +/** + * @file lv_imagebutton_private.h + * + */ + +#ifndef LV_IMAGEBUTTON_PRIVATE_H +#define LV_IMAGEBUTTON_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_imagebutton.h" + +#if LV_USE_IMAGEBUTTON != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_imagebutton_src_info_t { + const void * img_src; + lv_image_header_t header; +}; + +/** Data of image button */ +struct lv_imagebutton_t { + lv_obj_t obj; + lv_imagebutton_src_info_t src_mid[LV_IMAGEBUTTON_STATE_NUM]; /**< Store center images to each state */ + lv_imagebutton_src_info_t src_left[LV_IMAGEBUTTON_STATE_NUM]; /**< Store left side images to each state */ + lv_imagebutton_src_info_t src_right[LV_IMAGEBUTTON_STATE_NUM]; /**< Store right side images to each state */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_IMAGEBUTTON != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_IMAGEBUTTON_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c index abc431c2c..050a62a7c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c @@ -7,15 +7,14 @@ /********************* * INCLUDES *********************/ -#include "lv_keyboard.h" +#include "lv_keyboard_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_KEYBOARD #include "../textarea/lv_textarea.h" #include "../../misc/lv_assert.h" #include "../../stdlib/lv_string.h" -#include - /********************* * DEFINES *********************/ @@ -38,6 +37,30 @@ static void lv_keyboard_update_ctrl_map(lv_obj_t * obj); /********************** * STATIC VARIABLES **********************/ +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_KEYBOARD_TEXTAREA, + .setter = lv_keyboard_set_textarea, + .getter = lv_keyboard_get_textarea, + }, + { + .id = LV_PROPERTY_KEYBOARD_MODE, + .setter = lv_keyboard_set_mode, + .getter = lv_keyboard_get_mode, + }, + { + .id = LV_PROPERTY_KEYBOARD_POPOVERS, + .setter = lv_keyboard_set_popovers, + .getter = lv_keyboard_get_popovers, + }, + { + .id = LV_PROPERTY_KEYBOARD_SELECTED_BUTTON, + .setter = lv_buttonmatrix_set_selected_button, + .getter = lv_keyboard_get_selected_button, + }, +}; +#endif const lv_obj_class_t lv_keyboard_class = { .constructor_cb = lv_keyboard_constructor, @@ -47,6 +70,18 @@ const lv_obj_class_t lv_keyboard_class = { .editable = 1, .base_class = &lv_buttonmatrix_class, .name = "keyboard", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_KEYBOARD_START, + .prop_index_end = LV_PROPERTY_KEYBOARD_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_keyboard_property_names, + .names_count = sizeof(lv_keyboard_property_names) / sizeof(lv_property_name_t), +#endif + +#endif }; static const char * const default_kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n", @@ -208,7 +243,7 @@ void lv_keyboard_set_textarea(lv_obj_t * obj, lv_obj_t * ta) /*Show the cursor of the new Text area if cursor management is enabled*/ if(keyboard->ta) { - lv_obj_add_flag(obj, LV_STATE_FOCUSED); + lv_obj_add_state(obj, LV_STATE_FOCUSED); } } @@ -261,7 +296,7 @@ lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * obj) return keyboard->mode; } -bool lv_buttonmatrix_get_popovers(const lv_obj_t * obj) +bool lv_keyboard_get_popovers(const lv_obj_t * obj) { lv_keyboard_t * keyboard = (lv_keyboard_t *)obj; return keyboard->popovers; @@ -375,6 +410,21 @@ void lv_keyboard_def_event_cb(lv_event_t * e) } } +const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) +{ + return lv_buttonmatrix_get_map(kb); +} + +uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) +{ + return lv_buttonmatrix_get_selected_button(obj); +} + +const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id) +{ + return lv_buttonmatrix_get_button_text(obj, btn_id); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h index c2c84ba82..b315e97cc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.h @@ -23,7 +23,7 @@ extern "C" { #endif #if LV_USE_TEXTAREA == 0 -#error "lv_textare is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) " +#error "lv_textarea is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) " #endif /********************* @@ -36,7 +36,7 @@ extern "C" { **********************/ /** Current keyboard mode.*/ -enum _lv_keyboard_mode_t { +typedef enum { LV_KEYBOARD_MODE_TEXT_LOWER, LV_KEYBOARD_MODE_TEXT_UPPER, LV_KEYBOARD_MODE_SPECIAL, @@ -48,21 +48,17 @@ enum _lv_keyboard_mode_t { #if LV_USE_ARABIC_PERSIAN_CHARS == 1 LV_KEYBOARD_MODE_TEXT_ARABIC #endif +} lv_keyboard_mode_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(KEYBOARD, TEXTAREA, LV_PROPERTY_TYPE_OBJ, 0), + LV_PROPERTY_ID(KEYBOARD, MODE, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(KEYBOARD, POPOVERS, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(KEYBOARD, SELECTED_BUTTON, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_KEYBOARD_END, }; - -#ifdef DOXYGEN -typedef _lv_keyboard_mode_t lv_keyboard_mode_t; -#else -typedef uint8_t lv_keyboard_mode_t; -#endif /*DOXYGEN*/ - -/*Data of keyboard*/ -typedef struct { - lv_buttonmatrix_t btnm; - lv_obj_t * ta; /*Pointer to the assigned text area*/ - lv_keyboard_mode_t mode; /*Key map type*/ - uint8_t popovers : 1; /*Show button titles in popovers on press*/ -} lv_keyboard_t; +#endif LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_keyboard_class; @@ -137,17 +133,14 @@ lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb); * @param obj pointer to a Keyboard object * @return true: "popovers" mode is enabled; false: disabled */ -bool lv_buttonmatrix_get_popovers(const lv_obj_t * obj); +bool lv_keyboard_get_popovers(const lv_obj_t * obj); /** * Get the current map of a keyboard * @param kb pointer to a keyboard object * @return the current map */ -static inline const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) -{ - return lv_buttonmatrix_get_map(kb); -} +const char ** lv_keyboard_get_map_array(const lv_obj_t * kb); /** * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) @@ -155,10 +148,7 @@ static inline const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) * @param obj pointer to button matrix object * @return index of the last released button (LV_BUTTONMATRIX_BUTTON_NONE: if unset) */ -static inline uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) -{ - return lv_buttonmatrix_get_selected_button(obj); -} +uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj); /** * Get the button's text @@ -166,10 +156,7 @@ static inline uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) * @param btn_id the index a button not counting new line characters. * @return text of btn_index` button */ -static inline const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id) -{ - return lv_buttonmatrix_get_button_text(obj, btn_id); -} +const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id); /*===================== * Other functions diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard_private.h new file mode 100644 index 000000000..757b23e9e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard_private.h @@ -0,0 +1,53 @@ +/** + * @file lv_keyboard_private.h + * + */ + +#ifndef LV_KEYBOARD_PRIVATE_H +#define LV_KEYBOARD_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../buttonmatrix/lv_buttonmatrix_private.h" +#include "lv_keyboard.h" + +#if LV_USE_KEYBOARD + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of keyboard */ +struct lv_keyboard_t { + lv_buttonmatrix_t btnm; + lv_obj_t * ta; /**< Pointer to the assigned text area */ + lv_keyboard_mode_t mode; /**< Key map type */ + uint8_t popovers : 1; /**< Show button titles in popovers on press */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_KEYBOARD */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_KEYBOARD_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.c b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.c index 09fc5b68d..ae0711251 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.c @@ -6,17 +6,22 @@ /********************* * INCLUDES *********************/ -#include "lv_label.h" +#include "lv_label_private.h" +#include "../../misc/lv_area_private.h" +#include "../../misc/lv_anim_private.h" +#include "../../draw/lv_draw_label_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_LABEL != 0 -#include "../../core/lv_obj.h" +#include "../../core/lv_obj_private.h" #include "../../misc/lv_assert.h" #include "../../core/lv_group.h" #include "../../display/lv_display.h" -#include "../../draw/lv_draw.h" +#include "../../draw/lv_draw_private.h" #include "../../misc/lv_color.h" #include "../../misc/lv_math.h" -#include "../../misc/lv_bidi.h" +#include "../../misc/lv_bidi_private.h" #include "../../misc/lv_text_ap.h" +#include "../../misc/lv_text_private.h" #include "../../stdlib/lv_sprintf.h" #include "../../stdlib/lv_string.h" @@ -59,6 +64,31 @@ static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, con /********************** * STATIC VARIABLES **********************/ +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_LABEL_TEXT, + .setter = lv_label_set_text, + .getter = lv_label_get_text, + }, + { + .id = LV_PROPERTY_LABEL_LONG_MODE, + .setter = lv_label_set_long_mode, + .getter = lv_label_get_long_mode, + }, + { + .id = LV_PROPERTY_LABEL_TEXT_SELECTION_START, + .setter = lv_label_set_text_selection_start, + .getter = lv_label_get_text_selection_start, + }, + { + .id = LV_PROPERTY_LABEL_TEXT_SELECTION_END, + .setter = lv_label_set_text_selection_end, + .getter = lv_label_get_text_selection_end, + }, +}; +#endif + const lv_obj_class_t lv_label_class = { .constructor_cb = lv_label_constructor, .destructor_cb = lv_label_destructor, @@ -68,6 +98,18 @@ const lv_obj_class_t lv_label_class = { .instance_size = sizeof(lv_label_t), .base_class = &lv_obj_class, .name = "label", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_LABEL_START, + .prop_index_end = LV_PROPERTY_LABEL_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_label_property_names, + .names_count = sizeof(lv_label_property_names) / sizeof(lv_property_name_t), +#endif + +#endif }; /********************** @@ -109,7 +151,7 @@ void lv_label_set_text(lv_obj_t * obj, const char * text) if(label->text == NULL) return; #if LV_USE_ARABIC_PERSIAN_CHARS - _lv_text_ap_proc(label->text, label->text); + lv_text_ap_proc(label->text, label->text); #endif } @@ -154,7 +196,7 @@ void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) va_list args; va_start(args, fmt); - label->text = _lv_text_set_text_vfmt(fmt, args); + label->text = lv_text_set_text_vfmt(fmt, args); va_end(args); label->static_txt = 0; /*Now the text is dynamically allocated*/ @@ -279,7 +321,7 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t lv_text_flag_t flag = get_label_flags(label); - const uint32_t byte_id = _lv_text_encoded_get_byte_id(txt, char_id); + const uint32_t byte_id = lv_text_encoded_get_byte_id(txt, char_id); /*Search the line of the index letter*/ const int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); @@ -290,12 +332,16 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t lv_area_t txt_coords; lv_obj_get_content_coords(obj, &txt_coords); const int32_t max_w = lv_area_get_width(&txt_coords); + const int32_t max_h = lv_area_get_height(&txt_coords); int32_t y = 0; uint32_t line_start = 0; uint32_t new_line_start = 0; while(txt[new_line_start] != '\0') { - new_line_start += _lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); + bool last_line = y + letter_height + line_space + letter_height > max_h; + if(last_line && label->long_mode == LV_LABEL_LONG_DOT) flag |= LV_TEXT_FLAG_BREAK_ALL; + + new_line_start += lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); if(byte_id < new_line_start || txt[new_line_start] == '\0') break; /*The line of 'index' letter begins at 'line_start'*/ @@ -315,7 +361,7 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t uint32_t visual_byte_pos; #if LV_USE_BIDI lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); - if(base_dir == LV_BASE_DIR_AUTO) base_dir = _lv_bidi_detect_base_dir(txt); + if(base_dir == LV_BASE_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(txt); char * mutable_bidi_txt = NULL; /*Handle Bidi*/ @@ -324,15 +370,15 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t bidi_txt = &txt[line_start]; } else { - uint32_t line_char_id = _lv_text_encoded_get_char_id(&txt[line_start], byte_id - line_start); + uint32_t line_char_id = lv_text_encoded_get_char_id(&txt[line_start], byte_id - line_start); bool is_rtl; - uint32_t visual_char_pos = _lv_bidi_get_visual_pos(&txt[line_start], &mutable_bidi_txt, new_line_start - line_start, - base_dir, line_char_id, &is_rtl); + uint32_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &mutable_bidi_txt, new_line_start - line_start, + base_dir, line_char_id, &is_rtl); bidi_txt = mutable_bidi_txt; if(is_rtl) visual_char_pos++; - visual_byte_pos = _lv_text_encoded_get_byte_id(bidi_txt, visual_char_pos); + visual_byte_pos = lv_text_encoded_get_byte_id(bidi_txt, visual_char_pos); } #else bidi_txt = &txt[line_start]; @@ -369,7 +415,8 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool const char * txt = lv_label_get_text(obj); uint32_t line_start = 0; uint32_t new_line_start = 0; - int32_t max_w = lv_area_get_width(&txt_coords); + int32_t max_w = lv_area_get_width(&txt_coords); + int32_t max_h = lv_area_get_height(&txt_coords); const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); const int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); @@ -380,14 +427,19 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool /*Search the line of the index letter*/; while(txt[line_start] != '\0') { - new_line_start += _lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); + /*If dots will be shown, break the last visible line anywhere, + *not only at word boundaries.*/ + bool last_line = y + letter_height + line_space + letter_height > max_h; + if(last_line && label->long_mode == LV_LABEL_LONG_DOT) flag |= LV_TEXT_FLAG_BREAK_ALL; + + new_line_start += lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); if(pos.y <= y + letter_height) { /*The line is found (stored in 'line_start')*/ /*Include the NULL terminator in the last line*/ uint32_t tmp = new_line_start; uint32_t letter; - letter = _lv_text_encoded_prev(txt, &tmp); + letter = lv_text_encoded_prev(txt, &tmp); if(letter != '\n' && txt[new_line_start] == '\0') new_line_start++; break; } @@ -399,12 +451,12 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool char * bidi_txt; #if LV_USE_BIDI - uint32_t txt_len; + uint32_t txt_len = 0; if(bidi) { bidi_txt = lv_malloc(new_line_start - line_start + 1); txt_len = new_line_start - line_start; if(new_line_start > 0 && txt[new_line_start - 1] == '\0' && txt_len > 0) txt_len--; - _lv_bidi_process_paragraph(txt + line_start, bidi_txt, txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), NULL, 0); + lv_bidi_process_paragraph(txt + line_start, bidi_txt, txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), NULL, 0); } else #endif @@ -427,7 +479,7 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool /*Be careful 'i' already points to the next character*/ uint32_t letter; uint32_t letter_next; - _lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); + lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); int32_t gw = lv_font_get_glyph_width(font, letter, letter_next); @@ -446,14 +498,14 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool #if LV_USE_BIDI if(bidi) { /*Handle Bidi*/ - uint32_t cid = _lv_text_encoded_get_char_id(bidi_txt, i); + uint32_t cid = lv_text_encoded_get_char_id(bidi_txt, i); if(txt[line_start + i] == '\0') { logical_pos = i; } else { bool is_rtl; - logical_pos = _lv_bidi_get_logical_pos(&txt[line_start], NULL, - txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), cid, &is_rtl); + logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, + txt_len, lv_obj_get_style_base_dir(obj, LV_PART_MAIN), cid, &is_rtl); if(is_rtl) logical_pos++; } lv_free(bidi_txt); @@ -461,10 +513,10 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool else #endif { - logical_pos = _lv_text_encoded_get_char_id(bidi_txt, i); + logical_pos = lv_text_encoded_get_char_id(bidi_txt, i); } - return logical_pos + _lv_text_encoded_get_char_id(txt, line_start); + return logical_pos + lv_text_encoded_get_char_id(txt, line_start); } bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) @@ -478,7 +530,8 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) lv_label_t * label = (lv_label_t *)obj; uint32_t line_start = 0; uint32_t new_line_start = 0; - const int32_t max_w = lv_area_get_width(&txt_coords); + const int32_t max_w = lv_area_get_width(&txt_coords); + const int32_t max_h = lv_area_get_height(&txt_coords); const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); const int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); @@ -489,7 +542,10 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) /*Search the line of the index letter*/ int32_t y = 0; while(txt[line_start] != '\0') { - new_line_start += _lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); + bool last_line = y + letter_height + line_space + letter_height > max_h; + if(last_line && label->long_mode == LV_LABEL_LONG_DOT) flag |= LV_TEXT_FLAG_BREAK_ALL; + + new_line_start += lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/ y += letter_height + line_space; @@ -520,7 +576,7 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) while(i <= new_line_start - 1) { /*Get the current letter and the next letter for kerning*/ /*Be careful 'i' already points to the next character*/ - _lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); + lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); last_x = x; x += lv_font_get_glyph_width(font, letter, letter_next); @@ -574,7 +630,7 @@ void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt) lv_label_t * label = (lv_label_t *)obj; - /*Can not append to static text*/ + /*Cannot append to static text*/ if(label->static_txt != 0) return; lv_obj_invalidate(obj); @@ -588,10 +644,10 @@ void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt) if(label->text == NULL) return; if(pos == LV_LABEL_POS_LAST) { - pos = _lv_text_get_encoded_length(label->text); + pos = lv_text_get_encoded_length(label->text); } - _lv_text_ins(label->text, pos, txt); + lv_text_ins(label->text, pos, txt); lv_label_set_text(obj, NULL); } @@ -600,14 +656,14 @@ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt) LV_ASSERT_OBJ(obj, MY_CLASS); lv_label_t * label = (lv_label_t *)obj; - /*Can not append to static text*/ + /*Cannot append to static text*/ if(label->static_txt) return; lv_obj_invalidate(obj); char * label_txt = lv_label_get_text(obj); /*Delete the characters*/ - _lv_text_cut(label_txt, pos, cnt); + lv_text_cut(label_txt, pos, cnt); /*Refresh the label*/ lv_label_refr_text(obj); @@ -759,7 +815,7 @@ static void draw_main(lv_event_t * e) } lv_area_t txt_clip; - bool is_common = _lv_area_intersect(&txt_clip, &txt_coords, &layer->_clip_area); + bool is_common = lv_area_intersect(&txt_clip, &txt_coords, &layer->_clip_area); if(!is_common) { return; } @@ -882,7 +938,7 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); if(base_dir == LV_BASE_DIR_AUTO) - base_dir = _lv_bidi_detect_base_dir(label->text); + base_dir = lv_bidi_detect_base_dir(label->text); if(base_dir == LV_BASE_DIR_RTL) { start = lv_area_get_width(&txt_coords) - size.x; @@ -989,7 +1045,7 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); if(base_dir == LV_BASE_DIR_AUTO) - base_dir = _lv_bidi_detect_base_dir(label->text); + base_dir = lv_bidi_detect_base_dir(label->text); if(base_dir == LV_BASE_DIR_RTL) { start = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT; @@ -1060,7 +1116,7 @@ static void lv_label_refr_text(lv_obj_t * obj) else if(size.y <= lv_font_get_line_height(font)) { /*No dots are required for one-line texts*/ label->dot_end = LV_LABEL_DOT_END_INV; } - else if(_lv_text_get_encoded_length(label->text) <= LV_LABEL_DOT_NUM) { /*Don't turn to dots all the characters*/ + else if(lv_text_get_encoded_length(label->text) <= LV_LABEL_DOT_NUM) { /*Don't turn to dots all the characters*/ label->dot_end = LV_LABEL_DOT_END_INV; } else { @@ -1085,9 +1141,9 @@ static void lv_label_refr_text(lv_obj_t * obj) /*Be sure there is space for the dots*/ size_t txt_len = lv_strlen(label->text); - uint32_t byte_id = _lv_text_encoded_get_byte_id(label->text, letter_id); + uint32_t byte_id = lv_text_encoded_get_byte_id(label->text, letter_id); while(byte_id + LV_LABEL_DOT_NUM > txt_len) { - _lv_text_encoded_prev(label->text, &byte_id); + lv_text_encoded_prev(label->text, &byte_id); letter_id--; } @@ -1096,8 +1152,8 @@ static void lv_label_refr_text(lv_obj_t * obj) uint32_t i; uint8_t len = 0; for(i = 0; i <= LV_LABEL_DOT_NUM; i++) { - len += _lv_text_encoded_size(&label->text[byte_id]); - _lv_text_encoded_next(label->text, &byte_id); + len += lv_text_encoded_size(&label->text[byte_id]); + lv_text_encoded_next(label->text, &byte_id); if(len > LV_LABEL_DOT_NUM || byte_id > txt_len) { break; } @@ -1127,7 +1183,7 @@ static void lv_label_revert_dots(lv_obj_t * obj) if(label->dot_end == LV_LABEL_DOT_END_INV) return; const uint32_t letter_i = label->dot_end - LV_LABEL_DOT_NUM; - const uint32_t byte_i = _lv_text_encoded_get_byte_id(label->text, letter_i); + const uint32_t byte_i = lv_text_encoded_get_byte_id(label->text, letter_i); /*Restore the characters*/ uint8_t i = 0; @@ -1224,7 +1280,7 @@ static size_t get_text_length(const char * text) { size_t len = 0; #if LV_USE_ARABIC_PERSIAN_CHARS - len = _lv_text_ap_calc_bytes_count(text); + len = lv_text_ap_calc_bytes_count(text); #else len = lv_strlen(text) + 1; #endif @@ -1235,7 +1291,7 @@ static size_t get_text_length(const char * text) static void copy_text_to_label(lv_label_t * label, const char * text) { #if LV_USE_ARABIC_PERSIAN_CHARS - _lv_text_ap_proc(text, label->text); + lv_text_ap_proc(text, label->text); #else lv_strcpy(label->text, text); #endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.h b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.h index 7a6ea3d85..86964f33f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.h @@ -17,7 +17,7 @@ extern "C" { #if LV_USE_LABEL != 0 -#include +#include "../../misc/lv_types.h" #include "../../core/lv_obj.h" #include "../../font/lv_font.h" #include "../../font/lv_symbol_def.h" @@ -45,47 +45,24 @@ LV_EXPORT_CONST_INT(LV_LABEL_TEXT_SELECTION_OFF); **********************/ /** Long mode behaviors. Used in 'lv_label_ext_t'*/ -enum _lv_label_long_mode_t { +typedef enum { LV_LABEL_LONG_WRAP, /**< Keep the object width, wrap lines longer than object width and expand the object height*/ LV_LABEL_LONG_DOT, /**< Keep the size and write dots at the end if the text is too long*/ LV_LABEL_LONG_SCROLL, /**< Keep the size and roll the text back and forth*/ LV_LABEL_LONG_SCROLL_CIRCULAR, /**< Keep the size and roll the text circularly*/ LV_LABEL_LONG_CLIP, /**< Keep the size and clip the text out of it*/ +} lv_label_long_mode_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(LABEL, TEXT, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(LABEL, LONG_MODE, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(LABEL, TEXT_SELECTION_START, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(LABEL, TEXT_SELECTION_END, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_LABEL_END, }; - -#ifdef DOXYGEN -typedef _lv_label_long_mode_t lv_label_long_mode_t; -#else -typedef uint8_t lv_label_long_mode_t; -#endif /*DOXYGEN*/ - -typedef struct { - lv_obj_t obj; - char * text; - union { - char * tmp_ptr; /*Pointer to the allocated memory containing the character replaced by dots*/ - char tmp[LV_LABEL_DOT_NUM + 1]; /*Directly store the characters if <=4 characters*/ - } dot; - uint32_t dot_end; /*The real text length, used in dot mode*/ - -#if LV_LABEL_LONG_TXT_HINT - lv_draw_label_hint_t hint; #endif -#if LV_LABEL_TEXT_SELECTION - uint32_t sel_start; - uint32_t sel_end; -#endif - - lv_point_t size_cache; /*Text size cache*/ - lv_point_t offset; /*Text draw position offset*/ - lv_label_long_mode_t long_mode : 3; /*Determine what to do with the long texts*/ - uint8_t static_txt : 1; /*Flag to indicate the text is static*/ - uint8_t expand : 1; /*Ignore real width (used by the library with LV_LABEL_LONG_SCROLL)*/ - uint8_t dot_tmp_alloc : 1; /*1: dot is allocated, 0: dot directly holds up to 4 chars*/ - uint8_t invalid_size_cache : 1; /*1: Recalculate size and update cache*/ -} lv_label_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_label_class; /********************** @@ -114,7 +91,11 @@ void lv_label_set_text(lv_obj_t * obj, const char * text); * Set a new formatted text for a label. Memory will be allocated to store the text by the label. * @param obj pointer to a label object * @param fmt `printf`-like format - * @example lv_label_set_text_fmt(label1, "%d user", user_num); + * + * Example: + * @code + * lv_label_set_text_fmt(label1, "%d user", user_num); + * @endcode */ void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3); @@ -212,7 +193,7 @@ uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj); *====================*/ /** - * Insert a text to a label. The label text can not be static. + * Insert a text to a label. The label text cannot be static. * @param obj pointer to a label object * @param pos character index to insert. Expressed in character index and not byte index. * 0: before first char. LV_LABEL_POS_LAST: after last char. @@ -221,10 +202,10 @@ uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj); void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt); /** - * Delete characters from a label. The label text can not be static. + * Delete characters from a label. The label text cannot be static. * @param obj pointer to a label object * @param pos character index from where to cut. Expressed in character index and not byte index. - * 0: start in from of the first character + * 0: start in front of the first character * @param cnt number of characters to cut */ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label_private.h new file mode 100644 index 000000000..81a2e68ec --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label_private.h @@ -0,0 +1,73 @@ +/** + * @file lv_label_private.h + * + */ + +#ifndef LV_LABEL_PRIVATE_H +#define LV_LABEL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../draw/lv_draw_label_private.h" +#include "../../core/lv_obj_private.h" +#include "lv_label.h" + +#if LV_USE_LABEL != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_label_t { + lv_obj_t obj; + char * text; + union { + char * tmp_ptr; /**< Pointer to the allocated memory containing the character replaced by dots */ + char tmp[LV_LABEL_DOT_NUM + 1]; /**< Directly store the characters if <=4 characters */ + } dot; + uint32_t dot_end; /**< The real text length, used in dot mode */ + +#if LV_LABEL_LONG_TXT_HINT + lv_draw_label_hint_t hint; +#endif + +#if LV_LABEL_TEXT_SELECTION + uint32_t sel_start; + uint32_t sel_end; +#endif + + lv_point_t size_cache; /**< Text size cache */ + lv_point_t offset; /**< Text draw position offset */ + lv_label_long_mode_t long_mode : 3; /**< Determine what to do with the long texts */ + uint8_t static_txt : 1; /**< Flag to indicate the text is static */ + uint8_t expand : 1; /**< Ignore real width (used by the library with LV_LABEL_LONG_SCROLL) */ + uint8_t dot_tmp_alloc : 1; /**< 1: dot is allocated, 0: dot directly holds up to 4 chars */ + uint8_t invalid_size_cache : 1; /**< 1: Recalculate size and update cache */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LABEL != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LABEL_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.c b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.c index bf5db77c5..6a8c29bbf 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.c @@ -6,7 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_led.h" +#include "lv_led_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" + #if LV_USE_LED #include "../../misc/lv_assert.h" diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.h b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.h index f1ac52d87..c085a97f6 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.h @@ -34,13 +34,6 @@ extern "C" { * TYPEDEFS **********************/ -/*Data of led*/ -typedef struct { - lv_obj_t obj; - lv_color_t color; - uint8_t bright; /**< Current brightness of the LED (0..255)*/ -} lv_led_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_led_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led_private.h new file mode 100644 index 000000000..af76b4fb9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_led_private.h + * + */ + +#ifndef LV_LED_PRIVATE_H +#define LV_LED_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_led.h" + +#if LV_USE_LED +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of led */ +struct lv_led_t { + lv_obj_t obj; + lv_color_t color; + uint8_t bright; /**< Current brightness of the LED (0..255)*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LED */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LED_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.c b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.c index 4734e1bbe..a251aae72 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.c @@ -6,15 +6,15 @@ /********************* * INCLUDES *********************/ -#include "lv_line.h" +#include "lv_line_private.h" +#include "../../core/lv_obj_class_private.h" + #if LV_USE_LINE != 0 #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" +#include "../../misc/lv_types.h" #include "../../draw/lv_draw.h" -#include -#include -#include /********************* * DEFINES @@ -29,6 +29,7 @@ * STATIC PROTOTYPES **********************/ static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num, bool mut); static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e); /********************** @@ -66,15 +67,12 @@ lv_obj_t * lv_line_create(lv_obj_t * parent) void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num) { - LV_ASSERT_OBJ(obj, MY_CLASS); + line_set_points(obj, points, point_num, false); +} - lv_line_t * line = (lv_line_t *)obj; - line->point_array = points; - line->point_num = point_num; - - lv_obj_refresh_self_size(obj); - - lv_obj_invalidate(obj); +void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num) +{ + line_set_points(obj, points, point_num, true); } void lv_line_set_y_invert(lv_obj_t * obj, bool en) @@ -93,6 +91,42 @@ void lv_line_set_y_invert(lv_obj_t * obj, bool en) * Getter functions *====================*/ +const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_line_t * line = (lv_line_t *)obj; + return line->point_array.constant; +} + +uint32_t lv_line_get_point_count(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_line_t * line = (lv_line_t *)obj; + return line->point_num; +} + +bool lv_line_is_point_array_mutable(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_line_t * line = (lv_line_t *)obj; + return line->point_array_is_mutable; +} + +lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_line_t * line = (lv_line_t *)obj; + if(!line->point_array_is_mutable) { + LV_LOG_WARN("the line point array is not mutable"); + return NULL; + } + return line->point_array.mut; +} + bool lv_line_get_y_invert(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -114,14 +148,29 @@ static void lv_line_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_line_t * line = (lv_line_t *)obj; line->point_num = 0; - line->point_array = NULL; + line->point_array.constant = NULL; line->y_inv = 0; + line->point_array_is_mutable = 0; lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE); LV_TRACE_OBJ_CREATE("finished"); } +static void line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num, bool mut) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_line_t * line = (lv_line_t *)obj; + line->point_array.constant = points; + line->point_num = point_num; + line->point_array_is_mutable = mut; + + lv_obj_refresh_self_size(obj); + + lv_obj_invalidate(obj); +} + static inline lv_value_precise_t resolve_point_coord(lv_value_precise_t coord, int32_t max) { if(LV_COORD_IS_PCT((int32_t)coord)) { @@ -154,7 +203,7 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e) else if(code == LV_EVENT_GET_SELF_SIZE) { lv_line_t * line = (lv_line_t *)obj; - if(line->point_num == 0 || line->point_array == NULL) return; + if(line->point_num == 0 || line->point_array.constant == NULL) return; lv_point_t * p = lv_event_get_param(e); int32_t w = 0; @@ -162,12 +211,12 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e) uint32_t i; for(i = 0; i < line->point_num; i++) { - if(!LV_COORD_IS_PCT((int32_t)line->point_array[i].x)) { - w = (int32_t)LV_MAX(line->point_array[i].x, w); + if(!LV_COORD_IS_PCT((int32_t)line->point_array.constant[i].x)) { + w = (int32_t)LV_MAX(line->point_array.constant[i].x, w); } - if(!LV_COORD_IS_PCT((int32_t)line->point_array[i].y)) { - h = (int32_t)LV_MAX(line->point_array[i].y, h); + if(!LV_COORD_IS_PCT((int32_t)line->point_array.constant[i].y)) { + h = (int32_t)LV_MAX(line->point_array.constant[i].y, h); } } @@ -178,7 +227,7 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_line_t * line = (lv_line_t *)obj; lv_layer_t * layer = lv_event_get_layer(e); - if(line->point_num == 0 || line->point_array == NULL) return; + if(line->point_num == 0 || line->point_array.constant == NULL) return; lv_area_t area; lv_obj_get_coords(obj, &area); @@ -195,11 +244,11 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e) int32_t w = lv_obj_get_width(obj); int32_t h = lv_obj_get_height(obj); - line_dsc.p1.x = resolve_point_coord(line->point_array[i].x, w) + x_ofs; - line_dsc.p1.y = resolve_point_coord(line->point_array[i].y, h); + line_dsc.p1.x = resolve_point_coord(line->point_array.constant[i].x, w) + x_ofs; + line_dsc.p1.y = resolve_point_coord(line->point_array.constant[i].y, h); - line_dsc.p2.x = resolve_point_coord(line->point_array[i + 1].x, w) + x_ofs; - line_dsc.p2.y = resolve_point_coord(line->point_array[i + 1].y, h); + line_dsc.p2.x = resolve_point_coord(line->point_array.constant[i + 1].x, w) + x_ofs; + line_dsc.p2.y = resolve_point_coord(line->point_array.constant[i + 1].y, h); if(line->y_inv == 0) { line_dsc.p1.y = line_dsc.p1.y + y_ofs; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.h b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.h index 6a2423a22..d6a1d603e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.h @@ -24,14 +24,6 @@ extern "C" { * TYPEDEFS **********************/ -/*Data of line*/ -typedef struct { - lv_obj_t obj; - const lv_point_precise_t * point_array; /**< Pointer to an array with the points of the line*/ - uint32_t point_num; /**< Number of points in 'point_array'*/ - uint32_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/ -} lv_line_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_line_class; /********************** @@ -57,6 +49,14 @@ lv_obj_t * lv_line_create(lv_obj_t * parent); */ void lv_line_set_points(lv_obj_t * obj, const lv_point_precise_t points[], uint32_t point_num); +/** + * Set a non-const array of points. Identical to `lv_line_set_points` except the array may be retrieved by `lv_line_get_points_mutable`. + * @param obj pointer to a line object + * @param points a non-const array of points. Only the address is saved, so the array needs to be alive while the line exists. + * @param point_num number of points in 'point_a' + */ +void lv_line_set_points_mutable(lv_obj_t * obj, lv_point_precise_t points[], uint32_t point_num); + /** * Enable (or disable) the y coordinate inversion. * If enabled then y will be subtracted from the height of the object, @@ -70,6 +70,34 @@ void lv_line_set_y_invert(lv_obj_t * obj, bool en); * Getter functions *====================*/ +/** + * Get the pointer to the array of points. + * @param obj pointer to a line object + * @return const pointer to the array of points + */ +const lv_point_precise_t * lv_line_get_points(lv_obj_t * obj); + +/** + * Get the number of points in the array of points. + * @param obj pointer to a line object + * @return number of points in array of points + */ +uint32_t lv_line_get_point_count(lv_obj_t * obj); + +/** + * Check the mutability of the stored point array pointer. + * @param obj pointer to a line object + * @return true: the point array pointer is mutable, false: constant + */ +bool lv_line_is_point_array_mutable(lv_obj_t * obj); + +/** + * Get a pointer to the mutable array of points or NULL if it is not mutable + * @param obj pointer to a line object + * @return pointer to the array of points. NULL if not mutable. + */ +lv_point_precise_t * lv_line_get_points_mutable(lv_obj_t * obj); + /** * Get the y inversion attribute * @param obj pointer to a line object diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line_private.h new file mode 100644 index 000000000..4cbce9c8e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_line_private.h + * + */ + +#ifndef LV_LINE_PRIVATE_H +#define LV_LINE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_line.h" + +#if LV_USE_LINE != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of line */ +struct lv_line_t { + lv_obj_t obj; + union { + const lv_point_precise_t * constant; + lv_point_precise_t * mut; + } point_array; /**< Pointer to an array with the points of the line*/ + uint32_t point_num; /**< Number of points in 'point_array'*/ + uint32_t y_inv : 1; /**< 1: y == 0 will be on the bottom*/ + uint32_t point_array_is_mutable : 1; /**< whether the point array is const or mutable*/ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LINE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LINE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.c b/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.c index 5288c66e0..3556ef1dc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.c @@ -6,6 +6,7 @@ /********************* * INCLUDES *********************/ +#include "../../core/lv_obj_class_private.h" #include "lv_list.h" #include "../../layouts/flex/lv_flex.h" #include "../../display/lv_display.h" diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.h b/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.h index c01c086df..0c3894d04 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.h @@ -1,5 +1,5 @@ /** - * @file lv_win.h + * @file lv_list.h * */ @@ -69,7 +69,6 @@ const char * lv_list_get_button_text(lv_obj_t * list, lv_obj_t * btn); * @param list pointer to a list * @param btn pointer to the button * @param txt pointer to the text - * @return text of btn, if btn doesn't have text "" will be returned */ void lv_list_set_button_text(lv_obj_t * list, lv_obj_t * btn, const char * txt); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c new file mode 100644 index 000000000..48ae25814 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c @@ -0,0 +1,237 @@ +/** + * @file lv_lottie.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_lottie_private.h" +#include "../../lv_conf_internal.h" +#if LV_USE_LOTTIE + +#if LV_USE_THORVG_EXTERNAL + #include +#else + #include "../../libs/thorvg/thorvg_capi.h" +#endif + +#include "../../misc/lv_timer.h" +#include "../../core/lv_obj_class_private.h" + +/********************* + * DEFINES + *********************/ +#define MY_CLASS (&lv_lottie_class) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_lottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_lottie_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void anim_exec_cb(void * var, int32_t v); +static void lottie_update(lv_lottie_t * lottie, int32_t v); + +/********************** + * STATIC VARIABLES + **********************/ +const lv_obj_class_t lv_lottie_class = { + .constructor_cb = lv_lottie_constructor, + .destructor_cb = lv_lottie_destructor, + .width_def = LV_DPI_DEF, + .height_def = LV_DPI_DEF, + .instance_size = sizeof(lv_lottie_t), + .base_class = &lv_canvas_class, + .name = "lottie", +}; + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_lottie_create(lv_obj_t * parent) +{ + LV_LOG_INFO("begin"); + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + return obj; +} + +void lv_lottie_set_buffer(lv_obj_t * obj, int32_t w, int32_t h, void * buf) +{ + lv_lottie_t * lottie = (lv_lottie_t *)obj; + int32_t stride = lv_draw_buf_width_to_stride(w, LV_COLOR_FORMAT_ARGB8888); + buf = lv_draw_buf_align(buf, LV_COLOR_FORMAT_ARGB8888); + + tvg_swcanvas_set_target(lottie->tvg_canvas, buf, stride / 4, w, h, TVG_COLORSPACE_ARGB8888); + tvg_canvas_push(lottie->tvg_canvas, lottie->tvg_paint); + lv_canvas_set_buffer(obj, buf, w, h, LV_COLOR_FORMAT_ARGB8888); + tvg_picture_set_size(lottie->tvg_paint, w, h); + + /* Rendered output images are premultiplied */ + lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj); + lv_draw_buf_set_flag(draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED); + + /*Force updating when the buffer changes*/ + float f_current; + tvg_animation_get_frame(lottie->tvg_anim, &f_current); + anim_exec_cb(obj, (int32_t) f_current); +} + +void lv_lottie_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf) +{ + if(draw_buf->header.cf != LV_COLOR_FORMAT_ARGB8888) { + LV_LOG_WARN("The draw buf needs to have ARGB8888 color format"); + return; + } + + lv_lottie_t * lottie = (lv_lottie_t *)obj; + tvg_swcanvas_set_target(lottie->tvg_canvas, (void *)draw_buf->data, draw_buf->header.stride / 4, + draw_buf->header.w, draw_buf->header.h, TVG_COLORSPACE_ARGB8888); + tvg_canvas_push(lottie->tvg_canvas, lottie->tvg_paint); + lv_canvas_set_draw_buf(obj, draw_buf); + tvg_picture_set_size(lottie->tvg_paint, draw_buf->header.w, draw_buf->header.h); + + /* Rendered output images are premultiplied */ + lv_draw_buf_set_flag(draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED); + + /*Force updating when the buffer changes*/ + float f_current; + tvg_animation_get_frame(lottie->tvg_anim, &f_current); + anim_exec_cb(obj, (int32_t) f_current); +} + +void lv_lottie_set_src_data(lv_obj_t * obj, const void * src, size_t src_size) +{ + lv_lottie_t * lottie = (lv_lottie_t *)obj; + tvg_picture_load_data(lottie->tvg_paint, src, src_size, "lottie", true); + lv_draw_buf_t * canvas_draw_buf = lv_canvas_get_draw_buf(obj); + if(canvas_draw_buf) { + tvg_picture_set_size(lottie->tvg_paint, canvas_draw_buf->header.w, canvas_draw_buf->header.h); + } + + float f_total; + tvg_animation_get_total_frame(lottie->tvg_anim, &f_total); + lv_anim_set_time(lottie->anim, (int32_t)f_total * 1000 / 60); /*60 FPS*/ + lottie->anim->act_time = 0; + lottie->anim->end_value = (int32_t)f_total; + lottie->anim->playback_now = false; + lottie_update(lottie, 0); /*Render immediately*/ +} + +void lv_lottie_set_src_file(lv_obj_t * obj, const char * src) +{ + lv_lottie_t * lottie = (lv_lottie_t *)obj; + tvg_picture_load(lottie->tvg_paint, src); + lv_draw_buf_t * canvas_draw_buf = lv_canvas_get_draw_buf(obj); + if(canvas_draw_buf) { + tvg_picture_set_size(lottie->tvg_paint, canvas_draw_buf->header.w, canvas_draw_buf->header.h); + } + + float f_total; + tvg_animation_get_total_frame(lottie->tvg_anim, &f_total); + lv_anim_set_time(lottie->anim, (int32_t)f_total * 1000 / 60); /*60 FPS*/ + lottie->anim->act_time = 0; + lottie->anim->end_value = (int32_t)f_total; + lottie->anim->playback_now = false; + lottie_update(lottie, 0); /*Render immediately*/ +} + + +lv_anim_t * lv_lottie_get_anim(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_lottie_t * lottie = (lv_lottie_t *)obj; + return lottie->anim; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_lottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_TRACE_OBJ_CREATE("begin"); + + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + + lv_lottie_t * lottie = (lv_lottie_t *)obj; + lottie->tvg_anim = tvg_animation_new(); + + lottie->tvg_paint = tvg_animation_get_picture(lottie->tvg_anim); + + lottie->tvg_canvas = tvg_swcanvas_create(); + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_exec_cb(&a, anim_exec_cb); + lv_anim_set_var(&a, obj); + lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); + lottie->anim = lv_anim_start(&a); + + LV_TRACE_OBJ_CREATE("finished"); +} + +static void lv_lottie_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + lv_lottie_t * lottie = (lv_lottie_t *)obj; + + tvg_animation_del(lottie->tvg_anim); + tvg_canvas_destroy(lottie->tvg_canvas); +} + +static void anim_exec_cb(void * var, int32_t v) +{ + lv_lottie_t * lottie = var; + + /*Do not render not visible animations.*/ + if(lv_obj_is_visible(var)) { + lottie_update(lottie, v); + if(lottie->anim) { + lottie->last_rendered_time = lottie->anim->act_time; + } + } + else { + /*Artificially keep the animation on the last rendered frame's time + *To avoid a jump when the widget becomes visible*/ + if(lottie->anim) { + lottie->anim->act_time = lottie->last_rendered_time; + } + } +} + +static void lottie_update(lv_lottie_t * lottie, int32_t v) +{ + lv_obj_t * obj = (lv_obj_t *) lottie; + + lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj); + if(draw_buf) { + lv_draw_buf_clear(draw_buf, NULL); + + /*Drop old cached image*/ + lv_image_cache_drop(lv_image_get_src(obj)); + } + + tvg_animation_set_frame(lottie->tvg_anim, v); + tvg_canvas_update(lottie->tvg_canvas); + tvg_canvas_draw(lottie->tvg_canvas); + tvg_canvas_sync(lottie->tvg_canvas); + + lv_obj_invalidate(obj); +} + +#endif /*LV_USE_LOTTIE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.h b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.h new file mode 100644 index 000000000..1ccfe164a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.h @@ -0,0 +1,102 @@ +/** + * @file lv_lottie.h + * + */ + +#ifndef LV_LOTTIE_H +#define LV_LOTTIE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_LOTTIE + +/*Testing of dependencies*/ +#if LV_USE_CANVAS == 0 +#error "lv_lottie: lv_canvas is required. Enable it in lv_conf.h (LV_USE_CANVAS 1)" +#endif + +#if LV_USE_THORVG == 0 +#error "lv_lottie: ThorVG is required. Enable it in lv_conf.h (LV_USE_THORVG_INTERNAL/EXTERNAL 1)" +#endif + +#include "../../draw/lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a lottie animation + * @param parent pointer to the parent widget + * @return pointer to the created Lottie animation widget + */ +lv_obj_t * lv_lottie_create(lv_obj_t * parent); + +/** + * Set a buffer for the animation. It also defines the size of the animation + * @param obj pointer to a lottie widget + * @param w width of the animation and buffer + * @param h height of the animation and buffer + * @param buf a static buffer with `width x height x 4` byte size + */ +void lv_lottie_set_buffer(lv_obj_t * obj, int32_t w, int32_t h, void * buf); + +/** + * Set a draw buffer for the animation. It also defines the size of the animation + * @param obj pointer to a lottie widget + * @param draw_buf an initialized draw buffer with ARGB8888 color format + */ +void lv_lottie_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf); + +/** + * Set the source for the animation as an array + * @param obj pointer to a lottie widget + * @param src the lottie animation converted to an nul terminated array + * @param src_size size of the source array in bytes + */ +void lv_lottie_set_src_data(lv_obj_t * obj, const void * src, size_t src_size); + +/** + * Set the source for the animation as a path. + * Lottie doesn't use LVGL's File System API. + * @param obj pointer to a lottie widget + * @param src path to a json file, e.g. "path/to/file.json" + */ +void lv_lottie_set_src_file(lv_obj_t * obj, const char * src); + +/** + * Get the LVGL animation which controls the lottie animation + * @param obj pointer to a lottie widget + * @return the LVGL animation + */ +lv_anim_t * lv_lottie_get_anim(lv_obj_t * obj); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LOTTIE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LOTTIE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie_private.h new file mode 100644 index 000000000..6362afb89 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie_private.h @@ -0,0 +1,60 @@ +/** + * @file lv_lottie_private.h + * + */ + +#ifndef LV_LOTTIE_PRIVATE_H +#define LV_LOTTIE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_LOTTIE + +#include "lv_lottie.h" +#include "../canvas/lv_canvas_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_THORVG_EXTERNAL +#include +#else +#include "../../libs/thorvg/thorvg_capi.h" +#endif + +typedef struct { + lv_canvas_t canvas; + Tvg_Paint * tvg_paint; + Tvg_Canvas * tvg_canvas; + Tvg_Animation * tvg_anim; + lv_anim_t * anim; + int32_t last_rendered_time; +} lv_lottie_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_LOTTIE_H*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LOTTIE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.c b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.c index e21bdcd18..f9b49fc0e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_menu.h" +#include "lv_menu_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_MENU @@ -15,7 +16,7 @@ *********************/ #define MY_CLASS (&lv_menu_class) -#include "../../core/lv_obj.h" +#include "../../core/lv_obj_private.h" #include "../../layouts/lv_layout.h" #include "../../stdlib/lv_string.h" #include "../label/lv_label.h" @@ -170,14 +171,14 @@ void lv_menu_refr(lv_obj_t * obj) lv_ll_t * history_ll = &(menu->history_ll); /* The current menu */ - lv_menu_history_t * act_hist = _lv_ll_get_head(history_ll); + lv_menu_history_t * act_hist = lv_ll_get_head(history_ll); lv_obj_t * page = NULL; if(act_hist != NULL) { page = act_hist->page; /* Delete the current item from the history */ - _lv_ll_remove(history_ll, act_hist); + lv_ll_remove(history_ll, act_hist); lv_free(act_hist); menu->cur_depth--; } @@ -204,7 +205,7 @@ void lv_menu_set_page(lv_obj_t * obj, lv_obj_t * page) if(page != NULL) { /* Add a new node */ lv_ll_t * history_ll = &(menu->history_ll); - lv_menu_history_t * new_node = _lv_ll_ins_head(history_ll); + lv_menu_history_t * new_node = lv_ll_ins_head(history_ll); LV_ASSERT_MALLOC(new_node); new_node->page = page; menu->cur_depth++; @@ -506,7 +507,7 @@ void lv_menu_clear_history(lv_obj_t * obj) lv_menu_t * menu = (lv_menu_t *)obj; lv_ll_t * history_ll = &(menu->history_ll); - _lv_ll_clear(history_ll); + lv_ll_clear(history_ll); menu->cur_depth = 0; } @@ -531,7 +532,7 @@ static void lv_menu_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) menu->prev_depth = 0; menu->sidebar_generated = false; - _lv_ll_init(&(menu->history_ll), sizeof(lv_menu_history_t)); + lv_ll_init(&(menu->history_ll), sizeof(lv_menu_history_t)); menu->storage = lv_obj_create(obj); lv_obj_add_flag(menu->storage, LV_OBJ_FLAG_HIDDEN); @@ -590,7 +591,7 @@ static void lv_menu_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_menu_t * menu = (lv_menu_t *)obj; lv_ll_t * history_ll = &(menu->history_ll); - _lv_ll_clear(history_ll); + lv_ll_clear(history_ll); LV_TRACE_OBJ_CREATE("finished"); } @@ -770,20 +771,20 @@ static void lv_menu_back_event_cb(lv_event_t * e) lv_ll_t * history_ll = &(menu->history_ll); /* The current menu */ - lv_menu_history_t * act_hist = _lv_ll_get_head(history_ll); + lv_menu_history_t * act_hist = lv_ll_get_head(history_ll); /* The previous menu */ - lv_menu_history_t * prev_hist = _lv_ll_get_next(history_ll, act_hist); + lv_menu_history_t * prev_hist = lv_ll_get_next(history_ll, act_hist); if(prev_hist != NULL) { /* Previous menu exists */ /* Delete the current item from the history */ - _lv_ll_remove(history_ll, act_hist); + lv_ll_remove(history_ll, act_hist); lv_free(act_hist); menu->cur_depth--; /* Create the previous menu. * Remove it from the history because `lv_menu_set_page` will add it again */ - _lv_ll_remove(history_ll, prev_hist); + lv_ll_remove(history_ll, prev_hist); menu->cur_depth--; lv_menu_set_page(&(menu->obj), prev_hist->page); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.h b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.h index c187ff134..3d75f8d9a 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.h @@ -28,73 +28,16 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum _lv_menu_mode_header_t { - LV_MENU_HEADER_TOP_FIXED, /* Header is positioned at the top */ - LV_MENU_HEADER_TOP_UNFIXED, /* Header is positioned at the top and can be scrolled out of view*/ - LV_MENU_HEADER_BOTTOM_FIXED /* Header is positioned at the bottom */ -}; +typedef enum { + LV_MENU_HEADER_TOP_FIXED, /**< Header is positioned at the top */ + LV_MENU_HEADER_TOP_UNFIXED, /**< Header is positioned at the top and can be scrolled out of view*/ + LV_MENU_HEADER_BOTTOM_FIXED /**< Header is positioned at the bottom */ +} lv_menu_mode_header_t; -#ifdef DOXYGEN -typedef _lv_menu_mode_header_t lv_menu_mode_header_t; -#else -typedef uint8_t lv_menu_mode_header_t; -#endif /*DOXYGEN*/ - -enum _lv_menu_mode_root_back_button_t { +typedef enum { LV_MENU_ROOT_BACK_BUTTON_DISABLED, LV_MENU_ROOT_BACK_BUTTON_ENABLED -}; - -#ifdef DOXYGEN -typedef _lv_menu_mode_root_back_button_t lv_menu_mode_root_back_button_t; -#else -typedef uint8_t lv_menu_mode_root_back_button_t; -#endif /*DOXYGEN*/ - -typedef struct /// @cond -/** - * Tells Doxygen to ignore a duplicate declaration - */ - lv_menu_load_page_event_data_t -/// @endcond -{ - lv_obj_t * menu; - lv_obj_t * page; -} lv_menu_load_page_event_data_t ; - -typedef struct { - lv_obj_t * page; -} lv_menu_history_t; - -typedef struct { - lv_obj_t obj; - lv_obj_t * storage; /* a pointer to obj that is the parent of all pages not displayed */ - lv_obj_t * main; - lv_obj_t * main_page; - lv_obj_t * main_header; - lv_obj_t * - main_header_back_btn; /* a pointer to obj that on click triggers back btn event handler, can be same as 'main_header' */ - lv_obj_t * main_header_title; - lv_obj_t * sidebar; - lv_obj_t * sidebar_page; - lv_obj_t * sidebar_header; - lv_obj_t * - sidebar_header_back_btn; /* a pointer to obj that on click triggers back btn event handler, can be same as 'sidebar_header' */ - lv_obj_t * sidebar_header_title; - lv_obj_t * selected_tab; - lv_ll_t history_ll; - uint8_t cur_depth; - uint8_t prev_depth; - uint8_t sidebar_generated : 1; - lv_menu_mode_header_t mode_header : 2; - lv_menu_mode_root_back_button_t mode_root_back_btn : 1; -} lv_menu_t; - -typedef struct { - lv_obj_t obj; - char * title; - bool static_title; -} lv_menu_page_t; +} lv_menu_mode_root_back_button_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_class; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_page_class; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu_private.h new file mode 100644 index 000000000..fca898df9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu_private.h @@ -0,0 +1,84 @@ +/** + * @file lv_menu_private.h + * + */ + +#ifndef LV_MENU_PRIVATE_H +#define LV_MENU_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_menu.h" + +#if LV_USE_MENU + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_menu_load_page_event_data_t { + lv_obj_t * menu; + lv_obj_t * page; +}; + +struct lv_menu_history_t { + lv_obj_t * page; +}; + +struct lv_menu_t { + lv_obj_t obj; + lv_obj_t * storage; /**< a pointer to obj that is the parent of all pages not displayed */ + lv_obj_t * main; + lv_obj_t * main_page; + lv_obj_t * main_header; + lv_obj_t * + main_header_back_btn; /**< a pointer to obj that on click triggers back btn event handler, can be same as 'main_header' */ + lv_obj_t * main_header_title; + lv_obj_t * sidebar; + lv_obj_t * sidebar_page; + lv_obj_t * sidebar_header; + lv_obj_t * + sidebar_header_back_btn; /**< a pointer to obj that on click triggers back btn event handler, can be same as 'sidebar_header' */ + lv_obj_t * sidebar_header_title; + lv_obj_t * selected_tab; + lv_ll_t history_ll; + uint8_t cur_depth; + uint8_t prev_depth; + uint8_t sidebar_generated : 1; + lv_menu_mode_header_t mode_header : 2; + lv_menu_mode_root_back_button_t mode_root_back_btn : 1; +}; + +struct lv_menu_page_t { + lv_obj_t obj; + char * title; + bool static_title; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_MENU */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MENU_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.c b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.c index 6f9d4a72d..98ad81e16 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_msgbox.h" +#include "lv_msgbox_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_MSGBOX #include "../label/lv_label.h" @@ -31,6 +33,7 @@ * STATIC PROTOTYPES **********************/ static void msgbox_close_click_event_cb(lv_event_t * e); +static void msgbox_size_changed_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -128,6 +131,7 @@ lv_obj_t * lv_msgbox_create(lv_obj_t * parent) if(mbox->content == NULL) return NULL; lv_obj_class_init_obj(mbox->content); lv_obj_set_flex_flow(mbox->content, LV_FLEX_FLOW_COLUMN); + lv_obj_add_event_cb(obj, msgbox_size_changed_event_cb, LV_EVENT_SIZE_CHANGED, 0); lv_obj_center(obj); return obj; @@ -145,6 +149,7 @@ lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title) lv_obj_set_size(mbox->header, lv_pct(100), lv_display_get_dpi(lv_obj_get_display(obj)) / 3); lv_obj_set_flex_flow(mbox->header, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(mbox->header, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_remove_flag(mbox->header, LV_OBJ_FLAG_SCROLLABLE); lv_obj_move_to_index(mbox->header, 0); } @@ -169,6 +174,7 @@ lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon) LV_ASSERT_MALLOC(obj); if(btn == NULL) return NULL; lv_obj_class_init_obj(btn); + lv_obj_remove_flag(btn, LV_OBJ_FLAG_SCROLLABLE); if(icon) { lv_obj_t * img = lv_image_create(btn); @@ -201,12 +207,14 @@ lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text) lv_obj_set_flex_flow(mbox->footer, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(mbox->footer, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_remove_flag(mbox->footer, LV_OBJ_FLAG_SCROLLABLE); } lv_obj_t * btn = lv_obj_class_create_obj(&lv_msgbox_footer_button_class, mbox->footer); LV_ASSERT_MALLOC(obj); if(btn == NULL) return NULL; lv_obj_class_init_obj(btn); + lv_obj_remove_flag(btn, LV_OBJ_FLAG_SCROLLABLE); if(text) { lv_obj_t * label = lv_label_create(btn); @@ -275,4 +283,12 @@ static void msgbox_close_click_event_cb(lv_event_t * e) lv_msgbox_close(mbox); } +static void msgbox_size_changed_event_cb(lv_event_t * e) +{ + lv_obj_t * mbox = lv_event_get_target(e); + lv_obj_t * content = lv_msgbox_get_content(mbox); + bool is_msgbox_height_size_content = (lv_obj_get_style_height(mbox, 0) == LV_SIZE_CONTENT); + lv_obj_set_flex_grow(content, !is_msgbox_height_size_content); +} + #endif /*LV_USE_MSGBOX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.h b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.h index b7413ee7e..5605b8028 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.h @@ -1,5 +1,5 @@ /** - * @file lv_mbox.h + * @file lv_msgbox.h * */ @@ -19,7 +19,7 @@ extern "C" { /*Testing of dependencies*/ #if LV_USE_BUTTONMATRIX == 0 -#error "lv_mbox: lv_btnm is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " +#error "lv_mbox: lv_buttonmatrix is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " #endif #if LV_USE_LABEL == 0 @@ -30,18 +30,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_obj_t obj; - lv_obj_t * header; - lv_obj_t * content; - lv_obj_t * footer; - lv_obj_t * title; -} lv_msgbox_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_class; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_header_class; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_content_class; @@ -56,7 +44,7 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_msgbox_backdrop_class; /** * Create an empty message box - * @param parent the parent of the message box + * @param parent the parent or NULL to create a modal msgbox * @return the created message box */ lv_obj_t * lv_msgbox_create(lv_obj_t * parent); @@ -78,9 +66,9 @@ lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title); lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon); /** - * Add a text to the content area of message box. Multiply texts will be created below each other. + * Add a text to the content area of message box. Multiple texts will be created below each other. * @param obj pointer to a message box - * @param icon the icon of the button + * @param text text to add * @return the created button */ lv_obj_t * lv_msgbox_add_text(lv_obj_t * obj, const char * text); @@ -94,7 +82,7 @@ lv_obj_t * lv_msgbox_add_text(lv_obj_t * obj, const char * text); lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text); /** - * Add a close button to the message box. It also create a header. + * Add a close button to the message box. It also creates a header. * @param obj pointer to a message box * @return the created close button */ @@ -117,26 +105,26 @@ lv_obj_t * lv_msgbox_get_footer(lv_obj_t * obj); /** * Get the content widget * @param obj pointer to a message box - * @return the content, or NULL if not exists + * @return the content */ lv_obj_t * lv_msgbox_get_content(lv_obj_t * obj); /** * Get the title label * @param obj pointer to a message box - * @return the title, or NULL if not exists + * @return the title, or NULL if it does not exist */ lv_obj_t * lv_msgbox_get_title(lv_obj_t * obj); /** * Close a message box - * @param obj pointer to a message box + * @param mbox pointer to a message box */ void lv_msgbox_close(lv_obj_t * mbox); /** * Close a message box in the next call of the message box - * @param obj pointer to a message box + * @param mbox pointer to a message box */ void lv_msgbox_close_async(lv_obj_t * mbox); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox_private.h new file mode 100644 index 000000000..640a39cbd --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_msgbox_private.h + * + */ + +#ifndef LV_MSGBOX_PRIVATE_H +#define LV_MSGBOX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_msgbox.h" + +#if LV_USE_MSGBOX +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_msgbox_t { + lv_obj_t obj; + lv_obj_t * header; + lv_obj_t * content; + lv_obj_t * footer; + lv_obj_t * title; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_MSGBOX */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MSGBOX_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_dropdown_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_dropdown_properties.c new file mode 100644 index 000000000..9477ca3c8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_dropdown_properties.c @@ -0,0 +1,31 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_dropdown_properties.c + */ + +#include "../dropdown/lv_dropdown.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_DROPDOWN +/** + * Dropdown widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_dropdown_property_names[9] = { + {"dir", LV_PROPERTY_DROPDOWN_DIR,}, + {"is_open", LV_PROPERTY_DROPDOWN_IS_OPEN,}, + {"list", LV_PROPERTY_DROPDOWN_LIST,}, + {"option_count", LV_PROPERTY_DROPDOWN_OPTION_COUNT,}, + {"options", LV_PROPERTY_DROPDOWN_OPTIONS,}, + {"selected", LV_PROPERTY_DROPDOWN_SELECTED,}, + {"selected_highlight", LV_PROPERTY_DROPDOWN_SELECTED_HIGHLIGHT,}, + {"symbol", LV_PROPERTY_DROPDOWN_SYMBOL,}, + {"text", LV_PROPERTY_DROPDOWN_TEXT,}, +}; +#endif /*LV_USE_DROPDOWN*/ + +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_image_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_image_properties.c new file mode 100644 index 000000000..fd7fd7d1b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_image_properties.c @@ -0,0 +1,33 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_image_properties.c + */ + +#include "../image/lv_image.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_IMAGE +/** + * Image widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_image_property_names[11] = { + {"antialias", LV_PROPERTY_IMAGE_ANTIALIAS,}, + {"blend_mode", LV_PROPERTY_IMAGE_BLEND_MODE,}, + {"inner_align", LV_PROPERTY_IMAGE_INNER_ALIGN,}, + {"offset_x", LV_PROPERTY_IMAGE_OFFSET_X,}, + {"offset_y", LV_PROPERTY_IMAGE_OFFSET_Y,}, + {"pivot", LV_PROPERTY_IMAGE_PIVOT,}, + {"rotation", LV_PROPERTY_IMAGE_ROTATION,}, + {"scale", LV_PROPERTY_IMAGE_SCALE,}, + {"scale_x", LV_PROPERTY_IMAGE_SCALE_X,}, + {"scale_y", LV_PROPERTY_IMAGE_SCALE_Y,}, + {"src", LV_PROPERTY_IMAGE_SRC,}, +}; +#endif /*LV_USE_IMAGE*/ + +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_keyboard_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_keyboard_properties.c new file mode 100644 index 000000000..90cfc3e26 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_keyboard_properties.c @@ -0,0 +1,26 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_keyboard_properties.c + */ + +#include "../keyboard/lv_keyboard.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_KEYBOARD +/** + * Keyboard widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_keyboard_property_names[4] = { + {"mode", LV_PROPERTY_KEYBOARD_MODE,}, + {"popovers", LV_PROPERTY_KEYBOARD_POPOVERS,}, + {"selected_button", LV_PROPERTY_KEYBOARD_SELECTED_BUTTON,}, + {"textarea", LV_PROPERTY_KEYBOARD_TEXTAREA,}, +}; +#endif /*LV_USE_KEYBOARD*/ + +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_label_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_label_properties.c new file mode 100644 index 000000000..5fc6708b7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_label_properties.c @@ -0,0 +1,26 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_label_properties.c + */ + +#include "../label/lv_label.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_LABEL +/** + * Label widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_label_property_names[4] = { + {"long_mode", LV_PROPERTY_LABEL_LONG_MODE,}, + {"text", LV_PROPERTY_LABEL_TEXT,}, + {"text_selection_end", LV_PROPERTY_LABEL_TEXT_SELECTION_END,}, + {"text_selection_start", LV_PROPERTY_LABEL_TEXT_SELECTION_START,}, +}; +#endif /*LV_USE_LABEL*/ + +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_properties.c new file mode 100644 index 000000000..1008b3691 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_properties.c @@ -0,0 +1,93 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_obj_properties.c + */ + +#include "../../core/lv_obj.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + + +/** + * Obj widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_obj_property_names[73] = { + {"align", LV_PROPERTY_OBJ_ALIGN,}, + {"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,}, + {"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,}, + {"content_width", LV_PROPERTY_OBJ_CONTENT_WIDTH,}, + {"display", LV_PROPERTY_OBJ_DISPLAY,}, + {"event_count", LV_PROPERTY_OBJ_EVENT_COUNT,}, + {"ext_draw_size", LV_PROPERTY_OBJ_EXT_DRAW_SIZE,}, + {"flag_adv_hittest", LV_PROPERTY_OBJ_FLAG_ADV_HITTEST,}, + {"flag_checkable", LV_PROPERTY_OBJ_FLAG_CHECKABLE,}, + {"flag_click_focusable", LV_PROPERTY_OBJ_FLAG_CLICK_FOCUSABLE,}, + {"flag_clickable", LV_PROPERTY_OBJ_FLAG_CLICKABLE,}, + {"flag_end", LV_PROPERTY_OBJ_FLAG_END,}, + {"flag_event_bubble", LV_PROPERTY_OBJ_FLAG_EVENT_BUBBLE,}, + {"flag_flex_in_new_track", LV_PROPERTY_OBJ_FLAG_FLEX_IN_NEW_TRACK,}, + {"flag_floating", LV_PROPERTY_OBJ_FLAG_FLOATING,}, + {"flag_gesture_bubble", LV_PROPERTY_OBJ_FLAG_GESTURE_BUBBLE,}, + {"flag_hidden", LV_PROPERTY_OBJ_FLAG_HIDDEN,}, + {"flag_ignore_layout", LV_PROPERTY_OBJ_FLAG_IGNORE_LAYOUT,}, + {"flag_layout_1", LV_PROPERTY_OBJ_FLAG_LAYOUT_1,}, + {"flag_layout_2", LV_PROPERTY_OBJ_FLAG_LAYOUT_2,}, + {"flag_overflow_visible", LV_PROPERTY_OBJ_FLAG_OVERFLOW_VISIBLE,}, + {"flag_press_lock", LV_PROPERTY_OBJ_FLAG_PRESS_LOCK,}, + {"flag_scroll_chain_hor", LV_PROPERTY_OBJ_FLAG_SCROLL_CHAIN_HOR,}, + {"flag_scroll_chain_ver", LV_PROPERTY_OBJ_FLAG_SCROLL_CHAIN_VER,}, + {"flag_scroll_elastic", LV_PROPERTY_OBJ_FLAG_SCROLL_ELASTIC,}, + {"flag_scroll_momentum", LV_PROPERTY_OBJ_FLAG_SCROLL_MOMENTUM,}, + {"flag_scroll_on_focus", LV_PROPERTY_OBJ_FLAG_SCROLL_ON_FOCUS,}, + {"flag_scroll_one", LV_PROPERTY_OBJ_FLAG_SCROLL_ONE,}, + {"flag_scroll_with_arrow", LV_PROPERTY_OBJ_FLAG_SCROLL_WITH_ARROW,}, + {"flag_scrollable", LV_PROPERTY_OBJ_FLAG_SCROLLABLE,}, + {"flag_send_draw_task_events", LV_PROPERTY_OBJ_FLAG_SEND_DRAW_TASK_EVENTS,}, + {"flag_snappable", LV_PROPERTY_OBJ_FLAG_SNAPPABLE,}, + {"flag_start", LV_PROPERTY_OBJ_FLAG_START,}, + {"flag_user_1", LV_PROPERTY_OBJ_FLAG_USER_1,}, + {"flag_user_2", LV_PROPERTY_OBJ_FLAG_USER_2,}, + {"flag_user_3", LV_PROPERTY_OBJ_FLAG_USER_3,}, + {"flag_user_4", LV_PROPERTY_OBJ_FLAG_USER_4,}, + {"flag_widget_1", LV_PROPERTY_OBJ_FLAG_WIDGET_1,}, + {"flag_widget_2", LV_PROPERTY_OBJ_FLAG_WIDGET_2,}, + {"h", LV_PROPERTY_OBJ_H,}, + {"index", LV_PROPERTY_OBJ_INDEX,}, + {"layout", LV_PROPERTY_OBJ_LAYOUT,}, + {"parent", LV_PROPERTY_OBJ_PARENT,}, + {"screen", LV_PROPERTY_OBJ_SCREEN,}, + {"scroll_bottom", LV_PROPERTY_OBJ_SCROLL_BOTTOM,}, + {"scroll_dir", LV_PROPERTY_OBJ_SCROLL_DIR,}, + {"scroll_end", LV_PROPERTY_OBJ_SCROLL_END,}, + {"scroll_left", LV_PROPERTY_OBJ_SCROLL_LEFT,}, + {"scroll_right", LV_PROPERTY_OBJ_SCROLL_RIGHT,}, + {"scroll_snap_x", LV_PROPERTY_OBJ_SCROLL_SNAP_X,}, + {"scroll_snap_y", LV_PROPERTY_OBJ_SCROLL_SNAP_Y,}, + {"scroll_top", LV_PROPERTY_OBJ_SCROLL_TOP,}, + {"scroll_x", LV_PROPERTY_OBJ_SCROLL_X,}, + {"scroll_y", LV_PROPERTY_OBJ_SCROLL_Y,}, + {"scrollbar_mode", LV_PROPERTY_OBJ_SCROLLBAR_MODE,}, + {"state_any", LV_PROPERTY_OBJ_STATE_ANY,}, + {"state_checked", LV_PROPERTY_OBJ_STATE_CHECKED,}, + {"state_disabled", LV_PROPERTY_OBJ_STATE_DISABLED,}, + {"state_edited", LV_PROPERTY_OBJ_STATE_EDITED,}, + {"state_end", LV_PROPERTY_OBJ_STATE_END,}, + {"state_focus_key", LV_PROPERTY_OBJ_STATE_FOCUS_KEY,}, + {"state_focused", LV_PROPERTY_OBJ_STATE_FOCUSED,}, + {"state_hovered", LV_PROPERTY_OBJ_STATE_HOVERED,}, + {"state_pressed", LV_PROPERTY_OBJ_STATE_PRESSED,}, + {"state_scrolled", LV_PROPERTY_OBJ_STATE_SCROLLED,}, + {"state_start", LV_PROPERTY_OBJ_STATE_START,}, + {"state_user_1", LV_PROPERTY_OBJ_STATE_USER_1,}, + {"state_user_2", LV_PROPERTY_OBJ_STATE_USER_2,}, + {"state_user_3", LV_PROPERTY_OBJ_STATE_USER_3,}, + {"state_user_4", LV_PROPERTY_OBJ_STATE_USER_4,}, + {"w", LV_PROPERTY_OBJ_W,}, + {"x", LV_PROPERTY_OBJ_X,}, + {"y", LV_PROPERTY_OBJ_Y,}, +}; +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_property_names.h b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_property_names.h new file mode 100644 index 000000000..4b4ff67ae --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_obj_property_names.h @@ -0,0 +1,22 @@ + +/** + * @file lv_obj_property_names.h + * GENERATED FILE, DO NOT EDIT IT! + */ +#ifndef LV_OBJ_PROPERTY_NAMES_H +#define LV_OBJ_PROPERTY_NAMES_H + +#include "../../misc/lv_types.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + + extern const lv_property_name_t lv_dropdown_property_names[9]; + extern const lv_property_name_t lv_image_property_names[11]; + extern const lv_property_name_t lv_keyboard_property_names[4]; + extern const lv_property_name_t lv_label_property_names[4]; + extern const lv_property_name_t lv_obj_property_names[73]; + extern const lv_property_name_t lv_roller_property_names[3]; + extern const lv_property_name_t lv_style_property_names[112]; + extern const lv_property_name_t lv_textarea_property_names[15]; +#endif +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_roller_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_roller_properties.c new file mode 100644 index 000000000..72aa01783 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_roller_properties.c @@ -0,0 +1,25 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_roller_properties.c + */ + +#include "../roller/lv_roller.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_ROLLER +/** + * Roller widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_roller_property_names[3] = { + {"options", LV_PROPERTY_ROLLER_OPTIONS,}, + {"selected", LV_PROPERTY_ROLLER_SELECTED,}, + {"visible_row_count", LV_PROPERTY_ROLLER_VISIBLE_ROW_COUNT,}, +}; +#endif /*LV_USE_ROLLER*/ + +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.c new file mode 100644 index 000000000..22ef3e257 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.c @@ -0,0 +1,132 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_style_properties.c + */ + +#include "lv_style_properties.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + + +/** + * Style property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_style_property_names[112] = { + {"align", LV_PROPERTY_STYLE_ALIGN,}, + {"anim", LV_PROPERTY_STYLE_ANIM,}, + {"anim_duration", LV_PROPERTY_STYLE_ANIM_DURATION,}, + {"arc_color", LV_PROPERTY_STYLE_ARC_COLOR,}, + {"arc_image_src", LV_PROPERTY_STYLE_ARC_IMAGE_SRC,}, + {"arc_opa", LV_PROPERTY_STYLE_ARC_OPA,}, + {"arc_rounded", LV_PROPERTY_STYLE_ARC_ROUNDED,}, + {"arc_width", LV_PROPERTY_STYLE_ARC_WIDTH,}, + {"base_dir", LV_PROPERTY_STYLE_BASE_DIR,}, + {"bg_color", LV_PROPERTY_STYLE_BG_COLOR,}, + {"bg_grad", LV_PROPERTY_STYLE_BG_GRAD,}, + {"bg_grad_color", LV_PROPERTY_STYLE_BG_GRAD_COLOR,}, + {"bg_grad_dir", LV_PROPERTY_STYLE_BG_GRAD_DIR,}, + {"bg_grad_opa", LV_PROPERTY_STYLE_BG_GRAD_OPA,}, + {"bg_grad_stop", LV_PROPERTY_STYLE_BG_GRAD_STOP,}, + {"bg_image_opa", LV_PROPERTY_STYLE_BG_IMAGE_OPA,}, + {"bg_image_recolor", LV_PROPERTY_STYLE_BG_IMAGE_RECOLOR,}, + {"bg_image_recolor_opa", LV_PROPERTY_STYLE_BG_IMAGE_RECOLOR_OPA,}, + {"bg_image_src", LV_PROPERTY_STYLE_BG_IMAGE_SRC,}, + {"bg_image_tiled", LV_PROPERTY_STYLE_BG_IMAGE_TILED,}, + {"bg_main_opa", LV_PROPERTY_STYLE_BG_MAIN_OPA,}, + {"bg_main_stop", LV_PROPERTY_STYLE_BG_MAIN_STOP,}, + {"bg_opa", LV_PROPERTY_STYLE_BG_OPA,}, + {"bitmap_mask_src", LV_PROPERTY_STYLE_BITMAP_MASK_SRC,}, + {"blend_mode", LV_PROPERTY_STYLE_BLEND_MODE,}, + {"border_color", LV_PROPERTY_STYLE_BORDER_COLOR,}, + {"border_opa", LV_PROPERTY_STYLE_BORDER_OPA,}, + {"border_post", LV_PROPERTY_STYLE_BORDER_POST,}, + {"border_side", LV_PROPERTY_STYLE_BORDER_SIDE,}, + {"border_width", LV_PROPERTY_STYLE_BORDER_WIDTH,}, + {"clip_corner", LV_PROPERTY_STYLE_CLIP_CORNER,}, + {"color_filter_dsc", LV_PROPERTY_STYLE_COLOR_FILTER_DSC,}, + {"color_filter_opa", LV_PROPERTY_STYLE_COLOR_FILTER_OPA,}, + {"flex_cross_place", LV_PROPERTY_STYLE_FLEX_CROSS_PLACE,}, + {"flex_flow", LV_PROPERTY_STYLE_FLEX_FLOW,}, + {"flex_grow", LV_PROPERTY_STYLE_FLEX_GROW,}, + {"flex_main_place", LV_PROPERTY_STYLE_FLEX_MAIN_PLACE,}, + {"flex_track_place", LV_PROPERTY_STYLE_FLEX_TRACK_PLACE,}, + {"grid_cell_column_pos", LV_PROPERTY_STYLE_GRID_CELL_COLUMN_POS,}, + {"grid_cell_column_span", LV_PROPERTY_STYLE_GRID_CELL_COLUMN_SPAN,}, + {"grid_cell_row_pos", LV_PROPERTY_STYLE_GRID_CELL_ROW_POS,}, + {"grid_cell_row_span", LV_PROPERTY_STYLE_GRID_CELL_ROW_SPAN,}, + {"grid_cell_x_align", LV_PROPERTY_STYLE_GRID_CELL_X_ALIGN,}, + {"grid_cell_y_align", LV_PROPERTY_STYLE_GRID_CELL_Y_ALIGN,}, + {"grid_column_align", LV_PROPERTY_STYLE_GRID_COLUMN_ALIGN,}, + {"grid_column_dsc_array", LV_PROPERTY_STYLE_GRID_COLUMN_DSC_ARRAY,}, + {"grid_row_align", LV_PROPERTY_STYLE_GRID_ROW_ALIGN,}, + {"grid_row_dsc_array", LV_PROPERTY_STYLE_GRID_ROW_DSC_ARRAY,}, + {"height", LV_PROPERTY_STYLE_HEIGHT,}, + {"image_opa", LV_PROPERTY_STYLE_IMAGE_OPA,}, + {"image_recolor", LV_PROPERTY_STYLE_IMAGE_RECOLOR,}, + {"image_recolor_opa", LV_PROPERTY_STYLE_IMAGE_RECOLOR_OPA,}, + {"last_built_in_prop", LV_PROPERTY_STYLE_LAST_BUILT_IN_PROP,}, + {"layout", LV_PROPERTY_STYLE_LAYOUT,}, + {"length", LV_PROPERTY_STYLE_LENGTH,}, + {"line_color", LV_PROPERTY_STYLE_LINE_COLOR,}, + {"line_dash_gap", LV_PROPERTY_STYLE_LINE_DASH_GAP,}, + {"line_dash_width", LV_PROPERTY_STYLE_LINE_DASH_WIDTH,}, + {"line_opa", LV_PROPERTY_STYLE_LINE_OPA,}, + {"line_rounded", LV_PROPERTY_STYLE_LINE_ROUNDED,}, + {"line_width", LV_PROPERTY_STYLE_LINE_WIDTH,}, + {"margin_bottom", LV_PROPERTY_STYLE_MARGIN_BOTTOM,}, + {"margin_left", LV_PROPERTY_STYLE_MARGIN_LEFT,}, + {"margin_right", LV_PROPERTY_STYLE_MARGIN_RIGHT,}, + {"margin_top", LV_PROPERTY_STYLE_MARGIN_TOP,}, + {"max_height", LV_PROPERTY_STYLE_MAX_HEIGHT,}, + {"max_width", LV_PROPERTY_STYLE_MAX_WIDTH,}, + {"min_height", LV_PROPERTY_STYLE_MIN_HEIGHT,}, + {"min_width", LV_PROPERTY_STYLE_MIN_WIDTH,}, + {"opa", LV_PROPERTY_STYLE_OPA,}, + {"opa_layered", LV_PROPERTY_STYLE_OPA_LAYERED,}, + {"outline_color", LV_PROPERTY_STYLE_OUTLINE_COLOR,}, + {"outline_opa", LV_PROPERTY_STYLE_OUTLINE_OPA,}, + {"outline_pad", LV_PROPERTY_STYLE_OUTLINE_PAD,}, + {"outline_width", LV_PROPERTY_STYLE_OUTLINE_WIDTH,}, + {"pad_bottom", LV_PROPERTY_STYLE_PAD_BOTTOM,}, + {"pad_column", LV_PROPERTY_STYLE_PAD_COLUMN,}, + {"pad_left", LV_PROPERTY_STYLE_PAD_LEFT,}, + {"pad_right", LV_PROPERTY_STYLE_PAD_RIGHT,}, + {"pad_row", LV_PROPERTY_STYLE_PAD_ROW,}, + {"pad_top", LV_PROPERTY_STYLE_PAD_TOP,}, + {"prop_inv", LV_PROPERTY_STYLE_PROP_INV,}, + {"radius", LV_PROPERTY_STYLE_RADIUS,}, + {"rotary_sensitivity", LV_PROPERTY_STYLE_ROTARY_SENSITIVITY,}, + {"shadow_color", LV_PROPERTY_STYLE_SHADOW_COLOR,}, + {"shadow_offset_x", LV_PROPERTY_STYLE_SHADOW_OFFSET_X,}, + {"shadow_offset_y", LV_PROPERTY_STYLE_SHADOW_OFFSET_Y,}, + {"shadow_opa", LV_PROPERTY_STYLE_SHADOW_OPA,}, + {"shadow_spread", LV_PROPERTY_STYLE_SHADOW_SPREAD,}, + {"shadow_width", LV_PROPERTY_STYLE_SHADOW_WIDTH,}, + {"text_align", LV_PROPERTY_STYLE_TEXT_ALIGN,}, + {"text_color", LV_PROPERTY_STYLE_TEXT_COLOR,}, + {"text_decor", LV_PROPERTY_STYLE_TEXT_DECOR,}, + {"text_font", LV_PROPERTY_STYLE_TEXT_FONT,}, + {"text_letter_space", LV_PROPERTY_STYLE_TEXT_LETTER_SPACE,}, + {"text_line_space", LV_PROPERTY_STYLE_TEXT_LINE_SPACE,}, + {"text_opa", LV_PROPERTY_STYLE_TEXT_OPA,}, + {"transform_height", LV_PROPERTY_STYLE_TRANSFORM_HEIGHT,}, + {"transform_pivot_x", LV_PROPERTY_STYLE_TRANSFORM_PIVOT_X,}, + {"transform_pivot_y", LV_PROPERTY_STYLE_TRANSFORM_PIVOT_Y,}, + {"transform_rotation", LV_PROPERTY_STYLE_TRANSFORM_ROTATION,}, + {"transform_scale_x", LV_PROPERTY_STYLE_TRANSFORM_SCALE_X,}, + {"transform_scale_y", LV_PROPERTY_STYLE_TRANSFORM_SCALE_Y,}, + {"transform_skew_x", LV_PROPERTY_STYLE_TRANSFORM_SKEW_X,}, + {"transform_skew_y", LV_PROPERTY_STYLE_TRANSFORM_SKEW_Y,}, + {"transform_width", LV_PROPERTY_STYLE_TRANSFORM_WIDTH,}, + {"transition", LV_PROPERTY_STYLE_TRANSITION,}, + {"translate_x", LV_PROPERTY_STYLE_TRANSLATE_X,}, + {"translate_y", LV_PROPERTY_STYLE_TRANSLATE_Y,}, + {"width", LV_PROPERTY_STYLE_WIDTH,}, + {"x", LV_PROPERTY_STYLE_X,}, + {"y", LV_PROPERTY_STYLE_Y,}, +}; +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.h b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.h new file mode 100644 index 000000000..146f35ad7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.h @@ -0,0 +1,130 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_style_properties.h + */ +#ifndef LV_STYLE_PROPERTIES_H +#define LV_STYLE_PROPERTIES_H + +#include "../../core/lv_obj_property.h" +#if LV_USE_OBJ_PROPERTY + + +/* *INDENT-OFF* */ +enum { + LV_PROPERTY_ID(STYLE, ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_ALIGN), + LV_PROPERTY_ID(STYLE, ANIM, LV_PROPERTY_TYPE_INT, LV_STYLE_ANIM), + LV_PROPERTY_ID(STYLE, ANIM_DURATION, LV_PROPERTY_TYPE_INT, LV_STYLE_ANIM_DURATION), + LV_PROPERTY_ID(STYLE, ARC_COLOR, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_COLOR), + LV_PROPERTY_ID(STYLE, ARC_IMAGE_SRC, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_IMAGE_SRC), + LV_PROPERTY_ID(STYLE, ARC_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_OPA), + LV_PROPERTY_ID(STYLE, ARC_ROUNDED, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_ROUNDED), + LV_PROPERTY_ID(STYLE, ARC_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_ARC_WIDTH), + LV_PROPERTY_ID(STYLE, BASE_DIR, LV_PROPERTY_TYPE_INT, LV_STYLE_BASE_DIR), + LV_PROPERTY_ID(STYLE, BG_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BG_COLOR), + LV_PROPERTY_ID(STYLE, BG_GRAD, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD), + LV_PROPERTY_ID(STYLE, BG_GRAD_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BG_GRAD_COLOR), + LV_PROPERTY_ID(STYLE, BG_GRAD_DIR, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD_DIR), + LV_PROPERTY_ID(STYLE, BG_GRAD_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD_OPA), + LV_PROPERTY_ID(STYLE, BG_GRAD_STOP, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_GRAD_STOP), + LV_PROPERTY_ID(STYLE, BG_IMAGE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_IMAGE_OPA), + LV_PROPERTY_ID(STYLE, BG_IMAGE_RECOLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BG_IMAGE_RECOLOR), + LV_PROPERTY_ID(STYLE, BG_IMAGE_RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_IMAGE_RECOLOR_OPA), + LV_PROPERTY_ID(STYLE, BG_IMAGE_SRC, LV_PROPERTY_TYPE_IMGSRC, LV_STYLE_BG_IMAGE_SRC), + LV_PROPERTY_ID(STYLE, BG_IMAGE_TILED, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_IMAGE_TILED), + LV_PROPERTY_ID(STYLE, BG_MAIN_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_MAIN_OPA), + LV_PROPERTY_ID(STYLE, BG_MAIN_STOP, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_MAIN_STOP), + LV_PROPERTY_ID(STYLE, BG_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BG_OPA), + LV_PROPERTY_ID(STYLE, BITMAP_MASK_SRC, LV_PROPERTY_TYPE_INT, LV_STYLE_BITMAP_MASK_SRC), + LV_PROPERTY_ID(STYLE, BLEND_MODE, LV_PROPERTY_TYPE_INT, LV_STYLE_BLEND_MODE), + LV_PROPERTY_ID(STYLE, BORDER_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_BORDER_COLOR), + LV_PROPERTY_ID(STYLE, BORDER_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_OPA), + LV_PROPERTY_ID(STYLE, BORDER_POST, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_POST), + LV_PROPERTY_ID(STYLE, BORDER_SIDE, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_SIDE), + LV_PROPERTY_ID(STYLE, BORDER_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_BORDER_WIDTH), + LV_PROPERTY_ID(STYLE, CLIP_CORNER, LV_PROPERTY_TYPE_INT, LV_STYLE_CLIP_CORNER), + LV_PROPERTY_ID(STYLE, COLOR_FILTER_DSC, LV_PROPERTY_TYPE_INT, LV_STYLE_COLOR_FILTER_DSC), + LV_PROPERTY_ID(STYLE, COLOR_FILTER_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_COLOR_FILTER_OPA), + LV_PROPERTY_ID(STYLE, FLEX_CROSS_PLACE, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_CROSS_PLACE), + LV_PROPERTY_ID(STYLE, FLEX_FLOW, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_FLOW), + LV_PROPERTY_ID(STYLE, FLEX_GROW, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_GROW), + LV_PROPERTY_ID(STYLE, FLEX_MAIN_PLACE, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_MAIN_PLACE), + LV_PROPERTY_ID(STYLE, FLEX_TRACK_PLACE, LV_PROPERTY_TYPE_INT, LV_STYLE_FLEX_TRACK_PLACE), + LV_PROPERTY_ID(STYLE, GRID_CELL_COLUMN_POS, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_COLUMN_POS), + LV_PROPERTY_ID(STYLE, GRID_CELL_COLUMN_SPAN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_COLUMN_SPAN), + LV_PROPERTY_ID(STYLE, GRID_CELL_ROW_POS, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_ROW_POS), + LV_PROPERTY_ID(STYLE, GRID_CELL_ROW_SPAN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_ROW_SPAN), + LV_PROPERTY_ID(STYLE, GRID_CELL_X_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_X_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_CELL_Y_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_CELL_Y_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_COLUMN_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_COLUMN_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_COLUMN_DSC_ARRAY, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_COLUMN_DSC_ARRAY), + LV_PROPERTY_ID(STYLE, GRID_ROW_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_ROW_ALIGN), + LV_PROPERTY_ID(STYLE, GRID_ROW_DSC_ARRAY, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_ROW_DSC_ARRAY), + LV_PROPERTY_ID(STYLE, HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_HEIGHT), + LV_PROPERTY_ID(STYLE, IMAGE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_OPA), + LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_IMAGE_RECOLOR), + LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_RECOLOR_OPA), + LV_PROPERTY_ID(STYLE, LAST_BUILT_IN_PROP, LV_PROPERTY_TYPE_INT, LV_STYLE_LAST_BUILT_IN_PROP), + LV_PROPERTY_ID(STYLE, LAYOUT, LV_PROPERTY_TYPE_INT, LV_STYLE_LAYOUT), + LV_PROPERTY_ID(STYLE, LENGTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LENGTH), + LV_PROPERTY_ID(STYLE, LINE_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_LINE_COLOR), + LV_PROPERTY_ID(STYLE, LINE_DASH_GAP, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_DASH_GAP), + LV_PROPERTY_ID(STYLE, LINE_DASH_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_DASH_WIDTH), + LV_PROPERTY_ID(STYLE, LINE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_OPA), + LV_PROPERTY_ID(STYLE, LINE_ROUNDED, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_ROUNDED), + LV_PROPERTY_ID(STYLE, LINE_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_LINE_WIDTH), + LV_PROPERTY_ID(STYLE, MARGIN_BOTTOM, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_BOTTOM), + LV_PROPERTY_ID(STYLE, MARGIN_LEFT, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_LEFT), + LV_PROPERTY_ID(STYLE, MARGIN_RIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_RIGHT), + LV_PROPERTY_ID(STYLE, MARGIN_TOP, LV_PROPERTY_TYPE_INT, LV_STYLE_MARGIN_TOP), + LV_PROPERTY_ID(STYLE, MAX_HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_MAX_HEIGHT), + LV_PROPERTY_ID(STYLE, MAX_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_MAX_WIDTH), + LV_PROPERTY_ID(STYLE, MIN_HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_MIN_HEIGHT), + LV_PROPERTY_ID(STYLE, MIN_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_MIN_WIDTH), + LV_PROPERTY_ID(STYLE, OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_OPA), + LV_PROPERTY_ID(STYLE, OPA_LAYERED, LV_PROPERTY_TYPE_INT, LV_STYLE_OPA_LAYERED), + LV_PROPERTY_ID(STYLE, OUTLINE_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_OUTLINE_COLOR), + LV_PROPERTY_ID(STYLE, OUTLINE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_OUTLINE_OPA), + LV_PROPERTY_ID(STYLE, OUTLINE_PAD, LV_PROPERTY_TYPE_INT, LV_STYLE_OUTLINE_PAD), + LV_PROPERTY_ID(STYLE, OUTLINE_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_OUTLINE_WIDTH), + LV_PROPERTY_ID(STYLE, PAD_BOTTOM, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_BOTTOM), + LV_PROPERTY_ID(STYLE, PAD_COLUMN, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_COLUMN), + LV_PROPERTY_ID(STYLE, PAD_LEFT, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_LEFT), + LV_PROPERTY_ID(STYLE, PAD_RIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_RIGHT), + LV_PROPERTY_ID(STYLE, PAD_ROW, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_ROW), + LV_PROPERTY_ID(STYLE, PAD_TOP, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_TOP), + LV_PROPERTY_ID(STYLE, PROP_INV, LV_PROPERTY_TYPE_INT, LV_STYLE_PROP_INV), + LV_PROPERTY_ID(STYLE, RADIUS, LV_PROPERTY_TYPE_INT, LV_STYLE_RADIUS), + LV_PROPERTY_ID(STYLE, ROTARY_SENSITIVITY, LV_PROPERTY_TYPE_INT, LV_STYLE_ROTARY_SENSITIVITY), + LV_PROPERTY_ID(STYLE, SHADOW_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_SHADOW_COLOR), + LV_PROPERTY_ID(STYLE, SHADOW_OFFSET_X, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_OFFSET_X), + LV_PROPERTY_ID(STYLE, SHADOW_OFFSET_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_OFFSET_Y), + LV_PROPERTY_ID(STYLE, SHADOW_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_OPA), + LV_PROPERTY_ID(STYLE, SHADOW_SPREAD, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_SPREAD), + LV_PROPERTY_ID(STYLE, SHADOW_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_SHADOW_WIDTH), + LV_PROPERTY_ID(STYLE, TEXT_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_ALIGN), + LV_PROPERTY_ID(STYLE, TEXT_COLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_TEXT_COLOR), + LV_PROPERTY_ID(STYLE, TEXT_DECOR, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_DECOR), + LV_PROPERTY_ID(STYLE, TEXT_FONT, LV_PROPERTY_TYPE_FONT, LV_STYLE_TEXT_FONT), + LV_PROPERTY_ID(STYLE, TEXT_LETTER_SPACE, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_LETTER_SPACE), + LV_PROPERTY_ID(STYLE, TEXT_LINE_SPACE, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_LINE_SPACE), + LV_PROPERTY_ID(STYLE, TEXT_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_OPA), + LV_PROPERTY_ID(STYLE, TRANSFORM_HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_HEIGHT), + LV_PROPERTY_ID(STYLE, TRANSFORM_PIVOT_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_PIVOT_X), + LV_PROPERTY_ID(STYLE, TRANSFORM_PIVOT_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_PIVOT_Y), + LV_PROPERTY_ID(STYLE, TRANSFORM_ROTATION, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_ROTATION), + LV_PROPERTY_ID(STYLE, TRANSFORM_SCALE_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SCALE_X), + LV_PROPERTY_ID(STYLE, TRANSFORM_SCALE_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SCALE_Y), + LV_PROPERTY_ID(STYLE, TRANSFORM_SKEW_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SKEW_X), + LV_PROPERTY_ID(STYLE, TRANSFORM_SKEW_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_SKEW_Y), + LV_PROPERTY_ID(STYLE, TRANSFORM_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSFORM_WIDTH), + LV_PROPERTY_ID(STYLE, TRANSITION, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSITION), + LV_PROPERTY_ID(STYLE, TRANSLATE_X, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSLATE_X), + LV_PROPERTY_ID(STYLE, TRANSLATE_Y, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSLATE_Y), + LV_PROPERTY_ID(STYLE, WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_WIDTH), + LV_PROPERTY_ID(STYLE, X, LV_PROPERTY_TYPE_INT, LV_STYLE_X), + LV_PROPERTY_ID(STYLE, Y, LV_PROPERTY_TYPE_INT, LV_STYLE_Y), +}; + +#endif +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_textarea_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_textarea_properties.c new file mode 100644 index 000000000..7bed65eab --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_textarea_properties.c @@ -0,0 +1,37 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_textarea_properties.c + */ + +#include "../textarea/lv_textarea.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_TEXTAREA +/** + * Textarea widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_textarea_property_names[15] = { + {"accepted_chars", LV_PROPERTY_TEXTAREA_ACCEPTED_CHARS,}, + {"current_char", LV_PROPERTY_TEXTAREA_CURRENT_CHAR,}, + {"cursor_click_pos", LV_PROPERTY_TEXTAREA_CURSOR_CLICK_POS,}, + {"cursor_pos", LV_PROPERTY_TEXTAREA_CURSOR_POS,}, + {"insert_replace", LV_PROPERTY_TEXTAREA_INSERT_REPLACE,}, + {"label", LV_PROPERTY_TEXTAREA_LABEL,}, + {"max_length", LV_PROPERTY_TEXTAREA_MAX_LENGTH,}, + {"one_line", LV_PROPERTY_TEXTAREA_ONE_LINE,}, + {"password_bullet", LV_PROPERTY_TEXTAREA_PASSWORD_BULLET,}, + {"password_mode", LV_PROPERTY_TEXTAREA_PASSWORD_MODE,}, + {"password_show_time", LV_PROPERTY_TEXTAREA_PASSWORD_SHOW_TIME,}, + {"placeholder_text", LV_PROPERTY_TEXTAREA_PLACEHOLDER_TEXT,}, + {"text", LV_PROPERTY_TEXTAREA_TEXT,}, + {"text_is_selected", LV_PROPERTY_TEXTAREA_TEXT_IS_SELECTED,}, + {"text_selection", LV_PROPERTY_TEXTAREA_TEXT_SELECTION,}, +}; +#endif /*LV_USE_TEXTAREA*/ + +/* *INDENT-ON* */ +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c index 98ed0f3df..efdb8d81d 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c @@ -6,11 +6,17 @@ /********************* * INCLUDES *********************/ -#include "lv_roller.h" +#include "lv_roller_private.h" +#include "../label/lv_label_private.h" +#include "../../misc/lv_area_private.h" +#include "../../misc/lv_anim_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_ROLLER != 0 #include "../../misc/lv_assert.h" -#include "../../draw/lv_draw.h" +#include "../../misc/lv_text_private.h" +#include "../../draw/lv_draw_private.h" #include "../../core/lv_group.h" #include "../../indev/lv_indev.h" #include "../../indev/lv_indev_scroll.h" @@ -49,6 +55,26 @@ static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect); /********************** * STATIC VARIABLES **********************/ +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_ROLLER_OPTIONS, + .setter = NULL, + .getter = lv_roller_get_options, + }, + { + .id = LV_PROPERTY_ROLLER_SELECTED, + .setter = NULL, + .getter = lv_roller_get_selected, + }, + { + .id = LV_PROPERTY_ROLLER_VISIBLE_ROW_COUNT, + .setter = lv_roller_set_visible_row_count, + .getter = NULL, + }, +}; +#endif + const lv_obj_class_t lv_roller_class = { .constructor_cb = lv_roller_constructor, .event_cb = lv_roller_event, @@ -59,6 +85,17 @@ const lv_obj_class_t lv_roller_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .base_class = &lv_obj_class, .name = "roller", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_ROLLER_START, + .prop_index_end = LV_PROPERTY_ROLLER_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_roller_property_names, + .names_count = sizeof(lv_roller_property_names) / sizeof(lv_property_name_t), +#endif +#endif }; const lv_obj_class_t lv_roller_label_class = { @@ -141,7 +178,6 @@ void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_ /*If the selected text has larger font the label needs some extra draw padding to draw it.*/ lv_obj_refresh_ext_draw_size(label); - } void lv_roller_set_selected(lv_obj_t * obj, uint32_t sel_opt, lv_anim_enable_t anim) @@ -313,22 +349,27 @@ static void lv_roller_event(const lv_obj_class_t * class_p, lv_event_t * e) refr_position(obj, LV_ANIM_OFF); } else if(code == LV_EVENT_PRESSED) { + if(roller->option_cnt <= 1) return; + roller->moved = 0; lv_anim_delete(get_label(obj), set_y_anim); } else if(code == LV_EVENT_PRESSING) { + if(roller->option_cnt <= 1) return; + lv_indev_t * indev = lv_indev_active(); lv_point_t p; lv_indev_get_vect(indev, &p); - transform_vect_recursive(obj, &p); if(p.y) { lv_obj_t * label = get_label(obj); - lv_obj_set_y(label, lv_obj_get_y(label) + p.y); + lv_obj_set_y(label, lv_obj_get_y_aligned(label) + p.y); roller->moved = 1; } } else if(code == LV_EVENT_RELEASED || code == LV_EVENT_PRESS_LOST) { + if(roller->option_cnt <= 1) return; + release_handler(obj); } else if(code == LV_EVENT_FOCUSED) { @@ -364,6 +405,8 @@ static void lv_roller_event(const lv_obj_class_t * class_p, lv_event_t * e) } } else if(code == LV_EVENT_KEY) { + if(roller->option_cnt <= 1) return; + uint32_t c = lv_event_get_key(e); if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) { if(roller->sel_opt_id + 1 < roller->option_cnt) { @@ -381,6 +424,8 @@ static void lv_roller_event(const lv_obj_class_t * class_p, lv_event_t * e) } } else if(code == LV_EVENT_ROTARY) { + if(roller->option_cnt <= 1) return; + int32_t r = lv_event_get_rotary_diff(e); int32_t new_id = roller->sel_opt_id + r; new_id = LV_CLAMP(0, new_id, (int32_t)roller->option_cnt - 1); @@ -457,31 +502,36 @@ static void draw_main(lv_event_t * e) get_sel_area(obj, &sel_area); lv_area_t mask_sel; bool area_ok; - area_ok = _lv_area_intersect(&mask_sel, &layer->_clip_area, &sel_area); + area_ok = lv_area_intersect(&mask_sel, &layer->_clip_area, &sel_area); if(area_ok) { lv_obj_t * label = get_label(obj); /*Get the size of the "selected text"*/ - lv_point_t res_p; - lv_text_get_size(&res_p, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, label_dsc.line_space, - lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND); + lv_point_t label_sel_size; + lv_text_get_size(&label_sel_size, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, + label_dsc.line_space, lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND); /*Move the selected label proportionally with the background label*/ int32_t roller_h = lv_obj_get_height(obj); - int32_t label_y_prop = label->coords.y1 - (roller_h / 2 + - obj->coords.y1); /*label offset from the middle line of the roller*/ - label_y_prop = (label_y_prop * 16384) / lv_obj_get_height( - label); /*Proportional position from the middle line (upscaled by << 14)*/ - - /*Apply a correction with different line heights*/ const lv_font_t * normal_label_font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); - int32_t corr = (label_dsc.font->line_height - normal_label_font->line_height) / 2; + /*label offset from the middle line of the roller*/ + int32_t label_y_prop = (label->coords.y1 + normal_label_font->line_height / 2) - (roller_h / 2 + obj->coords.y1); + + /*Proportional position from the middle line. + *Will be 0 for the first option, and 1 for the last option (upscaled by << 14)*/ + int32_t remain_h = lv_obj_get_height(label) - normal_label_font->line_height; + if(remain_h > 0) { + label_y_prop = (label_y_prop << 14) / remain_h; + } + + /*We don't want the selected label start and end exactly where the normal label is as + *a larger font won't centered on selected area.*/ + int32_t corr = label_dsc.font->line_height; /*Apply the proportional position to the selected text*/ - res_p.y -= corr; int32_t label_sel_y = roller_h / 2 + obj->coords.y1; - label_sel_y += (label_y_prop * res_p.y) >> 14; - label_sel_y -= corr; + label_sel_y += ((label_sel_size.y - corr) * label_y_prop) >> 14; + label_sel_y -= corr / 2; int32_t bwidth = lv_obj_get_style_border_width(obj, LV_PART_MAIN); int32_t pleft = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); @@ -492,7 +542,7 @@ static void draw_main(lv_event_t * e) label_sel_area.x1 = obj->coords.x1 + pleft + bwidth; label_sel_area.y1 = label_sel_y; label_sel_area.x2 = obj->coords.x2 - pright - bwidth; - label_sel_area.y2 = label_sel_area.y1 + res_p.y; + label_sel_area.y2 = label_sel_area.y1 + label_sel_size.y; label_dsc.flag |= LV_TEXT_FLAG_EXPAND; const lv_area_t clip_area_ori = layer->_clip_area; @@ -513,7 +563,6 @@ static void draw_label(lv_event_t * e) lv_draw_label_dsc_t label_draw_dsc; lv_draw_label_dsc_init(&label_draw_dsc); lv_obj_init_draw_label_dsc(roller, LV_PART_MAIN, &label_draw_dsc); - lv_layer_t * layer = lv_event_get_layer(e); /*If the roller has shadow or outline it has some ext. draw size @@ -521,7 +570,7 @@ static void draw_label(lv_event_t * e) *To solve this limit the clip area to the "plain" roller.*/ const lv_area_t clip_area_ori = layer->_clip_area; lv_area_t roller_clip_area; - if(!_lv_area_intersect(&roller_clip_area, &layer->_clip_area, &roller->coords)) return; + if(!lv_area_intersect(&roller_clip_area, &layer->_clip_area, &roller->coords)) return; layer->_clip_area = roller_clip_area; lv_area_t sel_area; @@ -532,7 +581,7 @@ static void draw_label(lv_event_t * e) clip2.y1 = label_obj->coords.y1; clip2.x2 = label_obj->coords.x2; clip2.y2 = sel_area.y1; - if(_lv_area_intersect(&clip2, &layer->_clip_area, &clip2)) { + if(lv_area_intersect(&clip2, &layer->_clip_area, &clip2)) { const lv_area_t clip_area_ori2 = layer->_clip_area; layer->_clip_area = clip2; label_draw_dsc.text = lv_label_get_text(label_obj); @@ -544,7 +593,7 @@ static void draw_label(lv_event_t * e) clip2.y1 = sel_area.y2; clip2.x2 = label_obj->coords.x2; clip2.y2 = label_obj->coords.y2; - if(_lv_area_intersect(&clip2, &layer->_clip_area, &clip2)) { + if(lv_area_intersect(&clip2, &layer->_clip_area, &clip2)) { const lv_area_t clip_area_ori2 = layer->_clip_area; layer->_clip_area = clip2; label_draw_dsc.text = lv_label_get_text(label_obj); @@ -678,7 +727,7 @@ static lv_result_t release_handler(lv_obj_t * obj) uint32_t letter_cnt = 0; for(letter_cnt = 0; letter_cnt < letter_i; letter_cnt++) { - uint32_t letter = _lv_text_encoded_next(txt, &i); + uint32_t letter = lv_text_encoded_next(txt, &i); /*Count he lines to reach the clicked letter. But ignore the last '\n' because it * still belongs to the clicked line*/ if(letter == '\n' && i_prev != letter_i) new_opt++; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.h b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.h index 960994886..e6a94b299 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.h @@ -32,27 +32,20 @@ extern "C" { * TYPEDEFS **********************/ -/** Roller mode.*/ -enum _lv_roller_mode_t { - LV_ROLLER_MODE_NORMAL, /**< Normal mode (roller ends at the end of the options).*/ - LV_ROLLER_MODE_INFINITE, /**< Infinite mode (roller can be scrolled forever).*/ +/** Roller mode. */ +typedef enum { + LV_ROLLER_MODE_NORMAL, /**< Normal mode (roller ends at the end of the options). */ + LV_ROLLER_MODE_INFINITE, /**< Infinite mode (roller can be scrolled forever). */ +} lv_roller_mode_t; + +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(ROLLER, OPTIONS, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(ROLLER, SELECTED, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(ROLLER, VISIBLE_ROW_COUNT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ROLLER_END, }; - -#ifdef DOXYGEN -typedef _lv_roller_mode_t lv_roller_mode_t; -#else -typedef uint8_t lv_roller_mode_t; -#endif /*DOXYGEN*/ - -typedef struct { - lv_obj_t obj; - uint32_t option_cnt; /**< Number of options*/ - uint32_t sel_opt_id; /**< Index of the current option*/ - uint32_t sel_opt_id_ori; /**< Store the original index on focus*/ - uint32_t inf_page_cnt; /**< Number of extra pages added to make the roller look infinite */ - lv_roller_mode_t mode : 1; - uint32_t moved : 1; -} lv_roller_t; +#endif LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_roller_class; @@ -107,7 +100,7 @@ uint32_t lv_roller_get_selected(const lv_obj_t * obj); /** * Get the current selected option as a string. - * @param obj pointer to ddlist object + * @param obj pointer to roller object * @param buf pointer to an array to store the string * @param buf_size size of `buf` in bytes. 0: to ignore it. */ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller_private.h new file mode 100644 index 000000000..5f784a3bb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_roller_private.h + * + */ + +#ifndef LV_ROLLER_PRIVATE_H +#define LV_ROLLER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_roller.h" + +#if LV_USE_ROLLER != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_roller_t { + lv_obj_t obj; + uint32_t option_cnt; /**< Number of options*/ + uint32_t sel_opt_id; /**< Index of the current option*/ + uint32_t sel_opt_id_ori; /**< Store the original index on focus*/ + uint32_t inf_page_cnt; /**< Number of extra pages added to make the roller look infinite */ + lv_roller_mode_t mode : 2; + uint32_t moved : 1; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_ROLLER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ROLLER_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.c b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.c index 1e8df7ade..fbab46018 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.c @@ -6,7 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_scale.h" +#include "lv_scale_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_SCALE != 0 #include "../../core/lv_group.h" @@ -39,6 +41,9 @@ static void lv_scale_event(const lv_obj_class_t * class_p, lv_event_t * event); static void scale_draw_main(lv_obj_t * obj, lv_event_t * event); static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event); +static void scale_draw_label(lv_obj_t * obj, lv_event_t * event, lv_draw_label_dsc_t * label_dsc, + const uint32_t major_tick_idx, const int32_t tick_value, lv_point_t * tick_point_b, const uint32_t tick_idx); +static void scale_calculate_main_compensation(lv_obj_t * obj); static void scale_get_center(const lv_obj_t * obj, lv_point_t * center, int32_t * arc_r); static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool is_major_tick, @@ -48,18 +53,20 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d static void scale_set_indicator_label_properties(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc, lv_style_t * indicator_section_style); static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_dsc, lv_style_t * section_style, - uint32_t part); + lv_part_t part); static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc, lv_style_t * section_style); /* Helpers */ static void scale_find_section_tick_idx(lv_obj_t * obj); static void scale_store_main_line_tick_width_compensation(lv_obj_t * obj, const uint32_t tick_idx, const bool is_major_tick, const int32_t major_tick_width, const int32_t minor_tick_width); static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, const bool is_major_tick, - lv_draw_label_dsc_t * label_dsc, lv_draw_line_dsc_t * major_tick_dsc, lv_draw_line_dsc_t * minor_tick_dsc, + lv_draw_line_dsc_t * major_tick_dsc, lv_draw_line_dsc_t * minor_tick_dsc, const int32_t tick_value, const uint8_t tick_idx, lv_point_t * tick_point_a); static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc, const uint16_t major_tick_idx); +static void scale_free_line_needle_points_cb(lv_event_t * e); + /********************** * STATIC VARIABLES **********************/ @@ -180,7 +187,7 @@ void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int3 int32_t scale_width, scale_height; int32_t actual_needle_length; int32_t needle_length_x, needle_length_y; - static lv_point_precise_t needle_line_points[2]; + lv_point_precise_t * needle_line_points = NULL; LV_ASSERT_OBJ(obj, MY_CLASS); lv_scale_t * scale = (lv_scale_t *)obj; @@ -224,12 +231,35 @@ void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int3 needle_length_x = (actual_needle_length * lv_trigo_cos(scale->rotation + angle)) >> LV_TRIGO_SHIFT; needle_length_y = (actual_needle_length * lv_trigo_sin(scale->rotation + angle)) >> LV_TRIGO_SHIFT; + if(lv_line_is_point_array_mutable(needle_line) && lv_line_get_point_count(needle_line) >= 2) { + needle_line_points = lv_line_get_points_mutable(needle_line); + } + + if(needle_line_points == NULL) { + uint32_t i; + uint32_t line_event_cnt = lv_obj_get_event_count(needle_line); + for(i = 0; i < line_event_cnt; i--) { + lv_event_dsc_t * dsc = lv_obj_get_event_dsc(needle_line, i); + if(lv_event_dsc_get_cb(dsc) == scale_free_line_needle_points_cb) { + needle_line_points = lv_event_dsc_get_user_data(dsc); + break; + } + } + } + + if(needle_line_points == NULL) { + needle_line_points = lv_malloc(sizeof(lv_point_precise_t) * 2); + LV_ASSERT_MALLOC(needle_line_points); + if(needle_line_points == NULL) return; + lv_obj_add_event_cb(needle_line, scale_free_line_needle_points_cb, LV_EVENT_DELETE, needle_line_points); + } + needle_line_points[0].x = scale_width / 2; needle_line_points[0].y = scale_height / 2; needle_line_points[1].x = scale_width / 2 + needle_length_x; needle_line_points[1].y = scale_height / 2 + needle_length_y; - lv_line_set_points(needle_line, needle_line_points, 2); + lv_line_set_points_mutable(needle_line, needle_line_points, 2); } void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value) @@ -282,12 +312,22 @@ void lv_scale_set_post_draw(lv_obj_t * obj, bool en) lv_obj_invalidate(obj); } +void lv_scale_set_draw_ticks_on_top(lv_obj_t * obj, bool en) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_scale_t * scale = (lv_scale_t *)obj; + + scale->draw_ticks_on_top = en; + + lv_obj_invalidate(obj); +} + lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_scale_t * scale = (lv_scale_t *)obj; - lv_scale_section_t * section = _lv_ll_ins_head(&scale->section_ll); + lv_scale_section_t * section = lv_ll_ins_head(&scale->section_ll); LV_ASSERT_MALLOC(section); if(section == NULL) return NULL; @@ -315,7 +355,7 @@ void lv_scale_section_set_range(lv_scale_section_t * section, int32_t minor_rang section->major_range = major_range; } -void lv_scale_section_set_style(lv_scale_section_t * section, uint32_t part, lv_style_t * section_part_style) +void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style) { if(NULL == section) return; @@ -396,7 +436,7 @@ static void lv_scale_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_scale_t * scale = (lv_scale_t *)obj; - _lv_ll_init(&scale->section_ll, sizeof(lv_scale_section_t)); + lv_ll_init(&scale->section_ll, sizeof(lv_scale_section_t)); scale->total_tick_count = LV_SCALE_TOTAL_TICK_COUNT_DEFAULT; scale->major_tick_every = LV_SCALE_MAJOR_TICK_EVERY_DEFAULT; @@ -409,9 +449,12 @@ static void lv_scale_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) scale->last_tick_width = 0U; scale->first_tick_width = 0U; scale->post_draw = false; + scale->draw_ticks_on_top = false; scale->custom_label_cnt = 0U; scale->txt_src = NULL; + lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + LV_TRACE_OBJ_CREATE("finished"); } @@ -423,11 +466,11 @@ static void lv_scale_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_scale_t * scale = (lv_scale_t *)obj; lv_scale_section_t * section; while(scale->section_ll.head) { - section = _lv_ll_get_head(&scale->section_ll); - _lv_ll_remove(&scale->section_ll, section); + section = lv_ll_get_head(&scale->section_ll); + lv_ll_remove(&scale->section_ll, section); lv_free(section); } - _lv_ll_clear(&scale->section_ll); + lv_ll_clear(&scale->section_ll); LV_TRACE_OBJ_CREATE("finished"); } @@ -448,15 +491,31 @@ static void lv_scale_event(const lv_obj_class_t * class_p, lv_event_t * event) if(event_code == LV_EVENT_DRAW_MAIN) { if(scale->post_draw == false) { scale_find_section_tick_idx(obj); - scale_draw_indicator(obj, event); - scale_draw_main(obj, event); + scale_calculate_main_compensation(obj); + + if(scale->draw_ticks_on_top) { + scale_draw_main(obj, event); + scale_draw_indicator(obj, event); + } + else { + scale_draw_indicator(obj, event); + scale_draw_main(obj, event); + } } } if(event_code == LV_EVENT_DRAW_POST) { if(scale->post_draw == true) { scale_find_section_tick_idx(obj); - scale_draw_indicator(obj, event); - scale_draw_main(obj, event); + scale_calculate_main_compensation(obj); + + if(scale->draw_ticks_on_top) { + scale_draw_main(obj, event); + scale_draw_indicator(obj, event); + } + else { + scale_draw_indicator(obj, event); + scale_draw_main(obj, event); + } } } else if(event_code == LV_EVENT_REFR_EXT_DRAW_SIZE) { @@ -484,6 +543,9 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) lv_draw_line_dsc_t major_tick_dsc; lv_draw_line_dsc_init(&major_tick_dsc); lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc); + if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) { + major_tick_dsc.raw_end = 0; + } /* Configure line draw descriptor for the minor tick drawing */ lv_draw_line_dsc_t minor_tick_dsc; @@ -495,86 +557,88 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) lv_draw_line_dsc_init(&main_line_dsc); lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &main_line_dsc); - const int32_t major_len = lv_obj_get_style_length(obj, LV_PART_INDICATOR); + const uint32_t total_tick_count = scale->total_tick_count; + uint32_t tick_idx = 0; + uint32_t major_tick_idx = 0; + for(tick_idx = 0; tick_idx < total_tick_count; tick_idx++) { + /* A major tick is the one which has a label in it */ + bool is_major_tick = false; + if(tick_idx % scale->major_tick_every == 0) is_major_tick = true; + if(is_major_tick) major_tick_idx++; + + const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, scale->range_min, scale->range_max); + + label_dsc.base.id1 = tick_idx; + label_dsc.base.id2 = tick_value; + + /* Overwrite label and tick properties if tick value is within section range */ + lv_scale_section_t * section; + LV_LL_READ_BACK(&scale->section_ll, section) { + if(section->minor_range <= tick_value && section->major_range >= tick_value) { + if(is_major_tick) { + scale_set_indicator_label_properties(obj, &label_dsc, section->indicator_style); + scale_set_line_properties(obj, &major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); + } + else { + scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS); + } + break; + } + else { + /* Tick is not in section, get the proper styles */ + lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc); + lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc); + lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc); + } + } + + /* The tick is represented by a line. We need two points to draw it */ + lv_point_t tick_point_a; + lv_point_t tick_point_b; + scale_get_tick_points(obj, tick_idx, is_major_tick, &tick_point_a, &tick_point_b); + + /* Setup a label if they're enabled and we're drawing a major tick */ + if(scale->label_enabled && is_major_tick) { + scale_draw_label(obj, event, &label_dsc, major_tick_idx, tick_value, &tick_point_b, tick_idx); + } + + if(is_major_tick) { + major_tick_dsc.p1 = lv_point_to_precise(&tick_point_a); + major_tick_dsc.p2 = lv_point_to_precise(&tick_point_b); + lv_draw_line(layer, &major_tick_dsc); + } + else { + minor_tick_dsc.p1 = lv_point_to_precise(&tick_point_a); + minor_tick_dsc.p2 = lv_point_to_precise(&tick_point_b); + lv_draw_line(layer, &minor_tick_dsc); + } + } +} + +static void scale_draw_label(lv_obj_t * obj, lv_event_t * event, lv_draw_label_dsc_t * label_dsc, + const uint32_t major_tick_idx, const int32_t tick_value, lv_point_t * tick_point_b, + const uint32_t tick_idx) +{ + lv_scale_t * scale = (lv_scale_t *)obj; + lv_layer_t * layer = lv_event_get_layer(event); + + /* Label text setup */ + char text_buffer[LV_SCALE_LABEL_TXT_LEN] = {0}; + lv_area_t label_coords; + + /* Check if the custom text array has element for this major tick index */ + if(scale->txt_src) { + scale_build_custom_label_text(obj, label_dsc, major_tick_idx); + } + else { /* Add label with mapped values */ + lv_snprintf(text_buffer, sizeof(text_buffer), "%" LV_PRId32, tick_value); + label_dsc->text = text_buffer; + label_dsc->text_local = 1; + } if((LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) || (LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode || LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode)) { - - uint32_t total_tick_count = scale->total_tick_count; - uint32_t tick_idx = 0; - uint32_t major_tick_idx = 0; - for(tick_idx = 0; tick_idx < total_tick_count; tick_idx++) { - /* A major tick is the one which has a label in it */ - bool is_major_tick = false; - if(tick_idx % scale->major_tick_every == 0) is_major_tick = true; - if(is_major_tick) major_tick_idx++; - - const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, scale->range_min, scale->range_max); - - /* Overwrite label and tick properties if tick value is within section range */ - lv_scale_section_t * section; - _LV_LL_READ_BACK(&scale->section_ll, section) { - if(section->minor_range <= tick_value && section->major_range >= tick_value) { - if(is_major_tick) { - scale_set_indicator_label_properties(obj, &label_dsc, section->indicator_style); - scale_set_line_properties(obj, &major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); - } - else { - scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS); - } - break; - } - else { - /* Tick is not in section, get the proper styles */ - lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc); - lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc); - lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc); - } - } - - /* The tick is represented by a line. We need two points to draw it */ - lv_point_t tick_point_a; - lv_point_t tick_point_b; - scale_get_tick_points(obj, tick_idx, is_major_tick, &tick_point_a, &tick_point_b); - - /* Setup a label if they're enabled and we're drawing a major tick */ - if(scale->label_enabled && is_major_tick) { - /* Label text setup */ - char text_buffer[LV_SCALE_LABEL_TXT_LEN] = {0}; - lv_area_t label_coords; - - /* Check if the custom text array has element for this major tick index */ - if(scale->txt_src) { - scale_build_custom_label_text(obj, &label_dsc, major_tick_idx); - } - else { /* Add label with mapped values */ - lv_snprintf(text_buffer, sizeof(text_buffer), "%" LV_PRId32, tick_value); - label_dsc.text = text_buffer; - label_dsc.text_local = 1; - } - - scale_get_label_coords(obj, &label_dsc, &tick_point_b, &label_coords); - lv_draw_label(layer, &label_dsc, &label_coords); - } - - /* Store initial and last tick widths to be used in the main line drawing */ - scale_store_main_line_tick_width_compensation(obj, tick_idx, is_major_tick, major_tick_dsc.width, minor_tick_dsc.width); - - /* Store the first and last section tick vertical/horizontal position */ - scale_store_section_line_tick_width_compensation(obj, is_major_tick, &label_dsc, &major_tick_dsc, &minor_tick_dsc, - tick_value, tick_idx, &tick_point_a); - - if(is_major_tick) { - major_tick_dsc.p1 = lv_point_to_precise(&tick_point_a); - major_tick_dsc.p2 = lv_point_to_precise(&tick_point_b); - lv_draw_line(layer, &major_tick_dsc); - } - else { - minor_tick_dsc.p1 = lv_point_to_precise(&tick_point_a); - minor_tick_dsc.p2 = lv_point_to_precise(&tick_point_b); - lv_draw_line(layer, &minor_tick_dsc); - } - } + scale_get_label_coords(obj, label_dsc, tick_point_b, &label_coords); } else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) { lv_area_t scale_area; @@ -586,100 +650,93 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) center_point.x = scale_area.x1 + radius_edge; center_point.y = scale_area.y1 + radius_edge; - /* Major tick */ - major_tick_dsc.raw_end = 0; - + const int32_t major_len = lv_obj_get_style_length(obj, LV_PART_INDICATOR); uint32_t label_gap = LV_SCALE_DEFAULT_LABEL_GAP; /* TODO: Add to style properties */ - uint32_t tick_idx = 0; - uint32_t major_tick_idx = 0; - for(tick_idx = 0; tick_idx < scale->total_tick_count; tick_idx++) { - /* A major tick is the one which has a label in it */ - bool is_major_tick = false; - if(tick_idx % scale->major_tick_every == 0) is_major_tick = true; - if(is_major_tick) major_tick_idx++; - const int32_t tick_value = lv_map(tick_idx, 0U, scale->total_tick_count - 1, scale->range_min, scale->range_max); + /* Also take into consideration the letter space of the style */ + int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1); + angle_upscale += scale->rotation * 10U; - /* Overwrite label and tick properties if tick value is within section range */ - lv_scale_section_t * section; - _LV_LL_READ_BACK(&scale->section_ll, section) { - if(section->minor_range <= tick_value && section->major_range >= tick_value) { - if(is_major_tick) { - scale_set_indicator_label_properties(obj, &label_dsc, section->indicator_style); - scale_set_line_properties(obj, &major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); - } - else { - scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS); - } - break; + uint32_t radius_text = 0; + if(LV_SCALE_MODE_ROUND_INNER == scale->mode) { + radius_text = (radius_edge - major_len) - (label_gap + label_dsc->letter_space); + } + else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode) { + radius_text = (radius_edge + major_len) + (label_gap + label_dsc->letter_space); + } + else { /* Nothing to do */ } + + lv_point_t point; + point.x = center_point.x + radius_text; + point.y = center_point.y; + lv_point_transform(&point, angle_upscale, LV_SCALE_NONE, LV_SCALE_NONE, ¢er_point, false); + scale_get_label_coords(obj, label_dsc, &point, &label_coords); + } + /* Invalid mode */ + else { + return; + } + + lv_draw_label(layer, label_dsc, &label_coords); +} + +static void scale_calculate_main_compensation(lv_obj_t * obj) +{ + lv_scale_t * scale = (lv_scale_t *)obj; + + const uint32_t total_tick_count = scale->total_tick_count; + + if(total_tick_count <= 1) return; + /* Not supported in round modes */ + if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) return; + + /* Major tick style */ + lv_draw_line_dsc_t major_tick_dsc; + lv_draw_line_dsc_init(&major_tick_dsc); + lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc); + + /* Configure line draw descriptor for the minor tick drawing */ + lv_draw_line_dsc_t minor_tick_dsc; + lv_draw_line_dsc_init(&minor_tick_dsc); + lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc); + + uint32_t tick_idx = 0; + for(tick_idx = 0; tick_idx < total_tick_count; tick_idx++) { + + const bool is_major_tick = tick_idx % scale->major_tick_every == 0; + + const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, scale->range_min, scale->range_max); + + /* Overwrite label and tick properties if tick value is within section range */ + lv_scale_section_t * section; + LV_LL_READ_BACK(&scale->section_ll, section) { + if(section->minor_range <= tick_value && section->major_range >= tick_value) { + if(is_major_tick) { + scale_set_line_properties(obj, &major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); } else { - /* Tick is not in section, get the proper styles */ - lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc); - lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc); - lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc); + scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS); } - } - - /* The tick is represented by a line. We need two points to draw it */ - lv_point_t tick_point_a; - lv_point_t tick_point_b; - scale_get_tick_points(obj, tick_idx, is_major_tick, &tick_point_a, &tick_point_b); - - /* Setup a label if they're enabled and we're drawing a major tick */ - if(scale->label_enabled && is_major_tick) { - /* Label text setup */ - char text_buffer[LV_SCALE_LABEL_TXT_LEN] = {0}; - lv_area_t label_coords; - - /* Check if the custom text array has element for this major tick index */ - if(scale->txt_src) { - scale_build_custom_label_text(obj, &label_dsc, major_tick_idx); - } - else { /* Add label with mapped values */ - lv_snprintf(text_buffer, sizeof(text_buffer), "%" LV_PRId32, tick_value); - label_dsc.text = text_buffer; - label_dsc.text_local = 1; - } - - /* Also take into consideration the letter space of the style */ - int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1); - angle_upscale += scale->rotation * 10U; - - uint32_t radius_text = 0; - if(LV_SCALE_MODE_ROUND_INNER == scale->mode) { - radius_text = (radius_edge - major_len) - (label_gap + label_dsc.letter_space); - } - else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode) { - radius_text = (radius_edge + major_len) + (label_gap + label_dsc.letter_space); - } - else { /* Nothing to do */ } - - lv_point_t point; - point.x = center_point.x + radius_text; - point.y = center_point.y; - lv_point_transform(&point, angle_upscale, LV_SCALE_NONE, LV_SCALE_NONE, ¢er_point, false); - scale_get_label_coords(obj, &label_dsc, &point, &label_coords); - - lv_draw_label(layer, &label_dsc, &label_coords); - } - - /* Store initial and last tick widths to be used in the main line drawing */ - scale_store_main_line_tick_width_compensation(obj, tick_idx, is_major_tick, major_tick_dsc.width, minor_tick_dsc.width); - - if(is_major_tick) { - major_tick_dsc.p1 = lv_point_to_precise(&tick_point_a); - major_tick_dsc.p2 = lv_point_to_precise(&tick_point_b); - lv_draw_line(layer, &major_tick_dsc); + break; } else { - minor_tick_dsc.p1 = lv_point_to_precise(&tick_point_a); - minor_tick_dsc.p2 = lv_point_to_precise(&tick_point_b); - lv_draw_line(layer, &minor_tick_dsc); + /* Tick is not in section, get the proper styles */ + lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc); + lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc); } } + + /* The tick is represented by a line. We need two points to draw it */ + lv_point_t tick_point_a; + lv_point_t tick_point_b; + scale_get_tick_points(obj, tick_idx, is_major_tick, &tick_point_a, &tick_point_b); + + /* Store initial and last tick widths to be used in the main line drawing */ + scale_store_main_line_tick_width_compensation(obj, tick_idx, is_major_tick, major_tick_dsc.width, minor_tick_dsc.width); + /* Store the first and last section tick vertical/horizontal position */ + scale_store_section_line_tick_width_compensation(obj, is_major_tick, &major_tick_dsc, &minor_tick_dsc, + tick_value, tick_idx, &tick_point_a); } - else { /* Nothing to do */ } } static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) @@ -756,46 +813,45 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) lv_draw_line(layer, &line_dsc); lv_scale_section_t * section; - _LV_LL_READ_BACK(&scale->section_ll, section) { - lv_draw_line_dsc_t main_line_section_dsc; - lv_draw_line_dsc_init(&main_line_section_dsc); - lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &main_line_section_dsc); + LV_LL_READ_BACK(&scale->section_ll, section) { + lv_draw_line_dsc_t section_line_dsc; + lv_draw_line_dsc_init(§ion_line_dsc); + lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, §ion_line_dsc); /* Calculate the points of the section line */ - lv_point_t main_point_a; - lv_point_t main_point_b; + lv_point_t section_point_a; + lv_point_t section_point_b; + + const int32_t first_tick_width_halved = (int32_t)(section->first_tick_in_section_width / 2U); + const int32_t last_tick_width_halved = (int32_t)(section->last_tick_in_section_width / 2U); /* Calculate the position of the section based on the ticks (first and last) index */ if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) { /* Calculate position of the first tick in the section */ - main_point_a.x = main_line_point_a.x; - int32_t tmp = (int32_t)(section->first_tick_in_section_width / 2U); - main_point_a.y = section->first_tick_in_section.y + tmp; + section_point_a.x = main_line_point_a.x; + section_point_a.y = section->first_tick_in_section.y + first_tick_width_halved; /* Calculate position of the last tick in the section */ - main_point_b.x = main_line_point_a.x; - tmp = (int32_t)(section->last_tick_in_section_width / 2U); - main_point_b.y = section->last_tick_in_section.y - tmp; + section_point_b.x = main_line_point_a.x; + section_point_b.y = section->last_tick_in_section.y - last_tick_width_halved; } else { /* Calculate position of the first tick in the section */ - int32_t tmp = (int32_t)(section->first_tick_in_section_width / 2U); - main_point_a.x = section->first_tick_in_section.x - tmp; - main_point_a.y = main_line_point_a.y; + section_point_a.x = section->first_tick_in_section.x - first_tick_width_halved; + section_point_a.y = main_line_point_a.y; /* Calculate position of the last tick in the section */ - tmp = (int32_t)(section->last_tick_in_section_width / 2U); - main_point_b.x = section->last_tick_in_section.x + tmp; - main_point_b.y = main_line_point_a.y; + section_point_b.x = section->last_tick_in_section.x + last_tick_width_halved; + section_point_b.y = main_line_point_a.y; } - scale_set_line_properties(obj, &main_line_section_dsc, section->main_style, LV_PART_MAIN); + scale_set_line_properties(obj, §ion_line_dsc, section->main_style, LV_PART_MAIN); - main_line_section_dsc.p1.x = main_point_a.x; - main_line_section_dsc.p1.y = main_point_a.y; - main_line_section_dsc.p2.x = main_point_b.x; - main_line_section_dsc.p2.y = main_point_b.y; - lv_draw_line(layer, &main_line_section_dsc); + section_line_dsc.p1.x = section_point_a.x; + section_line_dsc.p1.y = section_point_a.y; + section_line_dsc.p2.x = section_point_b.x; + section_line_dsc.p2.y = section_point_b.y; + lv_draw_line(layer, §ion_line_dsc); } } else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) { @@ -822,7 +878,7 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) lv_draw_arc(layer, &arc_dsc); lv_scale_section_t * section; - _LV_LL_READ_BACK(&scale->section_ll, section) { + LV_LL_READ_BACK(&scale->section_ll, section) { lv_draw_arc_dsc_t main_arc_section_dsc; lv_draw_arc_dsc_init(&main_arc_section_dsc); lv_obj_init_draw_arc_dsc(obj, LV_PART_MAIN, &main_arc_section_dsc); @@ -1103,15 +1159,15 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d * @param part line part, example: LV_PART_INDICATOR, LV_PART_ITEMS, LV_PART_MAIN */ static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_dsc, lv_style_t * section_style, - uint32_t part) + lv_part_t part) { if(section_style) { lv_style_value_t value; - lv_result_t res; + lv_style_res_t res; /* Line width */ res = lv_style_get_prop(section_style, LV_STYLE_LINE_WIDTH, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { line_dsc->width = (int32_t)value.num; } else { @@ -1120,7 +1176,7 @@ static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_ /* Line color */ res = lv_style_get_prop(section_style, LV_STYLE_LINE_COLOR, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { line_dsc->color = value.color; } else { @@ -1129,7 +1185,7 @@ static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_ /* Line opa */ res = lv_style_get_prop(section_style, LV_STYLE_LINE_OPA, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { line_dsc->opa = (lv_opa_t)value.num; } else { @@ -1156,11 +1212,11 @@ static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc { if(section_style) { lv_style_value_t value; - lv_result_t res; + lv_style_res_t res; /* Line width */ res = lv_style_get_prop(section_style, LV_STYLE_ARC_WIDTH, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { arc_dsc->width = (int32_t)value.num; } else { @@ -1169,7 +1225,7 @@ static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc /* Line color */ res = lv_style_get_prop(section_style, LV_STYLE_ARC_COLOR, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { arc_dsc->color = value.color; } else { @@ -1178,7 +1234,7 @@ static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc /* Line opa */ res = lv_style_get_prop(section_style, LV_STYLE_ARC_OPA, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { arc_dsc->opa = (lv_opa_t)value.num; } else { @@ -1206,11 +1262,11 @@ static void scale_set_indicator_label_properties(lv_obj_t * obj, lv_draw_label_d { if(indicator_section_style) { lv_style_value_t value; - lv_result_t res; + lv_style_res_t res; /* Text color */ res = lv_style_get_prop(indicator_section_style, LV_STYLE_TEXT_COLOR, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { label_dsc->color = value.color; } else { @@ -1219,7 +1275,7 @@ static void scale_set_indicator_label_properties(lv_obj_t * obj, lv_draw_label_d /* Text opa */ res = lv_style_get_prop(indicator_section_style, LV_STYLE_TEXT_OPA, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { label_dsc->opa = (lv_opa_t)value.num; } else { @@ -1228,7 +1284,7 @@ static void scale_set_indicator_label_properties(lv_obj_t * obj, lv_draw_label_d /* Text letter space */ res = lv_style_get_prop(indicator_section_style, LV_STYLE_TEXT_LETTER_SPACE, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { label_dsc->letter_space = (int32_t)value.num; } else { @@ -1237,7 +1293,7 @@ static void scale_set_indicator_label_properties(lv_obj_t * obj, lv_draw_label_d /* Text font */ res = lv_style_get_prop(indicator_section_style, LV_STYLE_TEXT_FONT, &value); - if(res == LV_RESULT_OK) { + if(res == LV_STYLE_RES_FOUND) { label_dsc->font = (const lv_font_t *)value.ptr; } else { @@ -1270,7 +1326,7 @@ static void scale_find_section_tick_idx(lv_obj_t * obj) const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, min_out, max_out); lv_scale_section_t * section; - _LV_LL_READ_BACK(&scale->section_ll, section) { + LV_LL_READ_BACK(&scale->section_ll, section) { if(section->minor_range <= tick_value && section->major_range >= tick_value) { if(LV_SCALE_TICK_IDX_DEFAULT_ID == section->first_tick_idx_in_section) { section->first_tick_idx_in_section = tick_idx; @@ -1305,7 +1361,7 @@ static void scale_store_main_line_tick_width_compensation(lv_obj_t * obj, const const bool is_last_tick = scale->total_tick_count == tick_idx; const int32_t tick_width = is_major_tick ? major_tick_width : minor_tick_width; - /* Exit early if tick_idx is not the first nor last tick on the main line */ + /* Exit early if tick_idx is neither the first nor last tick on the main line */ if(((!is_last_tick) && (!is_first_tick)) /* Exit early if scale mode is round. It doesn't support main line compensation */ || ((LV_SCALE_MODE_ROUND_INNER == scale->mode) || (LV_SCALE_MODE_ROUND_OUTER == scale->mode))) { @@ -1370,7 +1426,6 @@ static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * * * @param obj pointer to a scale object * @param is_major_tick Indicates if tick is major or not - * @param label_dsc pointer to the label descriptor * @param major_tick_dsc pointer to the major_tick_dsc * @param minor_tick_dsc pointer to the minor_tick_dsc * @param tick_value Current tick value, used to know if tick_idx belongs to a section or not @@ -1378,16 +1433,15 @@ static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * * @param tick_point_a Pointer to tick point a */ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, const bool is_major_tick, - lv_draw_label_dsc_t * label_dsc, lv_draw_line_dsc_t * major_tick_dsc, lv_draw_line_dsc_t * minor_tick_dsc, + lv_draw_line_dsc_t * major_tick_dsc, lv_draw_line_dsc_t * minor_tick_dsc, const int32_t tick_value, const uint8_t tick_idx, lv_point_t * tick_point_a) { lv_scale_t * scale = (lv_scale_t *) obj; lv_scale_section_t * section; - _LV_LL_READ_BACK(&scale->section_ll, section) { + LV_LL_READ_BACK(&scale->section_ll, section) { if(section->minor_range <= tick_value && section->major_range >= tick_value) { if(is_major_tick) { - scale_set_indicator_label_properties(obj, label_dsc, section->indicator_style); scale_set_line_properties(obj, major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); } else { @@ -1441,4 +1495,10 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con } } +static void scale_free_line_needle_points_cb(lv_event_t * e) +{ + lv_point_precise_t * needle_line_points = lv_event_get_user_data(e); + lv_free(needle_line_points); +} + #endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.h b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.h index 8ac377eb1..ad1bd2b45 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.h @@ -44,52 +44,15 @@ LV_EXPORT_CONST_INT(LV_SCALE_LABEL_ENABLED_DEFAULT); /** * Scale mode */ -enum { +typedef enum { LV_SCALE_MODE_HORIZONTAL_TOP = 0x00U, LV_SCALE_MODE_HORIZONTAL_BOTTOM = 0x01U, LV_SCALE_MODE_VERTICAL_LEFT = 0x02U, LV_SCALE_MODE_VERTICAL_RIGHT = 0x04U, LV_SCALE_MODE_ROUND_INNER = 0x08U, LV_SCALE_MODE_ROUND_OUTER = 0x10U, - _LV_SCALE_MODE_LAST -}; -typedef uint32_t lv_scale_mode_t; - -typedef struct { - lv_style_t * main_style; - lv_style_t * indicator_style; - lv_style_t * items_style; - int32_t minor_range; - int32_t major_range; - uint32_t first_tick_idx_in_section; - uint32_t last_tick_idx_in_section; - uint32_t first_tick_idx_is_major; - uint32_t last_tick_idx_is_major; - int32_t first_tick_in_section_width; - int32_t last_tick_in_section_width; - lv_point_t first_tick_in_section; - lv_point_t last_tick_in_section; -} lv_scale_section_t; - -typedef struct { - lv_obj_t obj; - lv_ll_t section_ll; /**< Linked list for the sections (stores lv_scale_section_t)*/ - const char ** txt_src; - lv_scale_mode_t mode; - int32_t range_min; - int32_t range_max; - uint32_t total_tick_count : 15; - uint32_t major_tick_every : 15; - uint32_t label_enabled : 1; - uint32_t post_draw : 1; - /* Round scale */ - uint32_t angle_range; - int32_t rotation; - /* Private properties */ - int32_t custom_label_cnt; - int32_t last_tick_width; - int32_t first_tick_width; -} lv_scale_t; + LV_SCALE_MODE_LAST +} lv_scale_mode_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_scale_class; @@ -113,7 +76,7 @@ lv_obj_t * lv_scale_create(lv_obj_t * parent); *====================*/ /** - * Set scale mode. See @ref lv_scale_mode_t + * Set scale mode. See lv_scale_mode_t * @param obj pointer the scale object * @param mode the new scale mode */ @@ -165,7 +128,9 @@ void lv_scale_set_rotation(lv_obj_t * obj, int32_t rotation); /** * Point the needle to the corresponding value through the line * @param obj pointer to a scale object - * @param needle_line needle_line of the scale + * @param needle_line needle_line of the scale. The line points will be allocated and + * managed by the scale unless the line point array was previously set + * using `lv_line_set_points_mutable`. * @param needle_length length of the needle * needle_length>0 needle_length=needle_length; * needle_length<0 needle_length=radius-|needle_length|; @@ -197,6 +162,13 @@ void lv_scale_set_text_src(lv_obj_t * obj, const char * txt_src[]); */ void lv_scale_set_post_draw(lv_obj_t * obj, bool en); +/** + * Draw the scale ticks on top of all parts + * @param obj pointer to a scale object + * @param en true: enable draw ticks on top of all parts + */ +void lv_scale_set_draw_ticks_on_top(lv_obj_t * obj, bool en); + /** * Add a section to the given scale * @param obj pointer to a scale object @@ -218,14 +190,14 @@ void lv_scale_section_set_range(lv_scale_section_t * section, int32_t minor_rang * @param part the part for the section, e.g. LV_PART_INDICATOR * @param section_part_style Pointer to the section part style */ -void lv_scale_section_set_style(lv_scale_section_t * section, uint32_t part, lv_style_t * section_part_style); +void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style); /*===================== * Getter functions *====================*/ /** - * Get scale mode. See @ref lv_scale_mode_t + * Get scale mode. See lv_scale_mode_t * @param obj pointer the scale object * @return Scale mode */ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale_private.h new file mode 100644 index 000000000..c755c1774 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale_private.h @@ -0,0 +1,82 @@ +/** + * @file lv_scale_private.h + * + */ + +#ifndef LV_SCALE_PRIVATE_H +#define LV_SCALE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_scale.h" + +#if LV_USE_SCALE != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_scale_section_t { + lv_style_t * main_style; + lv_style_t * indicator_style; + lv_style_t * items_style; + int32_t minor_range; + int32_t major_range; + uint32_t first_tick_idx_in_section; + uint32_t last_tick_idx_in_section; + uint32_t first_tick_idx_is_major; + uint32_t last_tick_idx_is_major; + int32_t first_tick_in_section_width; + int32_t last_tick_in_section_width; + lv_point_t first_tick_in_section; + lv_point_t last_tick_in_section; +}; + +struct lv_scale_t { + lv_obj_t obj; + lv_ll_t section_ll; /**< Linked list for the sections (stores lv_scale_section_t)*/ + const char ** txt_src; + lv_scale_mode_t mode; + int32_t range_min; + int32_t range_max; + uint32_t total_tick_count : 15; + uint32_t major_tick_every : 15; + uint32_t label_enabled : 1; + uint32_t post_draw : 1; + uint32_t draw_ticks_on_top : 1; + /* Round scale */ + uint32_t angle_range; + int32_t rotation; + /* Private properties */ + int32_t custom_label_cnt; + int32_t last_tick_width; + int32_t first_tick_width; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SCALE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SCALE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.c b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.c index 2cce03ab2..e58597c88 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.c @@ -6,7 +6,11 @@ /********************* * INCLUDES *********************/ -#include "lv_slider.h" +#include "lv_slider_private.h" +#include "../../misc/lv_area_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_event_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_SLIDER != 0 #include "../../misc/lv_assert.h" @@ -79,6 +83,59 @@ bool lv_slider_is_dragged(const lv_obj_t * obj) return slider->dragging; } +void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) +{ + lv_bar_set_value(obj, value, anim); +} + +void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) +{ + lv_bar_set_start_value(obj, value, anim); +} + +void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max) +{ + lv_bar_set_range(obj, min, max); +} + +void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode) +{ + lv_bar_set_mode(obj, (lv_bar_mode_t)mode); +} + +int32_t lv_slider_get_value(const lv_obj_t * obj) +{ + return lv_bar_get_value(obj); +} + +int32_t lv_slider_get_left_value(const lv_obj_t * obj) +{ + return lv_bar_get_start_value(obj); +} + +int32_t lv_slider_get_min_value(const lv_obj_t * obj) +{ + return lv_bar_get_min_value(obj); +} + +int32_t lv_slider_get_max_value(const lv_obj_t * obj) +{ + return lv_bar_get_max_value(obj); +} + +lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider) +{ + lv_bar_mode_t mode = lv_bar_get_mode(slider); + if(mode == LV_BAR_MODE_SYMMETRICAL) return LV_SLIDER_MODE_SYMMETRICAL; + else if(mode == LV_BAR_MODE_RANGE) return LV_SLIDER_MODE_RANGE; + else return LV_SLIDER_MODE_NORMAL; +} + +bool lv_slider_is_symmetrical(lv_obj_t * obj) +{ + return lv_bar_is_symmetrical(obj); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -123,13 +180,13 @@ static void lv_slider_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_area_t a; lv_area_copy(&a, &slider->right_knob_area); lv_area_increase(&a, ext_click_area, ext_click_area); - info->res = _lv_area_is_point_on(&a, info->point, 0); + info->res = lv_area_is_point_on(&a, info->point, 0); /*There's still a chance that there is a hit if there is another knob*/ if((info->res == false) && (type == LV_SLIDER_MODE_RANGE)) { lv_area_copy(&a, &slider->left_knob_area); lv_area_increase(&a, ext_click_area, ext_click_area); - info->res = _lv_area_is_point_on(&a, info->point, 0); + info->res = lv_area_is_point_on(&a, info->point, 0); } } else if(code == LV_EVENT_PRESSED) { diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.h b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.h index 6c83c14f0..5f08a5c58 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.h @@ -29,27 +29,11 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum _lv_slider_mode_t { +typedef enum { LV_SLIDER_MODE_NORMAL = LV_BAR_MODE_NORMAL, LV_SLIDER_MODE_SYMMETRICAL = LV_BAR_MODE_SYMMETRICAL, LV_SLIDER_MODE_RANGE = LV_BAR_MODE_RANGE -}; - -#ifdef DOXYGEN -typedef _lv_slider_mode_t lv_slider_mode_t; -#else -typedef uint8_t lv_slider_mode_t; -#endif /*DOXYGEN*/ - -typedef struct { - lv_bar_t bar; /*Add the ancestor's type first*/ - lv_area_t left_knob_area; - lv_area_t right_knob_area; - lv_point_t pressed_point; - int32_t * value_to_set; /*Which bar value to set*/ - uint8_t dragging : 1; /*1: the slider is being dragged*/ - uint8_t left_knob_focus : 1; /*1: with encoder now the right knob can be adjusted*/ -} lv_slider_t; +} lv_slider_mode_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_slider_class; @@ -74,10 +58,7 @@ lv_obj_t * lv_slider_create(lv_obj_t * parent); * @param value the new value * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -static inline void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) -{ - lv_bar_set_value(obj, value, anim); -} +void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); /** * Set a new value for the left knob of a slider @@ -85,10 +66,7 @@ static inline void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_en * @param value new value * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -static inline void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) -{ - lv_bar_set_start_value(obj, value, anim); -} +void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); /** * Set minimum and the maximum values of a bar @@ -96,20 +74,14 @@ static inline void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_an * @param min minimum value * @param max maximum value */ -static inline void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max) -{ - lv_bar_set_range(obj, min, max); -} +void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max); /** * Set the mode of slider. * @param obj pointer to a slider object * @param mode the mode of the slider. See ::lv_slider_mode_t */ -static inline void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode) -{ - lv_bar_set_mode(obj, (lv_bar_mode_t)mode); -} +void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode); /*===================== * Getter functions @@ -120,40 +92,28 @@ static inline void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode) * @param obj pointer to a slider object * @return the value of the main knob of the slider */ -static inline int32_t lv_slider_get_value(const lv_obj_t * obj) -{ - return lv_bar_get_value(obj); -} +int32_t lv_slider_get_value(const lv_obj_t * obj); /** * Get the value of the left knob of a slider * @param obj pointer to a slider object * @return the value of the left knob of the slider */ -static inline int32_t lv_slider_get_left_value(const lv_obj_t * obj) -{ - return lv_bar_get_start_value(obj); -} +int32_t lv_slider_get_left_value(const lv_obj_t * obj); /** * Get the minimum value of a slider * @param obj pointer to a slider object * @return the minimum value of the slider */ -static inline int32_t lv_slider_get_min_value(const lv_obj_t * obj) -{ - return lv_bar_get_min_value(obj); -} +int32_t lv_slider_get_min_value(const lv_obj_t * obj); /** * Get the maximum value of a slider * @param obj pointer to a slider object * @return the maximum value of the slider */ -static inline int32_t lv_slider_get_max_value(const lv_obj_t * obj) -{ - return lv_bar_get_max_value(obj); -} +int32_t lv_slider_get_max_value(const lv_obj_t * obj); /** * Give the slider is being dragged or not @@ -167,23 +127,14 @@ bool lv_slider_is_dragged(const lv_obj_t * obj); * @param slider pointer to a slider object * @return see ::lv_slider_mode_t */ -static inline lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider) -{ - lv_bar_mode_t mode = lv_bar_get_mode(slider); - if(mode == LV_BAR_MODE_SYMMETRICAL) return LV_SLIDER_MODE_SYMMETRICAL; - else if(mode == LV_BAR_MODE_RANGE) return LV_SLIDER_MODE_RANGE; - else return LV_SLIDER_MODE_NORMAL; -} +lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider); /** * Give the slider is in symmetrical mode or not * @param obj pointer to slider object * @return true: in symmetrical mode false : not in */ -static inline bool lv_slider_is_symmetrical(lv_obj_t * obj) -{ - return lv_bar_is_symmetrical(obj); -} +bool lv_slider_is_symmetrical(lv_obj_t * obj); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider_private.h new file mode 100644 index 000000000..a1eab2f5b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_slider_private.h + * + */ + +#ifndef LV_SLIDER_PRIVATE_H +#define LV_SLIDER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../bar/lv_bar_private.h" +#include "lv_slider.h" + +#if LV_USE_SLIDER != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_slider_t { + lv_bar_t bar; /**< Add the ancestor's type first */ + lv_area_t left_knob_area; + lv_area_t right_knob_area; + lv_point_t pressed_point; + int32_t * value_to_set; /**< Which bar value to set */ + uint8_t dragging : 1; /**< 1: the slider is being dragged */ + uint8_t left_knob_focus : 1; /**< 1: with encoder now the right knob can be adjusted */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SLIDER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SLIDER_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c index 95dd03094..a6a287e94 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c @@ -6,11 +6,15 @@ /********************* * INCLUDES *********************/ -#include "lv_span.h" +#include "lv_span_private.h" +#include "../../misc/lv_area_private.h" +#include "../../draw/lv_draw_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_SPAN != 0 #include "../../misc/lv_assert.h" +#include "../../misc/lv_text_private.h" #include "../../core/lv_global.h" /********************* @@ -50,7 +54,7 @@ static const lv_font_t * lv_span_get_style_text_font(lv_obj_t * par, lv_span_t * static int32_t lv_span_get_style_text_letter_space(lv_obj_t * par, lv_span_t * span); static lv_color_t lv_span_get_style_text_color(lv_obj_t * par, lv_span_t * span); static lv_opa_t lv_span_get_style_text_opa(lv_obj_t * par, lv_span_t * span); -static lv_opa_t lv_span_get_style_text_blend_mode(lv_obj_t * par, lv_span_t * span); +static lv_blend_mode_t lv_span_get_style_text_blend_mode(lv_obj_t * par, lv_span_t * span); static int32_t lv_span_get_style_text_decor(lv_obj_t * par, lv_span_t * span); static inline void span_text_check(const char ** text); @@ -116,7 +120,7 @@ lv_span_t * lv_spangroup_new_span(lv_obj_t * obj) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - lv_span_t * span = _lv_ll_ins_tail(&spans->child_ll); + lv_span_t * span = lv_ll_ins_tail(&spans->child_ll); LV_ASSERT_MALLOC(span); lv_style_init(&span->style); @@ -138,9 +142,9 @@ void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; lv_span_t * cur_span; - _LV_LL_READ(&spans->child_ll, cur_span) { + LV_LL_READ(&spans->child_ll, cur_span) { if(cur_span == span) { - _lv_ll_remove(&spans->child_ll, cur_span); + lv_ll_remove(&spans->child_ll, cur_span); if(cur_span->txt && cur_span->static_flag == 0) { lv_free(cur_span->txt); cur_span->txt = NULL; @@ -210,7 +214,7 @@ void lv_spangroup_set_overflow(lv_obj_t * obj, lv_span_overflow_t overflow) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; if(spans->overflow == overflow) return; - if(overflow >= _LV_SPAN_OVERFLOW_LAST) return; + if(overflow >= LV_SPAN_OVERFLOW_LAST) return; spans->overflow = overflow; lv_obj_invalidate(obj); } @@ -231,7 +235,7 @@ void lv_spangroup_set_mode(lv_obj_t * obj, lv_span_mode_t mode) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - if(mode >= _LV_SPAN_MODE_LAST) return; + if(mode >= LV_SPAN_MODE_LAST) return; spans->mode = mode; lv_spangroup_refr_mode(obj); @@ -249,6 +253,11 @@ void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines) * Getter functions *====================*/ +lv_style_t * lv_span_get_style(lv_span_t * span) +{ + return &span->style; +} + lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id) { if(obj == NULL) { @@ -274,11 +283,11 @@ lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id) return (lv_span_t *) cur_node; } if(traverse_forwards) { - cur_node = (lv_ll_node_t *) _lv_ll_get_next(linked_list, cur_node); + cur_node = (lv_ll_node_t *) lv_ll_get_next(linked_list, cur_node); cur_idx++; } else { - cur_node = (lv_ll_node_t *) _lv_ll_get_prev(linked_list, cur_node); + cur_node = (lv_ll_node_t *) lv_ll_get_prev(linked_list, cur_node); cur_idx--; } } @@ -296,7 +305,7 @@ uint32_t lv_spangroup_get_span_count(const lv_obj_t * obj) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - return _lv_ll_get_len(&(spans->child_ll)); + return lv_ll_get_len(&(spans->child_ll)); } lv_text_align_t lv_spangroup_get_align(lv_obj_t * obj) @@ -373,7 +382,7 @@ int32_t lv_spangroup_get_max_line_height(lv_obj_t * obj) int32_t max_line_h = 0; lv_span_t * cur_span; - _LV_LL_READ(&spans->child_ll, cur_span) { + LV_LL_READ(&spans->child_ll, cur_span) { const lv_font_t * font = lv_span_get_style_text_font(obj, cur_span); int32_t line_h = lv_font_get_line_height(font); if(line_h > max_line_h) { @@ -389,14 +398,14 @@ uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - if(_lv_ll_get_head(&spans->child_ll) == NULL) { + if(lv_ll_get_head(&spans->child_ll) == NULL) { return 0; } uint32_t width = LV_COORD_IS_PCT(spans->indent) ? 0 : spans->indent; lv_span_t * cur_span; int32_t letter_space = 0; - _LV_LL_READ(&spans->child_ll, cur_span) { + LV_LL_READ(&spans->child_ll, cur_span) { const lv_font_t * font = lv_span_get_style_text_font(obj, cur_span); letter_space = lv_span_get_style_text_letter_space(obj, cur_span); uint32_t j = 0; @@ -406,8 +415,8 @@ uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width) if(max_width > 0 && width >= max_width) { return max_width; } - uint32_t letter = _lv_text_encoded_next(cur_txt, &j); - uint32_t letter_next = _lv_text_encoded_next(&cur_txt[j], NULL); + uint32_t letter = lv_text_encoded_next(cur_txt, &j); + uint32_t letter_next = lv_text_encoded_next(&cur_txt[j], NULL); uint32_t letter_w = lv_font_get_glyph_width(font, letter, letter_next); width = width + letter_w + letter_space; } @@ -420,7 +429,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - if(_lv_ll_get_head(&spans->child_ll) == NULL || width <= 0) { + if(lv_ll_get_head(&spans->child_ll) == NULL || width <= 0) { return 0; } @@ -435,12 +444,12 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) lv_point_t txt_pos; lv_point_set(&txt_pos, 0, indent); /* first line need add indent */ - lv_span_t * cur_span = _lv_ll_get_head(&spans->child_ll); + lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll); const char * cur_txt = cur_span->txt; span_text_check(&cur_txt); uint32_t cur_txt_ofs = 0; lv_snippet_t snippet; /* use to save cur_span info and push it to stack */ - memset(&snippet, 0, sizeof(snippet)); + lv_memset(&snippet, 0, sizeof(snippet)); int32_t line_cnt = 0; int32_t lines = spans->lines < 0 ? INT32_MAX : spans->lines; @@ -453,7 +462,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) while(1) { /* switch to the next span when current is end */ if(cur_txt[cur_txt_ofs] == '\0') { - cur_span = _lv_ll_get_next(&spans->child_ll, cur_span); + cur_span = lv_ll_get_next(&spans->child_ll, cur_span); if(cur_span == NULL) break; cur_txt = cur_span->txt; span_text_check(&cur_txt); @@ -478,16 +487,20 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) /* break word deal width */ if(isfill && next_ofs > 0 && snippet_cnt > 0) { - if(max_w < use_width) { + int32_t drawn_width = use_width; + if(lv_ll_get_next(&spans->child_ll, cur_span) == NULL) { + drawn_width -= snippet.letter_space; + } + if(max_w < drawn_width) { break; } uint32_t tmp_ofs = next_ofs; - uint32_t letter = _lv_text_encoded_prev(&cur_txt[cur_txt_ofs], &tmp_ofs); - if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_text_is_break_char(letter))) { - tmp_ofs = 0; - letter = _lv_text_encoded_next(&cur_txt[cur_txt_ofs + next_ofs], &tmp_ofs); - if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_text_is_break_char(letter))) { + uint32_t letter = lv_text_encoded_prev(&cur_txt[cur_txt_ofs], &tmp_ofs); + uint32_t letter_next = lv_text_encoded_next(&cur_txt[cur_txt_ofs + next_ofs], NULL); + if(!(letter == '\0' || letter == '\n' || letter == '\r' || lv_text_is_break_char(letter) || + lv_text_is_a_word(letter) || lv_text_is_a_word(letter_next))) { + if(!(letter_next == '\0' || letter_next == '\n' || letter_next == '\r' || lv_text_is_break_char(letter_next))) { break; } } @@ -501,7 +514,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) max_line_h = snippet.line_h; } snippet_cnt ++; - max_w = max_w - use_width - snippet.letter_space; + max_w = max_w - use_width; if(isfill || max_w <= 0) { break; } @@ -529,7 +542,7 @@ static void lv_spangroup_constructor(const lv_obj_class_t * class_p, lv_obj_t * { LV_UNUSED(class_p); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - _lv_ll_init(&spans->child_ll, sizeof(lv_span_t)); + lv_ll_init(&spans->child_ll, sizeof(lv_span_t)); spans->indent = 0; spans->lines = -1; spans->mode = LV_SPAN_MODE_EXPAND; @@ -543,16 +556,16 @@ static void lv_spangroup_destructor(const lv_obj_class_t * class_p, lv_obj_t * o { LV_UNUSED(class_p); lv_spangroup_t * spans = (lv_spangroup_t *)obj; - lv_span_t * cur_span = _lv_ll_get_head(&spans->child_ll); + lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll); while(cur_span) { - _lv_ll_remove(&spans->child_ll, cur_span); + lv_ll_remove(&spans->child_ll, cur_span); if(cur_span->txt && cur_span->static_flag == 0) { lv_free(cur_span->txt); cur_span->txt = NULL; } lv_style_reset(&cur_span->style); lv_free(cur_span); - cur_span = _lv_ll_get_head(&spans->child_ll); + cur_span = lv_ll_get_head(&spans->child_ll); } } @@ -641,10 +654,10 @@ static bool lv_text_get_snippet(const char * txt, const lv_font_t * font, real_max_width++; #endif - uint32_t ofs = _lv_text_get_next_line(txt, font, letter_space, real_max_width, use_width, flag); + uint32_t ofs = lv_text_get_next_line(txt, font, letter_space, real_max_width, use_width, flag); *end_ofs = ofs; - if(txt[ofs] == '\0' && *use_width < max_width) { + if(txt[ofs] == '\0' && *use_width < max_width && !(ofs && (txt[ofs - 1] == '\n' || txt[ofs - 1] == '\r'))) { return false; } else { @@ -656,7 +669,7 @@ static void lv_snippet_push(lv_snippet_t * item) { struct _snippet_stack * stack_p = snippet_stack; if(stack_p->index < LV_SPAN_SNIPPET_STACK_SIZE) { - memcpy(&stack_p->stack[stack_p->index], item, sizeof(lv_snippet_t)); + lv_memcpy(&stack_p->stack[stack_p->index], item, sizeof(lv_snippet_t)); stack_p->index++; } else { @@ -683,8 +696,8 @@ static const lv_font_t * lv_span_get_style_text_font(lv_obj_t * par, lv_span_t * { const lv_font_t * font; lv_style_value_t value; - lv_result_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_FONT, &value); - if(res != LV_RESULT_OK) { + lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_FONT, &value); + if(res != LV_STYLE_RES_FOUND) { font = lv_obj_get_style_text_font(par, LV_PART_MAIN); } else { @@ -697,8 +710,8 @@ static int32_t lv_span_get_style_text_letter_space(lv_obj_t * par, lv_span_t * s { int32_t letter_space; lv_style_value_t value; - lv_result_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_LETTER_SPACE, &value); - if(res != LV_RESULT_OK) { + lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_LETTER_SPACE, &value); + if(res != LV_STYLE_RES_FOUND) { letter_space = lv_obj_get_style_text_letter_space(par, LV_PART_MAIN); } else { @@ -710,8 +723,8 @@ static int32_t lv_span_get_style_text_letter_space(lv_obj_t * par, lv_span_t * s static lv_color_t lv_span_get_style_text_color(lv_obj_t * par, lv_span_t * span) { lv_style_value_t value; - lv_result_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_COLOR, &value); - if(res != LV_RESULT_OK) { + lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_COLOR, &value); + if(res != LV_STYLE_RES_FOUND) { value.color = lv_obj_get_style_text_color(par, LV_PART_MAIN); } return value.color; @@ -721,8 +734,8 @@ static lv_opa_t lv_span_get_style_text_opa(lv_obj_t * par, lv_span_t * span) { lv_opa_t opa; lv_style_value_t value; - lv_result_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_OPA, &value); - if(res != LV_RESULT_OK) { + lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_OPA, &value); + if(res != LV_STYLE_RES_FOUND) { opa = (lv_opa_t)lv_obj_get_style_text_opa(par, LV_PART_MAIN); } else { @@ -735,8 +748,8 @@ static lv_blend_mode_t lv_span_get_style_text_blend_mode(lv_obj_t * par, lv_span { lv_blend_mode_t mode; lv_style_value_t value; - lv_result_t res = lv_style_get_prop(&span->style, LV_STYLE_BLEND_MODE, &value); - if(res != LV_RESULT_OK) { + lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_BLEND_MODE, &value); + if(res != LV_STYLE_RES_FOUND) { mode = (lv_blend_mode_t)lv_obj_get_style_blend_mode(par, LV_PART_MAIN); } else { @@ -749,8 +762,8 @@ static int32_t lv_span_get_style_text_decor(lv_obj_t * par, lv_span_t * span) { int32_t decor; lv_style_value_t value; - lv_result_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_DECOR, &value); - if(res != LV_RESULT_OK) { + lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_DECOR, &value); + if(res != LV_STYLE_RES_FOUND) { decor = (lv_text_decor_t)lv_obj_get_style_text_decor(par, LV_PART_MAIN);; } else { @@ -799,13 +812,13 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) lv_spangroup_t * spans = (lv_spangroup_t *)obj; /* return if not span */ - if(_lv_ll_get_head(&spans->child_ll) == NULL) { + if(lv_ll_get_head(&spans->child_ll) == NULL) { return; } /* return if no draw area */ lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, &coords, &layer->_clip_area)) return; + if(!lv_area_intersect(&clip_area, &coords, &layer->_clip_area)) return; const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area; @@ -822,7 +835,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) txt_pos.y = coords.y1; txt_pos.x = coords.x1 + indent; /* first line need add indent */ - lv_span_t * cur_span = _lv_ll_get_head(&spans->child_ll); + lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll); const char * cur_txt = cur_span->txt; span_text_check(&cur_txt); uint32_t cur_txt_ofs = 0; @@ -845,7 +858,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) while(1) { /* switch to the next span when current is end */ if(cur_txt[cur_txt_ofs] == '\0') { - cur_span = _lv_ll_get_next(&spans->child_ll, cur_span); + cur_span = lv_ll_get_next(&spans->child_ll, cur_span); if(cur_span == NULL) break; cur_txt = cur_span->txt; span_text_check(&cur_txt); @@ -870,17 +883,21 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) if(isfill) { if(next_ofs > 0 && lv_get_snippet_count() > 0) { - /* To prevent infinite loops, the _lv_text_get_next_line() may return incomplete words, */ + int32_t drawn_width = use_width; + if(lv_ll_get_next(&spans->child_ll, cur_span) == NULL) { + drawn_width -= snippet.letter_space; + } + /* To prevent infinite loops, the lv_text_get_next_line() may return incomplete words, */ /* This phenomenon should be avoided when lv_get_snippet_count() > 0 */ - if(max_w < use_width) { + if(max_w < drawn_width) { break; } uint32_t tmp_ofs = next_ofs; - uint32_t letter = _lv_text_encoded_prev(&cur_txt[cur_txt_ofs], &tmp_ofs); - if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_text_is_break_char(letter))) { - tmp_ofs = 0; - letter = _lv_text_encoded_next(&cur_txt[cur_txt_ofs + next_ofs], &tmp_ofs); - if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_text_is_break_char(letter))) { + uint32_t letter = lv_text_encoded_prev(&cur_txt[cur_txt_ofs], &tmp_ofs); + uint32_t letter_next = lv_text_encoded_next(&cur_txt[cur_txt_ofs + next_ofs], NULL); + if(!(letter == '\0' || letter == '\n' || letter == '\r' || lv_text_is_break_char(letter) || + lv_text_is_a_word(letter) || lv_text_is_a_word(letter_next))) { + if(!(letter_next == '\0' || letter_next == '\n' || letter_next == '\r' || lv_text_is_break_char(letter_next))) { break; } } @@ -897,7 +914,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) } lv_snippet_push(&snippet); - max_w = max_w - use_width - snippet.letter_space; + max_w = max_w - use_width; if(isfill || max_w <= 0) { break; } @@ -916,7 +933,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) int32_t next_line_h = last_snippet->line_h; if(last_snippet->txt[last_snippet->bytes] == '\0') { next_line_h = 0; - lv_span_t * next_span = _lv_ll_get_next(&spans->child_ll, last_snippet->span); + lv_span_t * next_span = lv_ll_get_next(&spans->child_ll, last_snippet->span); if(next_span) { /* have the next line */ next_line_h = lv_font_get_line_height(lv_span_get_style_text_font(obj, next_span)) + line_space; } @@ -945,7 +962,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) uint32_t i; for(i = 0; i < item_cnt; i++) { lv_snippet_t * pinfo = lv_get_snippet(i); - txts_w = txts_w + pinfo->txt_w + pinfo->letter_space; + txts_w = txts_w + pinfo->txt_w; } txts_w -= lv_get_snippet(item_cnt - 1)->letter_space; align_ofs = max_width > txts_w ? max_width - txts_w : 0; @@ -990,8 +1007,8 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) if(pos.x > clip_area.x2) { break; } - uint32_t letter = _lv_text_encoded_next(bidi_txt, &j); - uint32_t letter_next = _lv_text_encoded_next(&bidi_txt[j], NULL); + uint32_t letter = lv_text_encoded_next(bidi_txt, &j); + uint32_t letter_next = lv_text_encoded_next(&bidi_txt[j], NULL); int32_t letter_w = lv_font_get_glyph_width(pinfo->font, letter, letter_next); /* skip invalid fields */ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.h b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.h index 0b0386913..f0406b918 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.h @@ -28,50 +28,18 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum _lv_span_overflow_t { +typedef enum { LV_SPAN_OVERFLOW_CLIP, LV_SPAN_OVERFLOW_ELLIPSIS, - _LV_SPAN_OVERFLOW_LAST, /**< Fence member*/ -}; + LV_SPAN_OVERFLOW_LAST, /**< Fence member*/ +} lv_span_overflow_t; -#ifdef DOXYGEN -typedef _lv_span_overflow_t lv_span_overflow_t; -#else -typedef uint32_t lv_span_overflow_t; -#endif /*DOXYGEN*/ - -enum _lv_span_mode_t { - LV_SPAN_MODE_FIXED, /**< fixed the obj size*/ - LV_SPAN_MODE_EXPAND, /**< Expand the object size to the text size*/ - LV_SPAN_MODE_BREAK, /**< Keep width, break the too long lines and expand height*/ - _LV_SPAN_MODE_LAST /**< Fence member*/ -}; - -#ifdef DOXYGEN -typedef _lv_span_mode_t lv_span_mode_t; -#else -typedef uint32_t lv_span_mode_t; -#endif /*DOXYGEN*/ - -typedef struct { - char * txt; /* a pointer to display text */ - lv_obj_t * spangroup; /* a pointer to spangroup */ - lv_style_t style; /* display text style */ - uint32_t static_flag : 1;/* the text is static flag */ -} lv_span_t; - -/** Data of label*/ -typedef struct { - lv_obj_t obj; - int32_t lines; - int32_t indent; /* first line indent */ - int32_t cache_w; /* the cache automatically calculates the width */ - int32_t cache_h; /* similar cache_w */ - lv_ll_t child_ll; - uint32_t mode : 2; /* details see lv_span_mode_t */ - uint32_t overflow : 1; /* details see lv_span_overflow_t */ - uint32_t refresh : 1; /* the spangroup need refresh cache_w and cache_h */ -} lv_spangroup_t; +typedef enum { + LV_SPAN_MODE_FIXED, /**< fixed the obj size */ + LV_SPAN_MODE_EXPAND, /**< Expand the object size to the text size */ + LV_SPAN_MODE_BREAK, /**< Keep width, break the too long lines and expand height */ + LV_SPAN_MODE_LAST /**< Fence member */ +} lv_span_mode_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_spangroup_class; @@ -161,6 +129,13 @@ void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines); * Getter functions *====================*/ +/** + * Get a pointer to the style of a span + * @param span pointer to the span + * @return pointer to the style. valid as long as the span is valid +*/ +lv_style_t * lv_span_get_style(lv_span_t * span); + /** * Get a spangroup child by its index. * diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span_private.h new file mode 100644 index 000000000..099ea1b7e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span_private.h @@ -0,0 +1,65 @@ +/** + * @file lv_span_private.h + * + */ + +#ifndef LV_SPAN_PRIVATE_H +#define LV_SPAN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_span.h" + +#if LV_USE_SPAN != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_span_t { + char * txt; /**< a pointer to display text */ + lv_obj_t * spangroup; /**< a pointer to spangroup */ + lv_style_t style; /**< display text style */ + uint32_t static_flag : 1; /**< the text is static flag */ +}; + +/** Data of label*/ +struct lv_spangroup_t { + lv_obj_t obj; + int32_t lines; + int32_t indent; /**< first line indent */ + int32_t cache_w; /**< the cache automatically calculates the width */ + int32_t cache_h; /**< similar cache_w */ + lv_ll_t child_ll; + uint32_t mode : 2; /**< details see lv_span_mode_t */ + uint32_t overflow : 1; /**< details see lv_span_overflow_t */ + uint32_t refresh : 1; /**< the spangroup need refresh cache_w and cache_h */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SPAN != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SPAN_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.c b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.c index 667c310b3..69e8d13da 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_spinbox.h" +#include "lv_spinbox_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_SPINBOX #include "../../misc/lv_assert.h" @@ -364,6 +365,8 @@ static void lv_spinbox_event(const lv_obj_class_t * class_p, lv_event_t * e) spinbox->step = 1; uint32_t i; for(i = 0; i < pos; i++) spinbox->step *= 10; + + lv_spinbox_updatevalue(obj); } } else if(code == LV_EVENT_KEY) { diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.h b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.h index 267026f2e..ae3fdb0c4 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.h @@ -31,20 +31,6 @@ extern "C" { * TYPEDEFS **********************/ -/*Data of spinbox*/ -typedef struct { - lv_textarea_t ta; /*Ext. of ancestor*/ - /*New data for this type*/ - int32_t value; - int32_t range_max; - int32_t range_min; - int32_t step; - uint32_t digit_count : 4; - uint32_t dec_point_pos : 4; /*if 0, there is no separator and the number is an integer*/ - uint32_t rollover : 1; /* Set to true for rollover functionality*/ - uint32_t digit_step_dir : 2; /* the direction the digit will step on encoder button press when editing*/ -} lv_spinbox_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_spinbox_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox_private.h new file mode 100644 index 000000000..0569f2103 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox_private.h @@ -0,0 +1,59 @@ +/** + * @file lv_spinbox_private.h + * + */ + +#ifndef LV_SPINBOX_PRIVATE_H +#define LV_SPINBOX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../textarea/lv_textarea_private.h" +#include "lv_spinbox.h" + +#if LV_USE_SPINBOX + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of spinbox */ +struct lv_spinbox_t { + lv_textarea_t ta; /**< Ext. of ancestor */ + /*New data for this type*/ + int32_t value; + int32_t range_max; + int32_t range_min; + int32_t step; + uint32_t digit_count : 4; + uint32_t dec_point_pos : 4; /**< if 0, there is no separator and the number is an integer */ + uint32_t rollover : 1; /**< Set to true for rollover functionality */ + uint32_t digit_step_dir : 2; /**< the direction the digit will step on encoder button press when editing */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SPINBOX */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SPINBOX_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/spinner/lv_spinner.c b/lib/libesp32_lvgl/lvgl/src/widgets/spinner/lv_spinner.c index 9b1daa8ef..18cb0050f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/spinner/lv_spinner.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinner/lv_spinner.c @@ -6,6 +6,8 @@ /********************* * INCLUDES *********************/ +#include "../../misc/lv_anim_private.h" +#include "../../core/lv_obj_class_private.h" #include "../../lvgl.h" #if LV_USE_SPINNER diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.c b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.c index f1973e9c4..89b4b6363 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.c @@ -6,13 +6,15 @@ /********************* * INCLUDES *********************/ -#include "lv_switch.h" +#include "lv_switch_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_SWITCH != 0 #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" -#include "../../misc/lv_anim.h" +#include "../../misc/lv_anim_private.h" #include "../../indev/lv_indev.h" #include "../../display/lv_display.h" @@ -127,7 +129,7 @@ static void lv_switch_event(const lv_obj_class_t * class_p, lv_event_t * e) /*The smaller size is the knob diameter*/ int32_t knob_size = LV_MAX4(knob_left, knob_right, knob_bottom, knob_top); - knob_size += _LV_SWITCH_KNOB_EXT_AREA_CORRECTION; + knob_size += LV_SWITCH_KNOB_EXT_AREA_CORRECTION; knob_size += lv_obj_calculate_ext_draw_size(obj, LV_PART_KNOB); int32_t * s = lv_event_get_param(e); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.h b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.h index da14450aa..989a3dd1b 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.h @@ -24,16 +24,7 @@ extern "C" { *********************/ /** Switch knob extra area correction factor */ -#define _LV_SWITCH_KNOB_EXT_AREA_CORRECTION 2 - -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_obj_t obj; - int32_t anim_state; -} lv_switch_t; +#define LV_SWITCH_KNOB_EXT_AREA_CORRECTION 2 LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_switch_class; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch_private.h new file mode 100644 index 000000000..7bc25763c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch_private.h @@ -0,0 +1,54 @@ +/** + * @file lv_switch_private.h + * + */ + +#ifndef LV_SWITCH_PRIVATE_H +#define LV_SWITCH_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_switch.h" + +#if LV_USE_SWITCH != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_switch_t { + lv_obj_t obj; + int32_t anim_state; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_SWITCH != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SWITCH_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.c b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.c index c69494c3a..affb99b88 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.c @@ -6,7 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_table.h" +#include "lv_table_private.h" +#include "../../misc/lv_area_private.h" +#include "../../core/lv_obj_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_TABLE != 0 #include "../../indev/lv_indev.h" @@ -15,7 +18,7 @@ #include "../../misc/lv_text_ap.h" #include "../../misc/lv_math.h" #include "../../stdlib/lv_sprintf.h" -#include "../../draw/lv_draw.h" +#include "../../draw/lv_draw_private.h" #include "../../stdlib/lv_string.h" /********************* @@ -166,14 +169,14 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint32_t row, uint32_t col, con lv_vsnprintf(raw_txt, len + 1, fmt, ap2); /*Get the size of the Arabic text and process it*/ - size_t len_ap = _lv_text_ap_calc_bytes_count(raw_txt); + size_t len_ap = lv_text_ap_calc_bytes_count(raw_txt); table->cell_data[cell] = lv_realloc(table->cell_data[cell], sizeof(lv_table_cell_t) + len_ap + 1); LV_ASSERT_MALLOC(table->cell_data[cell]); if(table->cell_data[cell] == NULL) { va_end(ap2); return; } - _lv_text_ap_proc(raw_txt, table->cell_data[cell]->txt); + lv_text_ap_proc(raw_txt, table->cell_data[cell]->txt); lv_free(raw_txt); #else @@ -391,6 +394,26 @@ void lv_table_set_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, voi table->cell_data[cell]->user_data = user_data; } +void lv_table_set_selected_cell(lv_obj_t * obj, uint16_t row, uint16_t col) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_table_t * table = (lv_table_t *)obj; + + if(table->col_cnt == 0 || table->row_cnt == 0) return; + + if(table->col_act != col || table->row_act != row) { + table->col_act = (col >= table->col_cnt) ? (table->col_cnt - 1) : col; + table->row_act = (row >= table->row_cnt) ? (table->row_cnt - 1) : row; + + lv_obj_invalidate(obj); + + scroll_to_selected_cell(obj); + + lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL); + } +} + /*===================== * Getter functions *====================*/ @@ -651,7 +674,7 @@ static void draw_main(lv_event_t * e) lv_table_t * table = (lv_table_t *)obj; lv_layer_t * layer = lv_event_get_layer(e); lv_area_t clip_area; - if(!_lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area)) return; + if(!lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area)) return; const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = clip_area; @@ -817,7 +840,7 @@ static void draw_main(lv_event_t * e) lv_area_t label_clip_area; bool label_mask_ok; - label_mask_ok = _lv_area_intersect(&label_clip_area, &clip_area, &cell_area); + label_mask_ok = lv_area_intersect(&label_clip_area, &clip_area, &cell_area); if(label_mask_ok) { layer->_clip_area = label_clip_area; label_dsc_act.text = table->cell_data[cell]->txt; @@ -1017,9 +1040,9 @@ static size_t get_cell_txt_len(const char * txt) size_t retval = 0; #if LV_USE_ARABIC_PERSIAN_CHARS - retval = sizeof(lv_table_cell_t) + _lv_text_ap_calc_bytes_count(txt) + 1; + retval = sizeof(lv_table_cell_t) + lv_text_ap_calc_bytes_count(txt) + 1; #else - retval = sizeof(lv_table_cell_t) + strlen(txt) + 1; + retval = sizeof(lv_table_cell_t) + lv_strlen(txt) + 1; #endif return retval; @@ -1029,9 +1052,9 @@ static size_t get_cell_txt_len(const char * txt) static void copy_cell_txt(lv_table_cell_t * dst, const char * txt) { #if LV_USE_ARABIC_PERSIAN_CHARS - _lv_text_ap_proc(txt, dst->txt); + lv_text_ap_proc(txt, dst->txt); #else - strcpy(dst->txt, txt); + lv_strcpy(dst->txt, txt); #endif } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.h b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.h index 456d794f3..0d615a1b1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.h @@ -33,39 +33,14 @@ LV_EXPORT_CONST_INT(LV_TABLE_CELL_NONE); * TYPEDEFS **********************/ -enum _lv_table_cell_ctrl_t { +typedef enum { LV_TABLE_CELL_CTRL_MERGE_RIGHT = 1 << 0, LV_TABLE_CELL_CTRL_TEXT_CROP = 1 << 1, LV_TABLE_CELL_CTRL_CUSTOM_1 = 1 << 4, LV_TABLE_CELL_CTRL_CUSTOM_2 = 1 << 5, LV_TABLE_CELL_CTRL_CUSTOM_3 = 1 << 6, LV_TABLE_CELL_CTRL_CUSTOM_4 = 1 << 7, -}; - -#ifdef DOXYGEN -typedef _lv_table_cell_ctrl_t lv_table_cell_ctrl_t; -#else -typedef uint32_t lv_table_cell_ctrl_t; -#endif /*DOXYGEN*/ - -/*Data of cell*/ -typedef struct { - lv_table_cell_ctrl_t ctrl; - void * user_data; /**< Custom user data*/ - char txt[1]; /**< Variable length array*/ -} lv_table_cell_t; - -/*Data of table*/ -typedef struct { - lv_obj_t obj; - uint32_t col_cnt; - uint32_t row_cnt; - lv_table_cell_t ** cell_data; - int32_t * row_h; - int32_t * col_w; - uint32_t col_act; - uint32_t row_act; -} lv_table_t; +} lv_table_cell_ctrl_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_table_class; @@ -157,6 +132,14 @@ void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_tab */ void lv_table_set_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, void * user_data); +/** + * Set the selected cell + * @param obj pointer to a table object + * @param row id of the cell row to select + * @param col id of the cell column to select + */ +void lv_table_set_selected_cell(lv_obj_t * obj, uint16_t row, uint16_t col); + /*===================== * Getter functions *====================*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table_private.h new file mode 100644 index 000000000..498ef5e28 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table_private.h @@ -0,0 +1,64 @@ +/** + * @file lv_table_private.h + * + */ + +#ifndef LV_TABLE_PRIVATE_H +#define LV_TABLE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_table.h" + +#if LV_USE_TABLE != 0 +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Cell data */ +struct lv_table_cell_t { + lv_table_cell_ctrl_t ctrl; + void * user_data; /**< Custom user data */ + char txt[1]; /**< Variable length array */ +}; + +/** Table data */ +struct lv_table_t { + lv_obj_t obj; + uint32_t col_cnt; + uint32_t row_cnt; + lv_table_cell_t ** cell_data; + int32_t * row_h; + int32_t * col_w; + uint32_t col_act; + uint32_t row_act; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TABLE != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABLE_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.c b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.c index e6bd36805..29e3e2e27 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.c @@ -6,6 +6,8 @@ /********************* * INCLUDES *********************/ +#include "lv_tabview_private.h" +#include "../../core/lv_obj_class_private.h" #include "../../lvgl.h" #if LV_USE_TABVIEW @@ -168,6 +170,11 @@ void lv_tabview_set_tab_bar_position(lv_obj_t * obj, lv_dir_t dir) case LV_DIR_RIGHT: lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW_REVERSE); break; + case LV_DIR_HOR: + case LV_DIR_VER: + case LV_DIR_ALL: + case LV_DIR_NONE: + break; } lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); @@ -192,6 +199,11 @@ void lv_tabview_set_tab_bar_position(lv_obj_t * obj, lv_dir_t dir) lv_obj_set_scroll_snap_x(cont, LV_SCROLL_SNAP_NONE); lv_obj_set_scroll_snap_y(cont, LV_SCROLL_SNAP_CENTER); break; + case LV_DIR_HOR: + case LV_DIR_VER: + case LV_DIR_ALL: + case LV_DIR_NONE: + break; } bool was_ver = tabview->tab_pos & LV_DIR_VER; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.h b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.h index a4e0c7640..f9bfdcc18 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.h @@ -1,5 +1,5 @@ /** - * @file lv_templ.h + * @file lv_tabview.h * */ @@ -22,16 +22,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - lv_obj_t obj; - uint32_t tab_cur; - lv_dir_t tab_pos; -} lv_tabview_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tabview_class; /********************** @@ -78,6 +68,7 @@ void lv_tabview_set_tab_bar_position(lv_obj_t * obj, lv_dir_t dir); /** * Set the width or height of the tab bar + * @param obj pointer to tabview widget * @param size size of the tab bar in pixels or percentage. * will be used as width or height based on the position of the tab bar) */ @@ -93,7 +84,7 @@ uint32_t lv_tabview_get_tab_count(lv_obj_t * obj); /** * Get the current tab's index * @param obj pointer to a tabview widget - * @return the zero based indoex of the current tab + * @return the zero based index of the current tab */ uint32_t lv_tabview_get_tab_active(lv_obj_t * obj); @@ -107,7 +98,7 @@ lv_obj_t * lv_tabview_get_content(lv_obj_t * obj); /** * Get the tab bar where the buttons are created * @param obj pointer to a tabview widget - * @return the tabbar + * @return the tab bar */ lv_obj_t * lv_tabview_get_tab_bar(lv_obj_t * obj); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview_private.h new file mode 100644 index 000000000..b08c96820 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview_private.h @@ -0,0 +1,55 @@ +/** + * @file lv_tabview_private.h + * + */ + +#ifndef LV_TABVIEW_PRIVATE_H +#define LV_TABVIEW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_tabview.h" + +#if LV_USE_TABVIEW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct lv_tabview_t { + lv_obj_t obj; + uint32_t tab_cur; + lv_dir_t tab_pos; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TABVIEW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABVIEW_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c index 37bf816b1..02f1b1614 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c @@ -6,17 +6,18 @@ /********************* * INCLUDES *********************/ -#include "lv_textarea.h" +#include "lv_textarea_private.h" +#include "../label/lv_label_private.h" +#include "../../core/lv_obj_class_private.h" #if LV_USE_TEXTAREA != 0 -#include #include "../../core/lv_group.h" #include "../../core/lv_refr.h" #include "../../indev/lv_indev.h" #include "../../draw/lv_draw.h" #include "../../misc/lv_assert.h" -#include "../../misc/lv_anim.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_anim_private.h" +#include "../../misc/lv_text_private.h" #include "../../misc/lv_math.h" #include "../../stdlib/lv_string.h" @@ -60,11 +61,92 @@ static lv_result_t insert_handler(lv_obj_t * obj, const char * txt); static void draw_placeholder(lv_event_t * e); static void draw_cursor(lv_event_t * e); static void auto_hide_characters(lv_obj_t * obj); +static void auto_hide_characters_cancel(lv_obj_t * obj); static inline bool is_valid_but_non_printable_char(const uint32_t letter); /********************** * STATIC VARIABLES **********************/ +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_TEXTAREA_TEXT, + .setter = lv_textarea_set_text, + .getter = lv_textarea_get_text, + }, + { + .id = LV_PROPERTY_TEXTAREA_PLACEHOLDER_TEXT, + .setter = lv_textarea_set_placeholder_text, + .getter = lv_textarea_get_placeholder_text, + }, + { + .id = LV_PROPERTY_TEXTAREA_CURSOR_POS, + .setter = lv_textarea_set_cursor_pos, + .getter = lv_textarea_get_cursor_pos, + }, + { + .id = LV_PROPERTY_TEXTAREA_CURSOR_CLICK_POS, + .setter = lv_textarea_set_cursor_click_pos, + .getter = lv_textarea_get_cursor_click_pos, + }, + { + .id = LV_PROPERTY_TEXTAREA_PASSWORD_MODE, + .setter = lv_textarea_set_password_mode, + .getter = lv_textarea_get_password_mode, + }, + { + .id = LV_PROPERTY_TEXTAREA_PASSWORD_BULLET, + .setter = lv_textarea_set_password_bullet, + .getter = lv_textarea_get_password_bullet, + }, + { + .id = LV_PROPERTY_TEXTAREA_ONE_LINE, + .setter = lv_textarea_set_one_line, + .getter = lv_textarea_get_one_line, + }, + { + .id = LV_PROPERTY_TEXTAREA_ACCEPTED_CHARS, + .setter = lv_textarea_set_accepted_chars, + .getter = lv_textarea_get_accepted_chars, + }, + { + .id = LV_PROPERTY_TEXTAREA_MAX_LENGTH, + .setter = lv_textarea_set_max_length, + .getter = lv_textarea_get_max_length, + }, + { + .id = LV_PROPERTY_TEXTAREA_INSERT_REPLACE, + .setter = lv_textarea_set_insert_replace, + .getter = NULL, + }, + { + .id = LV_PROPERTY_TEXTAREA_TEXT_SELECTION, + .setter = lv_textarea_set_text_selection, + .getter = lv_textarea_get_text_selection, + }, + { + .id = LV_PROPERTY_TEXTAREA_PASSWORD_SHOW_TIME, + .setter = lv_textarea_set_password_show_time, + .getter = lv_textarea_get_password_show_time, + }, + { + .id = LV_PROPERTY_TEXTAREA_LABEL, + .setter = NULL, + .getter = lv_textarea_get_label, + }, + { + .id = LV_PROPERTY_TEXTAREA_TEXT_IS_SELECTED, + .setter = NULL, + .getter = lv_textarea_text_is_selected, + }, + { + .id = LV_PROPERTY_TEXTAREA_CURRENT_CHAR, + .setter = NULL, + .getter = lv_textarea_get_current_char, + }, +}; +#endif + const lv_obj_class_t lv_textarea_class = { .constructor_cb = lv_textarea_constructor, .destructor_cb = lv_textarea_destructor, @@ -72,9 +154,22 @@ const lv_obj_class_t lv_textarea_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .width_def = LV_DPI_DEF * 2, .height_def = LV_DPI_DEF, + .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .instance_size = sizeof(lv_textarea_t), .base_class = &lv_obj_class, .name = "textarea", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_TEXTAREA_START, + .prop_index_end = LV_PROPERTY_TEXTAREA_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_textarea_property_names, + .names_count = sizeof(lv_textarea_property_names) / sizeof(lv_property_name_t), +#endif + +#endif }; static const char * ta_insert_replace; @@ -134,7 +229,7 @@ void lv_textarea_add_char(lv_obj_t * obj, uint32_t c) lv_result_t res = insert_handler(obj, letter_buf); if(res != LV_RESULT_OK) return; - uint32_t c_uni = _lv_text_encoded_next((const char *)&c2, NULL); + uint32_t c_uni = lv_text_encoded_next((const char *)&c2, NULL); if(char_is_accepted(obj, c_uni) == false) { LV_LOG_INFO("Character is not accepted by the text area (too long text or not in the accepted list)"); @@ -159,7 +254,7 @@ void lv_textarea_add_char(lv_obj_t * obj, uint32_t c) LV_ASSERT_MALLOC(ta->pwd_tmp); if(ta->pwd_tmp == NULL) return; - _lv_text_ins(ta->pwd_tmp, ta->cursor.pos, (const char *)letter_buf); + lv_text_ins(ta->pwd_tmp, ta->cursor.pos, (const char *)letter_buf); /*Auto hide characters*/ auto_hide_characters(obj); @@ -184,8 +279,8 @@ void lv_textarea_add_text(lv_obj_t * obj, const char * txt) if(lv_textarea_get_accepted_chars(obj) || lv_textarea_get_max_length(obj)) { uint32_t i = 0; while(txt[i] != '\0') { - uint32_t c = _lv_text_encoded_next(txt, &i); - lv_textarea_add_char(obj, _lv_text_unicode_to_encoded(c)); + uint32_t c = lv_text_encoded_next(txt, &i); + lv_textarea_add_char(obj, lv_text_unicode_to_encoded(c)); } return; } @@ -209,14 +304,14 @@ void lv_textarea_add_text(lv_obj_t * obj, const char * txt) LV_ASSERT_MALLOC(ta->pwd_tmp); if(ta->pwd_tmp == NULL) return; - _lv_text_ins(ta->pwd_tmp, ta->cursor.pos, txt); + lv_text_ins(ta->pwd_tmp, ta->cursor.pos, txt); /*Auto hide characters*/ auto_hide_characters(obj); } /*Move the cursor after the new text*/ - lv_textarea_set_cursor_pos(obj, lv_textarea_get_cursor_pos(obj) + _lv_text_get_encoded_length(txt)); + lv_textarea_set_cursor_pos(obj, lv_textarea_get_cursor_pos(obj) + lv_text_get_encoded_length(txt)); lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL); } @@ -238,7 +333,7 @@ void lv_textarea_delete_char(lv_obj_t * obj) char * label_txt = lv_label_get_text(ta->label); /*Delete a character*/ - _lv_text_cut(label_txt, ta->cursor.pos - 1, 1); + lv_text_cut(label_txt, ta->cursor.pos - 1, 1); /*Refresh the label*/ lv_label_set_text(ta->label, label_txt); @@ -251,7 +346,7 @@ void lv_textarea_delete_char(lv_obj_t * obj) } if(ta->pwd_mode) { - _lv_text_cut(ta->pwd_tmp, ta->cursor.pos - 1, 1); + lv_text_cut(ta->pwd_tmp, ta->cursor.pos - 1, 1); ta->pwd_tmp = lv_realloc(ta->pwd_tmp, lv_strlen(ta->pwd_tmp) + 1); LV_ASSERT_MALLOC(ta->pwd_tmp); @@ -297,8 +392,8 @@ void lv_textarea_set_text(lv_obj_t * obj, const char * txt) } uint32_t i = 0; while(txt[i] != '\0') { - uint32_t c = _lv_text_encoded_next(txt, &i); - lv_textarea_add_char(obj, _lv_text_unicode_to_encoded(c)); + uint32_t c = lv_text_encoded_next(txt, &i); + lv_textarea_add_char(obj, lv_text_unicode_to_encoded(c)); } } else { @@ -313,12 +408,12 @@ void lv_textarea_set_text(lv_obj_t * obj, const char * txt) } if(ta->pwd_mode) { + lv_free(ta->pwd_tmp); ta->pwd_tmp = lv_strdup(txt); LV_ASSERT_MALLOC(ta->pwd_tmp); if(ta->pwd_tmp == NULL) return; - /*Auto hide characters*/ - auto_hide_characters(obj); + pwd_char_hider(obj); } lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL); @@ -360,7 +455,7 @@ void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos) lv_textarea_t * ta = (lv_textarea_t *)obj; if((uint32_t)ta->cursor.pos == (uint32_t)pos) return; - uint32_t len = _lv_text_get_encoded_length(lv_label_get_text(ta->label)); + uint32_t len = lv_text_get_encoded_length(lv_label_get_text(ta->label)); if(pos < 0) pos = len + pos; @@ -424,6 +519,7 @@ void lv_textarea_set_password_mode(lv_obj_t * obj, bool en) /*Pwd mode is now enabled*/ if(en) { char * txt = lv_label_get_text(ta->label); + lv_free(ta->pwd_tmp); ta->pwd_tmp = lv_strdup(txt); LV_ASSERT_MALLOC(ta->pwd_tmp); if(ta->pwd_tmp == NULL) return; @@ -470,7 +566,7 @@ void lv_textarea_set_password_bullet(lv_obj_t * obj, const char * bullet) ta->pwd_bullet[txt_len] = '\0'; } - lv_obj_invalidate(obj); + pwd_char_hider(obj); } void lv_textarea_set_one_line(lv_obj_t * obj, bool en) @@ -545,6 +641,7 @@ void lv_textarea_set_password_show_time(lv_obj_t * obj, uint32_t time) lv_textarea_t * ta = (lv_textarea_t *)obj; ta->pwd_show_time = time; + pwd_char_hider(obj); } void lv_textarea_set_align(lv_obj_t * obj, lv_text_align_t align) @@ -719,8 +816,8 @@ uint32_t lv_textarea_get_current_char(lv_obj_t * obj) const char * txt = lv_textarea_get_text(obj); lv_textarea_t * ta = (lv_textarea_t *)obj; uint32_t pos = ta->cursor.pos; - if(_lv_text_get_encoded_length(txt) >= pos && pos > 0) - return _lv_text_encoded_prev(txt, &pos); + if(lv_text_get_encoded_length(txt) >= pos && pos > 0) + return lv_text_encoded_prev(txt, &pos); else return 0; } @@ -1001,7 +1098,7 @@ static void pwd_char_hider(lv_obj_t * obj) /* When ta->label is empty we get 0 back */ char * txt = lv_label_get_text(ta->label); - uint32_t enc_len = _lv_text_get_encoded_length(txt); + uint32_t enc_len = lv_text_get_encoded_length(txt); if(enc_len == 0) return; const char * bullet = lv_textarea_get_password_bullet(obj); @@ -1017,6 +1114,8 @@ static void pwd_char_hider(lv_obj_t * obj) lv_label_set_text(ta->label, txt_tmp); lv_free(txt_tmp); + auto_hide_characters_cancel(obj); + refr_cursor_area(obj); } @@ -1031,7 +1130,7 @@ static bool char_is_accepted(lv_obj_t * obj, uint32_t c) lv_textarea_t * ta = (lv_textarea_t *)obj; /*Too many characters?*/ - if(ta->max_length > 0 && _lv_text_get_encoded_length(lv_textarea_get_text(obj)) >= ta->max_length) { + if(ta->max_length > 0 && lv_text_get_encoded_length(lv_textarea_get_text(obj)) >= ta->max_length) { return false; } @@ -1040,7 +1139,7 @@ static bool char_is_accepted(lv_obj_t * obj, uint32_t c) uint32_t i = 0; while(ta->accepted_chars[i] != '\0') { - uint32_t a = _lv_text_encoded_next(ta->accepted_chars, &i); + uint32_t a = lv_text_encoded_next(ta->accepted_chars, &i); if(a == c) return true; /*Accepted*/ } @@ -1079,8 +1178,8 @@ static void refr_cursor_area(lv_obj_t * obj) uint32_t cur_pos = lv_textarea_get_cursor_pos(obj); const char * txt = lv_label_get_text(ta->label); - uint32_t byte_pos = _lv_text_encoded_get_byte_id(txt, cur_pos); - uint32_t letter = _lv_text_encoded_next(&txt[byte_pos], NULL); + uint32_t byte_pos = lv_text_encoded_get_byte_id(txt, cur_pos); + uint32_t letter = lv_text_encoded_next(&txt[byte_pos], NULL); /* Letter height and width */ const int32_t letter_h = lv_font_get_line_height(font); @@ -1104,8 +1203,8 @@ static void refr_cursor_area(lv_obj_t * obj) letter_pos.y += letter_h + line_space; if(letter != '\0') { - byte_pos += _lv_text_encoded_size(&txt[byte_pos]); - letter = _lv_text_encoded_next(&txt[byte_pos], NULL); + byte_pos += lv_text_encoded_size(&txt[byte_pos]); + letter = lv_text_encoded_next(&txt[byte_pos], NULL); } uint32_t tmp = letter; @@ -1342,7 +1441,7 @@ static void draw_cursor(lv_event_t * e) int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_CURSOR) + border_width; int32_t top = lv_obj_get_style_pad_top(obj, LV_PART_CURSOR) + border_width; char letter_buf[8] = {0}; - lv_memcpy(letter_buf, &txt[ta->cursor.txt_byte_pos], _lv_text_encoded_size(&txt[ta->cursor.txt_byte_pos])); + lv_memcpy(letter_buf, &txt[ta->cursor.txt_byte_pos], lv_text_encoded_size(&txt[ta->cursor.txt_byte_pos])); cur_area.x1 += left; cur_area.y1 += top; @@ -1381,6 +1480,11 @@ static void auto_hide_characters(lv_obj_t * obj) } } +static void auto_hide_characters_cancel(lv_obj_t * obj) +{ + lv_anim_delete(obj, pwd_char_hider_anim); +} + static inline bool is_valid_but_non_printable_char(const uint32_t letter) { if(letter == '\0' || letter == '\n' || letter == '\r') { diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.h b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.h index 0db80eb8f..0804029d1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.h @@ -33,35 +33,26 @@ LV_EXPORT_CONST_INT(LV_TEXTAREA_CURSOR_LAST); * TYPEDEFS **********************/ -/*Data of text area*/ -typedef struct { - lv_obj_t obj; - lv_obj_t * label; /*Label of the text area*/ - char * placeholder_txt; /*Place holder label. only visible if text is an empty string*/ - char * pwd_tmp; /*Used to store the original text in password mode*/ - char * pwd_bullet; /*Replacement characters displayed in password mode*/ - const char * accepted_chars; /*Only these characters will be accepted. NULL: accept all*/ - uint32_t max_length; /*The max. number of characters. 0: no limit*/ - uint32_t pwd_show_time; /*Time to show characters in password mode before change them to '*'*/ - struct { - int32_t valid_x; /*Used when stepping up/down to a shorter line. - *(Used by the library)*/ - uint32_t pos; /*The current cursor position - *(0: before 1st letter; 1: before 2nd letter ...)*/ - lv_area_t area; /*Cursor area relative to the Text Area*/ - uint32_t txt_byte_pos; /*Byte index of the letter after (on) the cursor*/ - uint8_t show : 1; /*Cursor is visible now or not (Handled by the library)*/ - uint8_t click_pos : 1; /*1: Enable positioning the cursor by clicking the text area*/ - } cursor; -#if LV_LABEL_TEXT_SELECTION - uint32_t sel_start; /*Temporary values for text selection*/ - uint32_t sel_end; - uint8_t text_sel_in_prog : 1; /*User is in process of selecting*/ - uint8_t text_sel_en : 1; /*Text can be selected on this text area*/ +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID(TEXTAREA, TEXT, LV_PROPERTY_TYPE_TEXT, 0), + LV_PROPERTY_ID(TEXTAREA, PLACEHOLDER_TEXT, LV_PROPERTY_TYPE_TEXT, 1), + LV_PROPERTY_ID(TEXTAREA, CURSOR_POS, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(TEXTAREA, CURSOR_CLICK_POS, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_ID(TEXTAREA, PASSWORD_MODE, LV_PROPERTY_TYPE_INT, 4), + LV_PROPERTY_ID(TEXTAREA, PASSWORD_BULLET, LV_PROPERTY_TYPE_TEXT, 5), + LV_PROPERTY_ID(TEXTAREA, ONE_LINE, LV_PROPERTY_TYPE_BOOL, 6), + LV_PROPERTY_ID(TEXTAREA, ACCEPTED_CHARS, LV_PROPERTY_TYPE_TEXT, 7), + LV_PROPERTY_ID(TEXTAREA, MAX_LENGTH, LV_PROPERTY_TYPE_INT, 8), + LV_PROPERTY_ID(TEXTAREA, INSERT_REPLACE, LV_PROPERTY_TYPE_TEXT, 9), + LV_PROPERTY_ID(TEXTAREA, TEXT_SELECTION, LV_PROPERTY_TYPE_BOOL, 10), + LV_PROPERTY_ID(TEXTAREA, PASSWORD_SHOW_TIME, LV_PROPERTY_TYPE_INT, 11), + LV_PROPERTY_ID(TEXTAREA, LABEL, LV_PROPERTY_TYPE_OBJ, 12), + LV_PROPERTY_ID(TEXTAREA, TEXT_IS_SELECTED, LV_PROPERTY_TYPE_INT, 13), + LV_PROPERTY_ID(TEXTAREA, CURRENT_CHAR, LV_PROPERTY_TYPE_INT, 14), + LV_PROPERTY_TEXTAREA_END, +}; #endif - uint8_t pwd_mode : 1; /*Replace characters with '*'*/ - uint8_t one_line : 1; /*One line mode (ignore line breaks)*/ -} lv_textarea_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_textarea_class; @@ -86,7 +77,7 @@ lv_obj_t * lv_textarea_create(lv_obj_t * parent); /** * Insert a character to the current cursor position. - * To add a wide char, e.g. 'Á' use `_lv_text_encoded_conv_wc('Á')` + * To add a wide char, e.g. 'Á' use `lv_text_encoded_conv_wc('Á')` * @param obj pointer to a text area object * @param c a character (e.g. 'a') */ @@ -181,7 +172,7 @@ void lv_textarea_set_accepted_chars(lv_obj_t * obj, const char * list); void lv_textarea_set_max_length(lv_obj_t * obj, uint32_t num); /** - * In `LV_EVENT_INSERT` the text which planned to be inserted can be replaced by an other text. + * In `LV_EVENT_INSERT` the text which planned to be inserted can be replaced by another text. * It can be used to add automatic formatting to the text area. * @param obj pointer to a text area object * @param txt pointer to a new string to insert. If `""` no text will be added. diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea_private.h new file mode 100644 index 000000000..e2d3aaab9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea_private.h @@ -0,0 +1,75 @@ +/** + * @file lv_textarea_private.h + * + */ + +#ifndef LV_TEXTAREA_PRIVATE_H +#define LV_TEXTAREA_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_textarea.h" + +#if LV_USE_TEXTAREA != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** Data of text area */ +struct lv_textarea_t { + lv_obj_t obj; + lv_obj_t * label; /**< Label of the text area */ + char * placeholder_txt; /**< Place holder label. only visible if text is an empty string */ + char * pwd_tmp; /**< Used to store the original text in password mode */ + char * pwd_bullet; /**< Replacement characters displayed in password mode */ + const char * accepted_chars; /**< Only these characters will be accepted. NULL: accept all */ + uint32_t max_length; /**< The max. number of characters. 0: no limit */ + uint32_t pwd_show_time; /**< Time to show characters in password mode before change them to '*' */ + struct { + int32_t valid_x; /**< Used when stepping up/down to a shorter line. + *(Used by the library) */ + uint32_t pos; /**< The current cursor position + *(0: before 1st letter; 1: before 2nd letter ...) */ + lv_area_t area; /**< Cursor area relative to the Text Area */ + uint32_t txt_byte_pos; /**< Byte index of the letter after (on) the cursor */ + uint8_t show : 1; /**< Cursor is visible now or not (Handled by the library) */ + uint8_t click_pos : 1; /**< 1: Enable positioning the cursor by clicking the text area */ + } cursor; +#if LV_LABEL_TEXT_SELECTION + uint32_t sel_start; /**< Temporary values for text selection */ + uint32_t sel_end; + uint8_t text_sel_in_prog : 1; /**< User is in process of selecting */ + uint8_t text_sel_en : 1; /**< Text can be selected on this text area */ +#endif + uint8_t pwd_mode : 1; /**< Replace characters with '*' */ + uint8_t one_line : 1; /**< One line mode (ignore line breaks) */ +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TEXTAREA != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEXTAREA_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.c b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.c index 400ca15c7..8844a89ae 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.c @@ -6,7 +6,8 @@ /********************* * INCLUDES *********************/ -#include "lv_tileview.h" +#include "lv_tileview_private.h" +#include "../../core/lv_obj_class_private.h" #include "../../indev/lv_indev.h" #include "../../indev/lv_indev_private.h" #if LV_USE_TILEVIEW diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.h b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.h index 6413a1b15..d373a2684 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.h @@ -21,19 +21,6 @@ extern "C" { * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ -typedef struct { - lv_obj_t obj; - lv_obj_t * tile_act; -} lv_tileview_t; - -typedef struct { - lv_obj_t obj; - lv_dir_t dir; -} lv_tileview_tile_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tileview_class; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tileview_tile_class; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview_private.h new file mode 100644 index 000000000..5c91a409e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview_private.h @@ -0,0 +1,58 @@ +/** + * @file lv_tileview_private.h + * + */ + +#ifndef LV_TILEVIEW_PRIVATE_H +#define LV_TILEVIEW_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_tileview.h" + +#if LV_USE_TILEVIEW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ +struct lv_tileview_t { + lv_obj_t obj; + lv_obj_t * tile_act; +}; + +struct lv_tileview_tile_t { + lv_obj_t obj; + lv_dir_t dir; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_TILEVIEW */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TILEVIEW_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.c b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.c index 437b3af48..508d2f010 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.c @@ -6,6 +6,8 @@ /********************* * INCLUDES *********************/ +#include "lv_win_private.h" +#include "../../core/lv_obj_class_private.h" #include "../../lvgl.h" #if LV_USE_WIN diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.h b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.h index 0f6d5a4ce..8191bd116 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.h @@ -14,18 +14,12 @@ extern "C" { * INCLUDES *********************/ #include "../../lv_conf_internal.h" +#include "../../core/lv_obj.h" #if LV_USE_WIN /********************* * DEFINES *********************/ -/********************** - * TYPEDEFS - **********************/ -typedef struct { - lv_obj_t obj; -} lv_win_t; - LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_win_class; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win_private.h new file mode 100644 index 000000000..015224712 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win_private.h @@ -0,0 +1,52 @@ +/** + * @file lv_win_private.h + * + */ + +#ifndef LV_WIN_PRIVATE_H +#define LV_WIN_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../core/lv_obj_private.h" +#include "lv_win.h" + +#if LV_USE_WIN + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * TYPEDEFS + **********************/ +struct lv_win_t { + lv_obj_t obj; +}; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WIN */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WIN_PRIVATE_H*/ diff --git a/tasmota/lvgl_berry/tasmota_lv_conf.h b/tasmota/lvgl_berry/tasmota_lv_conf.h index 7e53749a6..6b3cc423f 100644 --- a/tasmota/lvgl_berry/tasmota_lv_conf.h +++ b/tasmota/lvgl_berry/tasmota_lv_conf.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v9.1.0 + * Configuration file for v9.2.0 */ /* @@ -26,7 +26,7 @@ COLOR SETTINGS *====================*/ -/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ #define LV_COLOR_DEPTH 16 /*========================= @@ -44,6 +44,12 @@ #define LV_USE_STDLIB_STRING LV_STDLIB_CLIB // TASMOTA #define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB // TASMOTA +#define LV_STDINT_INCLUDE +#define LV_STDDEF_INCLUDE +#define LV_STDBOOL_INCLUDE +#define LV_INTTYPES_INCLUDE +#define LV_LIMITS_INCLUDE +#define LV_STDARG_INCLUDE #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ @@ -82,6 +88,7 @@ * - LV_OS_CMSIS_RTOS2 * - LV_OS_RTTHREAD * - LV_OS_WINDOWS + * - LV_OS_MQX * - LV_OS_CUSTOM */ #define LV_USE_OS LV_OS_NONE @@ -99,6 +106,12 @@ /*Align the start address of draw_buf addresses to this bytes*/ #define LV_DRAW_BUF_ALIGN 4 +/*Using matrix for transformations. + *Requirements: + `LV_USE_MATRIX = 1`. + The rendering engine needs to support 3x3 matrix transformations.*/ +#define LV_DRAW_TRANSFORM_USE_MATRIX 0 + /* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers @@ -107,11 +120,34 @@ /*The target buffer size for simple layer chunks.*/ #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ +/* The stack size of the drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /*[bytes]*/ + #define LV_USE_DRAW_SW 1 #if LV_USE_DRAW_SW == 1 - /* Set the number of draw unit. + + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ + + #define LV_DRAW_SW_SUPPORT_RGB565 1 + #define LV_DRAW_SW_SUPPORT_RGB565A8 1 + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #define LV_DRAW_SW_SUPPORT_XRGB8888 0 + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #define LV_DRAW_SW_SUPPORT_L8 0 + #define LV_DRAW_SW_SUPPORT_AL88 1 + #define LV_DRAW_SW_SUPPORT_A8 0 + #define LV_DRAW_SW_SUPPORT_I1 1 + + /* Set the number of draw unit. * > 1 requires an operating system enabled in `LV_USE_OS` - * > 1 means multiply threads will render the screen in parallel */ + * > 1 means multiple threads will render the screen in parallel */ #define LV_DRAW_SW_DRAW_UNIT_CNT 1 /* Use Arm-2D to accelerate the sw render */ @@ -119,7 +155,7 @@ /* Enable native helium assembly to be compiled */ #define LV_USE_NATIVE_HELIUM_ASM 0 - + /* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only * 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */ #define LV_DRAW_SW_COMPLEX 1 @@ -142,6 +178,9 @@ #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" #endif + + /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 #endif /* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ @@ -152,8 +191,13 @@ #define LV_USE_VGLITE_BLIT_SPLIT 0 #if LV_USE_OS - /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ - #define LV_USE_VGLITE_DRAW_ASYNC 1 + /* Use additional draw thread for VG-Lite processing.*/ + #define LV_USE_VGLITE_DRAW_THREAD 1 + + #if LV_USE_VGLITE_DRAW_THREAD + /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ + #define LV_USE_VGLITE_DRAW_ASYNC 1 + #endif #endif /* Enable VGLite asserts. */ @@ -164,6 +208,11 @@ #define LV_USE_DRAW_PXP 0 #if LV_USE_DRAW_PXP + #if LV_USE_OS + /* Use additional draw thread for PXP processing.*/ + #define LV_USE_PXP_DRAW_THREAD 1 + #endif + /* Enable PXP asserts. */ #define LV_USE_PXP_ASSERT 0 #endif @@ -178,24 +227,28 @@ #define LV_USE_DRAW_VG_LITE 0 #if LV_USE_DRAW_VG_LITE -/* Enable VG-Lite custom external 'gpu_init()' function */ -#define LV_VG_LITE_USE_GPU_INIT 0 + /* Enable VG-Lite custom external 'gpu_init()' function */ + #define LV_VG_LITE_USE_GPU_INIT 0 -/* Enable VG-Lite assert. */ -#define LV_VG_LITE_USE_ASSERT 0 + /* Enable VG-Lite assert. */ + #define LV_VG_LITE_USE_ASSERT 0 -/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ -#define LV_VG_LITE_FLUSH_MAX_COUNT 8 + /* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ + #define LV_VG_LITE_FLUSH_MAX_COUNT 8 -/* Enable border to simulate shadow - * NOTE: which usually improves performance, - * but does not guarantee the same rendering quality as the software. */ -#define LV_VG_LITE_USE_BOX_SHADOW 0 + /* Enable border to simulate shadow + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ + #define LV_VG_LITE_USE_BOX_SHADOW 0 -/* VG-Lite gradient image maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ -#define LV_VG_LITE_GRAD_CACHE_SIZE 32 + /* VG-Lite gradient maximum cache number. + * NOTE: The memory usage of a single gradient image is 4K bytes. + */ + #define LV_VG_LITE_GRAD_CACHE_CNT 32 + + /* VG-Lite stroke maximum cache number. + */ + #define LV_VG_LITE_STROKE_CACHE_CNT 32 #endif @@ -224,6 +277,11 @@ *0: User need to register a callback with `lv_log_register_print_cb()`*/ #define LV_LOG_PRINTF 0 + /*Set callback to print the logs. + *E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)` + *Can be overwritten by `lv_log_register_print_cb`*/ + //#define LV_LOG_PRINT_CB + /*1: Enable print timestamp; *0: Disable print timestamp*/ #define LV_LOG_USE_TIMESTAMP 1 @@ -232,6 +290,7 @@ *0: Do not print file and line number of the log*/ #define LV_LOG_USE_FILE_LINE 1 + /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ #define LV_LOG_TRACE_MEM 0 #define LV_LOG_TRACE_TIMER 0 @@ -296,7 +355,7 @@ /*Default number of image header cache entries. The cache is used to store the headers of images *The main logic is like `LV_CACHE_DEF_SIZE` but for image headers.*/ -#define LV_IMAGE_HEADER_CACHE_DEF_CNT 10 +#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 /*Number of stops allowed per gradient. Increase this to allow more stops. *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ @@ -312,12 +371,23 @@ /* Add `id` field to `lv_obj_t` */ #define LV_USE_OBJ_ID 1 // TASMOTA -/* Use lvgl builtin method for obj ID */ -#define LV_USE_OBJ_ID_BUILTIN 1 // TASMOTA +/* Automatically assign an ID when obj is created */ +#define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + +/*Use the builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return e.g. "button3" +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#define LV_USE_OBJ_ID_BUILTIN 1 /*Use obj property set/get API*/ #define LV_USE_OBJ_PROPERTY 0 +/*Enable property name support*/ +#define LV_USE_OBJ_PROPERTY_NAME 0 // TASMOTA + /* VG-Lite Simulator */ /*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ #define LV_USE_VG_LITE_THORVG 0 @@ -330,6 +400,9 @@ /*Enable YUV color format support*/ #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + /*Enable Linear gradient extension support*/ + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + /*Enable 16 pixels alignment*/ #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 @@ -374,7 +447,7 @@ #define LV_ATTRIBUTE_FAST_MEM /*Export integer constant to binding. This macro is used with constants in the form of LV_ that - *should also appear on LVGL binding API such as Micropython.*/ + *should also appear on LVGL binding API such as MicroPython.*/ #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ /*Prefix all global extern data with this*/ @@ -383,6 +456,13 @@ /* Use `float` as `lv_value_precise_t` */ #define LV_USE_FLOAT 0 +/*Enable matrix support + *Requires `LV_USE_FLOAT = 1`*/ +#define LV_USE_MATRIX 0 + +/*Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default*/ +#define LV_USE_PRIVATE_API 0 + /*================== * FONT USAGE *===================*/ @@ -542,7 +622,7 @@ #endif /*Enable Arabic/Persian processing - *In these languages characters should be replaced with an other form based on their position in the text*/ + *In these languages characters should be replaced with another form based on their position in the text*/ #define LV_USE_ARABIC_PERSIAN_CHARS 0 /*================== @@ -575,6 +655,7 @@ #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} #define LV_USE_CALENDAR_HEADER_ARROW 1 #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + #define LV_USE_CALENDAR_CHINESE 0 #endif /*LV_USE_CALENDAR*/ #define LV_USE_CANVAS 1 @@ -604,6 +685,8 @@ #define LV_USE_LIST 1 +#define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ + #define LV_USE_MENU 1 #define LV_USE_MSGBOX 1 @@ -679,6 +762,9 @@ /*File system interfaces for common APIs */ +/*Setting a default driver letter allows skipping the driver prefix in filepaths*/ +#define LV_FS_DEFAULT_DRIVE_LETTER '\0' + /*API for fopen, fread, etc*/ #define LV_USE_FS_STDIO 0 #if LV_USE_FS_STDIO @@ -722,6 +808,18 @@ #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ #endif +/*API for Arduino LittleFs. */ +#define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + +/*API for Arduino Sd. */ +#define LV_USE_FS_ARDUINO_SD 0 +#if LV_USE_FS_ARDUINO_SD + #define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + /*LODEPNG decoder library*/ #define LV_USE_LODEPNG 1 // TASMOTA @@ -742,8 +840,8 @@ /*GIF decoder library*/ #define LV_USE_GIF 0 #if LV_USE_GIF -/*GIF decoder accelerate*/ -#define LV_GIF_CACHE_DECODE_DATA 0 + /*GIF decoder accelerate*/ + #define LV_GIF_CACHE_DECODE_DATA 0 #endif @@ -762,9 +860,6 @@ /*FreeType library*/ #define LV_USE_FREETYPE 1 // TASMOTA #if LV_USE_FREETYPE - /*Memory used by FreeType to cache characters in kilobytes*/ - #define LV_FREETYPE_CACHE_SIZE 64 // TODO TASMOTA (only with PSRAM ?) - /*Let FreeType to use LVGL memory and file porting*/ #define LV_FREETYPE_USE_LVGL_PORT 0 @@ -778,12 +873,14 @@ #if LV_USE_TINY_TTF /* Enable loading TTF data from files */ #define LV_TINY_TTF_FILE_SUPPORT 0 + #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 #endif /*Rlottie library*/ #define LV_USE_RLOTTIE 0 -/*Enable Vector Graphic APIs*/ +/*Enable Vector Graphic APIs + *Requires `LV_USE_MATRIX = 1`*/ #define LV_USE_VECTOR_GRAPHIC 0 /* Enable ThorVG (vector graphics library) from the src/libs folder */ @@ -885,7 +982,7 @@ #define LV_USE_IME_PINYIN 0 #if LV_USE_IME_PINYIN /*1: Use default thesaurus*/ - /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ + /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus*/ #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 /*Set the maximum number of candidate panels that can be displayed*/ /*This needs to be adjusted according to the size of the screen*/ @@ -919,6 +1016,7 @@ #define LV_SDL_INCLUDE_PATH #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ + #define LV_SDL_ACCELERATED 1 /*1: Use hardware acceleration*/ #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ @@ -928,13 +1026,20 @@ #define LV_USE_X11 0 #if LV_USE_X11 #define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/ - #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/ + #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for rendering*/ /*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/ #define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/ #define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/ #define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/ #endif +/*Use Wayland to open a window and handle input on Linux or BSD desktops */ +#define LV_USE_WAYLAND 0 +#if LV_USE_WAYLAND + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /*Draw client side window decorations only necessary on Mutter/GNOME*/ + #define LV_WAYLAND_WL_SHELL 0 /*Use the legacy wl_shell protocol instead of the default XDG shell*/ +#endif + /*Driver for /dev/fb*/ #define LV_USE_LINUX_FBDEV 0 #if LV_USE_LINUX_FBDEV @@ -989,16 +1094,31 @@ #endif /*Drivers for LCD devices connected via SPI/parallel port*/ -#define LV_USE_ST7735 0 -#define LV_USE_ST7789 0 -#define LV_USE_ST7796 0 -#define LV_USE_ILI9341 0 +#define LV_USE_ST7735 0 +#define LV_USE_ST7789 0 +#define LV_USE_ST7796 0 +#define LV_USE_ILI9341 0 #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) +/*Driver for Renesas GLCD*/ +#define LV_USE_RENESAS_GLCDC 0 + /* LVGL Windows backend */ #define LV_USE_WINDOWS 0 +/* Use OpenGL to open window on PC and handle mouse and keyboard */ +#define LV_USE_OPENGLES 0 +#if LV_USE_OPENGLES + #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ +#endif + +/* QNX Screen display and input drivers */ +#define LV_USE_QNX 0 +#if LV_USE_QNX + #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ +#endif + /*================== * EXAMPLES *==================*/ @@ -1049,6 +1169,7 @@ /*Vector graphic demo*/ #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + /*--END OF LV_CONF_H--*/ #endif /*LV_CONF_H*/ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino index c3e95522a..f6cbc09f1 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino @@ -141,7 +141,7 @@ extern "C" { // lv_ft_info_t info = {}; const char * name = be_tostring(vm, 1); int32_t weight = be_toint(vm, 2); - int32_t style = be_toint(vm, 3); + lv_freetype_font_style_t style = (lv_freetype_font_style_t) be_toint(vm, 3); lv_font_t * font = lv_freetype_font_create(name, LV_FREETYPE_FONT_RENDER_MODE_BITMAP, weight, style); // lv_ft_font_init(&info); // lv_font_t * font = info.font; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino index 622b06d00..abbeea257 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino @@ -22,6 +22,7 @@ #include #include "lvgl.h" +#include "core/lv_global.h" // needed for LV_GLOBAL_DEFAULT #include "tasmota_lvgl_assets.h" // force compilation of assets #define XDRV_54 54 @@ -138,12 +139,12 @@ extern "C" { } // int fclose ( FILE * stream ); - int lvbe_fclose(lvbe_FILE * stream) { + lv_fs_res_t lvbe_fclose(lvbe_FILE * stream) { File * f_ptr = (File*) stream; f_ptr->close(); delete f_ptr; // AddLog(LOG_LEVEL_INFO, "LVG: lvbe_fclose(%p)", f_ptr); - return 0; + return LV_FS_RES_OK; } // size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );